add support for threaded comments
This commit is contained in:
parent
15398e9ca1
commit
bfbb6d515e
6 changed files with 359 additions and 87 deletions
133
includes/collection/class-interactions.php
Normal file
133
includes/collection/class-interactions.php
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
<?php
|
||||||
|
namespace Activitypub\Collection;
|
||||||
|
|
||||||
|
use WP_Error;
|
||||||
|
|
||||||
|
use function Activitypub\object_id_to_comment;
|
||||||
|
use function Activitypub\get_remote_metadata_by_actor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ActivityPub Interactions Collection
|
||||||
|
*/
|
||||||
|
class Interactions {
|
||||||
|
/**
|
||||||
|
* Add a comment to a post
|
||||||
|
*
|
||||||
|
* @param array $activity The activity-object
|
||||||
|
*
|
||||||
|
* @return array|false The commentdata or false on failure
|
||||||
|
*/
|
||||||
|
public static function add_comment( $activity ) {
|
||||||
|
if (
|
||||||
|
! isset( $activity['object'] ) ||
|
||||||
|
! isset( $activity['object']['id'] )
|
||||||
|
) {
|
||||||
|
return new WP_Error(
|
||||||
|
'activitypub_no_valid_object',
|
||||||
|
__( 'No object id found.', 'activitypub' ),
|
||||||
|
array( 'status' => 400 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! isset( $activity['object']['inReplyTo'] ) ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'activitypub_no_reply',
|
||||||
|
__( 'Object is no reply.', 'activitypub' ),
|
||||||
|
array( 'status' => 400 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$in_reply_to = \esc_url_raw( $activity['object']['inReplyTo'] );
|
||||||
|
$comment_post_id = \url_to_postid( $in_reply_to );
|
||||||
|
$parent_comment = object_id_to_comment( $in_reply_to );
|
||||||
|
|
||||||
|
// save only replys and reactions
|
||||||
|
if ( ! $comment_post_id && $parent_comment ) {
|
||||||
|
$comment_post_id = $parent_comment->comment_post_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not a reply to a post or comment
|
||||||
|
if ( ! $comment_post_id ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'activitypub_no_reply',
|
||||||
|
__( 'Object is no reply.', 'activitypub' ),
|
||||||
|
array( 'status' => 400 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$meta = get_remote_metadata_by_actor( $activity['actor'] );
|
||||||
|
|
||||||
|
if ( ! $meta || \is_wp_error( $meta ) ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'activitypub_invalid_follower',
|
||||||
|
__( 'Invalid Follower', 'activitypub' ),
|
||||||
|
array( 'status' => 400 )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$commentdata = array(
|
||||||
|
'comment_post_ID' => $comment_post_id,
|
||||||
|
'comment_author' => \esc_attr( $meta['name'] ),
|
||||||
|
'comment_author_url' => \esc_url_raw( $meta['url'] ),
|
||||||
|
'comment_content' => addslashes( \wp_kses( $activity['object']['content'], 'pre_comment_content' ) ),
|
||||||
|
'comment_type' => 'comment',
|
||||||
|
'comment_author_email' => '',
|
||||||
|
'comment_parent' => $parent_comment ? $parent_comment->comment_ID : 0,
|
||||||
|
'comment_meta' => array(
|
||||||
|
'source_id' => \esc_url_raw( $activity['object']['id'] ),
|
||||||
|
'source_url' => \esc_url_raw( $activity['object']['url'] ),
|
||||||
|
'avatar_url' => \esc_url_raw( $meta['icon']['url'] ),
|
||||||
|
'protocol' => 'activitypub',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// disable flood control
|
||||||
|
\remove_action( 'check_comment_flood', 'check_comment_flood_db', 10 );
|
||||||
|
|
||||||
|
// do not require email for AP entries
|
||||||
|
\add_filter( 'pre_option_require_name_email', '__return_false' );
|
||||||
|
// No nonce possible for this submission route
|
||||||
|
\add_filter(
|
||||||
|
'akismet_comment_nonce',
|
||||||
|
function() {
|
||||||
|
return 'inactive';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
\add_filter( 'wp_kses_allowed_html', array( self::class, 'allowed_comment_html' ), 10, 2 );
|
||||||
|
|
||||||
|
$comment = \wp_new_comment( $commentdata, true );
|
||||||
|
|
||||||
|
\remove_filter( 'wp_kses_allowed_html', array( self::class, 'allowed_comment_html' ), 10 );
|
||||||
|
\remove_filter( 'pre_option_require_name_email', '__return_false' );
|
||||||
|
|
||||||
|
// re-add flood control
|
||||||
|
\add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 );
|
||||||
|
|
||||||
|
return $comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds line breaks to the list of allowed comment tags.
|
||||||
|
*
|
||||||
|
* @param array $allowedtags Allowed HTML tags.
|
||||||
|
* @param string $context Context.
|
||||||
|
* @return array Filtered tag list.
|
||||||
|
*/
|
||||||
|
public static function allowed_comment_html( $allowedtags, $context = '' ) {
|
||||||
|
if ( 'pre_comment_content' !== $context ) {
|
||||||
|
// Do nothing.
|
||||||
|
return $allowedtags;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add `p` and `br` to the list of allowed tags.
|
||||||
|
if ( ! array_key_exists( 'br', $allowedtags ) ) {
|
||||||
|
$allowedtags['br'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! array_key_exists( 'p', $allowedtags ) ) {
|
||||||
|
$allowedtags['p'] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $allowedtags;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Activitypub\Handler;
|
namespace Activitypub\Handler;
|
||||||
|
|
||||||
|
use WP_Error;
|
||||||
|
use Activitypub\Collection\Interactions;
|
||||||
|
|
||||||
use function Activitypub\is_activity_public;
|
use function Activitypub\is_activity_public;
|
||||||
use function Activitypub\get_remote_metadata_by_actor;
|
use function Activitypub\object_id_to_comment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle Create requests
|
* Handle Create requests
|
||||||
|
@ -12,108 +15,59 @@ class Create {
|
||||||
* Initialize the class, registering WordPress hooks
|
* Initialize the class, registering WordPress hooks
|
||||||
*/
|
*/
|
||||||
public static function init() {
|
public static function init() {
|
||||||
\add_action( 'activitypub_inbox_create', array( self::class, 'handle_create' ), 10, 2 );
|
\add_action( 'activitypub_inbox_create', array( self::class, 'handle_create' ), 10, 3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles "Create" requests
|
* Handles "Create" requests
|
||||||
*
|
*
|
||||||
* @param array $activity The activity-object
|
* @param array $array The activity-object
|
||||||
* @param int $user_id The id of the local blog-user
|
* @param int $user_id The id of the local blog-user
|
||||||
|
* @param Activitypub\Activity $object The activity object
|
||||||
|
*
|
||||||
|
* @return void|WP_Error WP_Error on failure
|
||||||
*/
|
*/
|
||||||
public static function handle_create( $activity, $user_id ) {
|
public static function handle_create( $array, $user_id, $object = null ) {
|
||||||
$meta = get_remote_metadata_by_actor( $activity['actor'] );
|
if (
|
||||||
|
! isset( $array['object'] ) ||
|
||||||
if ( ! isset( $activity['object']['inReplyTo'] ) ) {
|
! isset( $array['object']['id'] )
|
||||||
return;
|
) {
|
||||||
|
return new WP_Error(
|
||||||
|
'activitypub_no_valid_object',
|
||||||
|
__( 'No object id found.', 'activitypub' ),
|
||||||
|
array( 'status' => 400 )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if Activity is public or not
|
// check if Activity is public or not
|
||||||
if ( ! is_activity_public( $activity ) ) {
|
if ( ! is_activity_public( $array ) ) {
|
||||||
// @todo maybe send email
|
// @todo maybe send email
|
||||||
return;
|
return new WP_Error(
|
||||||
}
|
'activitypub_activity_not_public',
|
||||||
|
__( 'Activity is not public.', 'activitypub' ),
|
||||||
$comment_post_id = \url_to_postid( $activity['object']['inReplyTo'] );
|
array( 'status' => 400 )
|
||||||
|
|
||||||
// save only replys and reactions
|
|
||||||
if ( ! $comment_post_id ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$commentdata = array(
|
|
||||||
'comment_post_ID' => $comment_post_id,
|
|
||||||
'comment_author' => \esc_attr( $meta['name'] ),
|
|
||||||
'comment_author_url' => \esc_url_raw( $activity['actor'] ),
|
|
||||||
'comment_content' => \wp_filter_kses( $activity['object']['content'] ),
|
|
||||||
'comment_type' => 'comment',
|
|
||||||
'comment_author_email' => '',
|
|
||||||
'comment_parent' => 0,
|
|
||||||
'comment_meta' => array(
|
|
||||||
'source_id' => \esc_url_raw( $activity['object']['id'] ),
|
|
||||||
'source_url' => \esc_url_raw( $activity['object']['url'] ),
|
|
||||||
'avatar_url' => \esc_url_raw( $meta['icon']['url'] ),
|
|
||||||
'protocol' => 'activitypub',
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// disable flood control
|
|
||||||
\remove_action( 'check_comment_flood', 'check_comment_flood_db', 10 );
|
|
||||||
|
|
||||||
// do not require email for AP entries
|
|
||||||
\add_filter( 'pre_option_require_name_email', '__return_false' );
|
|
||||||
|
|
||||||
// No nonce possible for this submission route
|
|
||||||
\add_filter(
|
|
||||||
'akismet_comment_nonce',
|
|
||||||
function() {
|
|
||||||
return 'inactive';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$check_dupe = object_id_to_comment( $array['object']['id'] );
|
||||||
|
|
||||||
|
// if comment exists, call update action
|
||||||
|
if ( $check_dupe ) {
|
||||||
|
\do_action( 'activitypub_inbox_update', $array, $user_id, $object );
|
||||||
|
return new WP_Error(
|
||||||
|
'activitypub_comment_exists',
|
||||||
|
__( 'Comment already exists, initiated Update process.', 'activitypub' ),
|
||||||
|
array( 'status' => 400 )
|
||||||
);
|
);
|
||||||
|
|
||||||
$state = \wp_new_comment( $commentdata, true );
|
|
||||||
|
|
||||||
\remove_filter( 'pre_option_require_name_email', '__return_false' );
|
|
||||||
|
|
||||||
// re-add flood control
|
|
||||||
\add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 );
|
|
||||||
|
|
||||||
\do_action( 'activitypub_handled_create', $activity, $user_id, $state, $commentdata );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
$reaction = Interactions::add_comment( $array );
|
||||||
* Handles "Create" requests
|
$state = null;
|
||||||
*
|
|
||||||
* @param array $object The activity-object
|
if ( $reaction ) {
|
||||||
* @param int $user_id The id of the local blog-user
|
$state = $reaction['comment_ID'];
|
||||||
*/
|
|
||||||
public static function handle_create_alt( $object, $user_id ) {
|
|
||||||
$commentdata = self::convert_object_to_comment_data( $object, $user_id );
|
|
||||||
if ( ! $commentdata ) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// disable flood control
|
\do_action( 'activitypub_handled_create', $array, $user_id, $state, $reaction );
|
||||||
\remove_action( 'check_comment_flood', 'check_comment_flood_db', 10 );
|
|
||||||
|
|
||||||
// do not require email for AP entries
|
|
||||||
\add_filter( 'pre_option_require_name_email', '__return_false' );
|
|
||||||
|
|
||||||
// No nonce possible for this submission route
|
|
||||||
\add_filter(
|
|
||||||
'akismet_comment_nonce',
|
|
||||||
function() {
|
|
||||||
return 'inactive';
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
$state = \wp_new_comment( $commentdata, true );
|
|
||||||
|
|
||||||
\remove_filter( 'pre_option_require_name_email', '__return_false' );
|
|
||||||
|
|
||||||
// re-add flood control
|
|
||||||
\add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 4 );
|
|
||||||
|
|
||||||
do_action( 'activitypub_handled_create', $object, $user_id, $state, $commentdata );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ class Delete {
|
||||||
*/
|
*/
|
||||||
public static function init() {
|
public static function init() {
|
||||||
\add_action( 'activitypub_inbox_delete', array( self::class, 'handle_delete' ), 10, 2 );
|
\add_action( 'activitypub_inbox_delete', array( self::class, 'handle_delete' ), 10, 2 );
|
||||||
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +43,8 @@ class Delete {
|
||||||
$follower->delete();
|
$follower->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete all activities from this user.
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'Tombstone':
|
case 'Tombstone':
|
||||||
// Handle tombstone.
|
// Handle tombstone.
|
||||||
|
|
70
tests/test-class-activitypub-create-handler.php
Normal file
70
tests/test-class-activitypub-create-handler.php
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
<?php
|
||||||
|
class Test_Activitypub_Create_Handler extends WP_UnitTestCase {
|
||||||
|
public $user_id;
|
||||||
|
public $user_url;
|
||||||
|
public $post_id;
|
||||||
|
public $post_permalink;
|
||||||
|
|
||||||
|
public function set_up() {
|
||||||
|
$this->user_id = 1;
|
||||||
|
$authordata = \get_userdata( $this->user_id );
|
||||||
|
$this->user_url = $authordata->user_url;
|
||||||
|
|
||||||
|
$this->post_id = \wp_insert_post(
|
||||||
|
array(
|
||||||
|
'post_author' => $this->user_id,
|
||||||
|
'post_content' => 'test',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->post_permalink = \get_permalink( $this->post_id );
|
||||||
|
|
||||||
|
\add_filter( 'pre_get_remote_metadata_by_actor', array( '\Test_Activitypub_Create_Handler', 'get_remote_metadata_by_actor' ), 0, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get_remote_metadata_by_actor( $value, $actor ) {
|
||||||
|
return array(
|
||||||
|
'name' => 'Example User',
|
||||||
|
'icon' => array(
|
||||||
|
'url' => 'https://example.com/icon',
|
||||||
|
),
|
||||||
|
'url' => $actor,
|
||||||
|
'id' => 'http://example.org/users/example',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create_test_object( $id = 'https://example.com/123' ) {
|
||||||
|
return array(
|
||||||
|
'actor' => $this->user_url,
|
||||||
|
'id' => 'https://example.com/id/' . microtime( true ),
|
||||||
|
'to' => [ $this->user_url ],
|
||||||
|
'cc' => [ 'https://www.w3.org/ns/activitystreams#Public' ],
|
||||||
|
'object' => array(
|
||||||
|
'id' => $id,
|
||||||
|
'url' => 'https://example.com/example',
|
||||||
|
'inReplyTo' => $this->post_permalink,
|
||||||
|
'content' => 'example',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_handle_create_object_unset_rejected() {
|
||||||
|
$object = $this->create_test_object();
|
||||||
|
unset( $object['object'] );
|
||||||
|
$converted = Activitypub\Handler\Create::handle_create( $object, $this->user_id );
|
||||||
|
$this->assertEquals( $converted->get_error_code(), 'activitypub_no_valid_object' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_handle_create_non_public_rejected() {
|
||||||
|
$object = $this->create_test_object();
|
||||||
|
$object['cc'] = [];
|
||||||
|
$converted = Activitypub\Handler\Create::handle_create( $object, $this->user_id );
|
||||||
|
$this->assertEquals( $converted->get_error_code(), 'activitypub_activity_not_public' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_handle_create_no_id_rejected() {
|
||||||
|
$object = $this->create_test_object();
|
||||||
|
unset( $object['object']['id'] );
|
||||||
|
$converted = Activitypub\Handler\Create::handle_create( $object, $this->user_id );
|
||||||
|
$this->assertEquals( $converted->get_error_code(), 'activitypub_no_valid_object' );
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
class Test_Db_Activitypub_Followers extends WP_UnitTestCase {
|
class Test_Activitypub_Followers extends WP_UnitTestCase {
|
||||||
public static $users = array(
|
public static $users = array(
|
||||||
'username@example.org' => array(
|
'username@example.org' => array(
|
||||||
'id' => 'https://example.org/users/username',
|
'id' => 'https://example.org/users/username',
|
112
tests/test-class-activitypub-interactions.php
Normal file
112
tests/test-class-activitypub-interactions.php
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
class Test_Activitypub_Interactions extends WP_UnitTestCase {
|
||||||
|
public $user_id;
|
||||||
|
public $user_url;
|
||||||
|
public $post_id;
|
||||||
|
public $post_permalink;
|
||||||
|
|
||||||
|
public function set_up() {
|
||||||
|
$this->user_id = 1;
|
||||||
|
$authordata = \get_userdata( $this->user_id );
|
||||||
|
$this->user_url = $authordata->user_url;
|
||||||
|
|
||||||
|
$this->post_id = \wp_insert_post(
|
||||||
|
array(
|
||||||
|
'post_author' => $this->user_id,
|
||||||
|
'post_content' => 'test',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->post_permalink = \get_permalink( $this->post_id );
|
||||||
|
|
||||||
|
\add_filter( 'pre_get_remote_metadata_by_actor', array( '\Test_Activitypub_Interactions', 'get_remote_metadata_by_actor' ), 0, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function get_remote_metadata_by_actor( $value, $actor ) {
|
||||||
|
return array(
|
||||||
|
'name' => 'Example User',
|
||||||
|
'icon' => array(
|
||||||
|
'url' => 'https://example.com/icon',
|
||||||
|
),
|
||||||
|
'url' => $actor,
|
||||||
|
'id' => 'http://example.org/users/example',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create_test_object( $id = 'https://example.com/123' ) {
|
||||||
|
return array(
|
||||||
|
'actor' => $this->user_url,
|
||||||
|
'id' => 'https://example.com/id/' . microtime( true ),
|
||||||
|
'to' => [ $this->user_url ],
|
||||||
|
'cc' => [ 'https://www.w3.org/ns/activitystreams#Public' ],
|
||||||
|
'object' => array(
|
||||||
|
'id' => $id,
|
||||||
|
'url' => 'https://example.com/example',
|
||||||
|
'inReplyTo' => $this->post_permalink,
|
||||||
|
'content' => 'example',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_handle_create_basic() {
|
||||||
|
$comment_id = Activitypub\Collection\Interactions::add_comment( $this->create_test_object() );
|
||||||
|
$comment = get_comment( $comment_id, ARRAY_A );
|
||||||
|
|
||||||
|
$this->assertIsArray( $comment );
|
||||||
|
$this->assertEquals( $this->post_id, $comment['comment_post_ID'] );
|
||||||
|
$this->assertEquals( 'Example User', $comment['comment_author'] );
|
||||||
|
$this->assertEquals( $this->user_url, $comment['comment_author_url'] );
|
||||||
|
$this->assertEquals( 'example', $comment['comment_content'] );
|
||||||
|
$this->assertEquals( 'comment', $comment['comment_type'] );
|
||||||
|
$this->assertEquals( '', $comment['comment_author_email'] );
|
||||||
|
$this->assertEquals( 0, $comment['comment_parent'] );
|
||||||
|
$this->assertEquals( 'https://example.com/123', get_comment_meta( $comment_id, 'source_id', true ) );
|
||||||
|
$this->assertEquals( 'https://example.com/example', get_comment_meta( $comment_id, 'source_url', true ) );
|
||||||
|
$this->assertEquals( 'https://example.com/icon', get_comment_meta( $comment_id, 'avatar_url', true ) );
|
||||||
|
$this->assertEquals( 'activitypub', get_comment_meta( $comment_id, 'protocol', true ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_convert_object_to_comment_not_reply_rejected() {
|
||||||
|
$object = $this->create_test_object();
|
||||||
|
unset( $object['object']['inReplyTo'] );
|
||||||
|
$converted = Activitypub\Collection\Interactions::add_comment( $object );
|
||||||
|
$this->assertEquals( $converted->get_error_code(), 'activitypub_no_reply' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_convert_object_to_comment_already_exists_rejected() {
|
||||||
|
$object = $this->create_test_object( 'https://example.com/test_convert_object_to_comment_already_exists_rejected' );
|
||||||
|
Activitypub\Collection\Interactions::add_comment( $object );
|
||||||
|
$converted = Activitypub\Collection\Interactions::add_comment( $object );
|
||||||
|
$this->assertEquals( $converted->get_error_code(), 'comment_duplicate' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_convert_object_to_comment_reply_to_comment() {
|
||||||
|
$id = 'https://example.com/test_convert_object_to_comment_reply_to_comment';
|
||||||
|
$object = $this->create_test_object( $id );
|
||||||
|
Activitypub\Collection\Interactions::add_comment( $object );
|
||||||
|
$comment = \Activitypub\object_id_to_comment( $id );
|
||||||
|
|
||||||
|
$object['object']['inReplyTo'] = $id;
|
||||||
|
$object['object']['id'] = 'https://example.com/234';
|
||||||
|
$id = Activitypub\Collection\Interactions::add_comment( $object );
|
||||||
|
$converted = get_comment( $id, ARRAY_A );
|
||||||
|
|
||||||
|
$this->assertIsArray( $converted );
|
||||||
|
$this->assertEquals( $this->post_id, $converted['comment_post_ID'] );
|
||||||
|
$this->assertEquals( $comment->comment_ID, $converted['comment_parent'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_convert_object_to_comment_reply_to_non_existent_comment_rejected() {
|
||||||
|
$object = $this->create_test_object();
|
||||||
|
$object['object']['inReplyTo'] = 'https://example.com/not_found';
|
||||||
|
$converted = Activitypub\Collection\Interactions::add_comment( $object );
|
||||||
|
$this->assertEquals( $converted->get_error_code(), 'activitypub_no_reply' );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_handle_create_basic2() {
|
||||||
|
$id = 'https://example.com/test_handle_create_basic';
|
||||||
|
$object = $this->create_test_object( $id );
|
||||||
|
Activitypub\Collection\Interactions::add_comment( $object );
|
||||||
|
$comment = \Activitypub\object_id_to_comment( $id );
|
||||||
|
$this->assertInstanceOf( WP_Comment::class, $comment );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue