Add unit test
This commit is contained in:
parent
7036a65991
commit
a82dea0685
5 changed files with 239 additions and 29 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -5,3 +5,5 @@ composer.lock
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.idea/
|
.idea/
|
||||||
.php_cs.cache
|
.php_cs.cache
|
||||||
|
.phpunit.result.cache
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,10 @@ function get_webfinger_resource( $user_id ) {
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function get_remote_metadata_by_actor( $actor ) {
|
function get_remote_metadata_by_actor( $actor ) {
|
||||||
|
$pre = apply_filters( 'pre_get_remote_metadata_by_actor', false, $actor );
|
||||||
|
if ( $pre ) {
|
||||||
|
return $pre;
|
||||||
|
}
|
||||||
if ( preg_match( '/^@?[^@]+@((?:[a-z0-9-]+\.)+[a-z]+)$/i', $actor ) ) {
|
if ( preg_match( '/^@?[^@]+@((?:[a-z0-9-]+\.)+[a-z]+)$/i', $actor ) ) {
|
||||||
$actor = Rest\Webfinger::resolve( $actor );
|
$actor = Rest\Webfinger::resolve( $actor );
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,8 @@ class Friends_Feed_Parser_ActivityPub extends \Friends\Feed_Parser {
|
||||||
// We don't need to handle 'Accept' types since it's handled by the ActivityPub plugin itself.
|
// We don't need to handle 'Accept' types since it's handled by the ActivityPub plugin itself.
|
||||||
'create',
|
'create',
|
||||||
'announce',
|
'announce',
|
||||||
)
|
),
|
||||||
|
true
|
||||||
) ) {
|
) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -215,16 +216,35 @@ class Friends_Feed_Parser_ActivityPub extends \Friends\Feed_Parser {
|
||||||
* @param \Friends\User_Feed $user_feed The user feed.
|
* @param \Friends\User_Feed $user_feed The user feed.
|
||||||
*/
|
*/
|
||||||
private function handle_incoming_post( $object, \Friends\User_Feed $user_feed ) {
|
private function handle_incoming_post( $object, \Friends\User_Feed $user_feed ) {
|
||||||
$item = new \Friends\Feed_Item(
|
$data = array(
|
||||||
array(
|
'permalink' => $object['url'],
|
||||||
'permalink' => $object['url'],
|
'content' => $object['content'],
|
||||||
'content' => $object['content'],
|
'post_format' => $this->map_type_to_post_format( $object['type'] ),
|
||||||
'post_format' => $this->map_type_to_post_format( $object['type'] ),
|
'date' => $object['published'],
|
||||||
'date' => $object['published'],
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ( isset( $object['attributedTo'] ) ) {
|
||||||
|
$meta = \Activitypub\get_remote_metadata_by_actor( $object['attributedTo'] );
|
||||||
|
$this->log( 'Attributed to ' . $object['attributedTo'], compact( 'meta' ) );
|
||||||
|
if ( isset( $meta['name'] ) ) {
|
||||||
|
$override_author = $meta['name'];
|
||||||
|
} elseif ( isset( $meta['preferredUsername'] ) ) {
|
||||||
|
$override_author = $meta['preferredUsername'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->log(
|
||||||
|
'Received feed item',
|
||||||
|
array(
|
||||||
|
'url' => $object['url'],
|
||||||
|
'data' => $data,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$item = new \Friends\Feed_Item( $data );
|
||||||
|
|
||||||
$this->friends_feed->process_incoming_feed_items( array( $item ), $user_feed );
|
$this->friends_feed->process_incoming_feed_items( array( $item ), $user_feed );
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -250,27 +270,7 @@ class Friends_Feed_Parser_ActivityPub extends \Friends\Feed_Parser {
|
||||||
}
|
}
|
||||||
$this->log( 'Received response', compact( 'url', 'object' ) );
|
$this->log( 'Received response', compact( 'url', 'object' ) );
|
||||||
|
|
||||||
$data = array(
|
return $this->handle_incoming_post( $object, $user_feed );
|
||||||
'permalink' => $url,
|
|
||||||
'content' => $object['content'],
|
|
||||||
'post_format' => $this->map_type_to_post_format( $object['type'] ),
|
|
||||||
'date' => $object['published'],
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( isset( $object['attributedTo'] ) ) {
|
|
||||||
$meta = \Activitypub\get_remote_metadata_by_actor( $object['attributedTo'] );
|
|
||||||
$this->log( 'Attributed to ' . $object['attributedTo'], compact( 'meta' ) );
|
|
||||||
if ( isset( $meta['name'] ) ) {
|
|
||||||
$data['author'] = $meta['name'];
|
|
||||||
} elseif ( isset( $meta['preferredUsername'] ) ) {
|
|
||||||
$data['author'] = $meta['preferredUsername'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->log( 'Received feed item', compact( 'url', 'data' ) );
|
|
||||||
|
|
||||||
$item = new \Friends\Feed_Item( $data );
|
|
||||||
|
|
||||||
$this->friends_feed->process_incoming_feed_items( array( $item ), $user_feed );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,6 +19,10 @@ require_once $_tests_dir . '/includes/functions.php';
|
||||||
*/
|
*/
|
||||||
function _manually_load_plugin() {
|
function _manually_load_plugin() {
|
||||||
require \dirname( \dirname( __FILE__ ) ) . '/activitypub.php';
|
require \dirname( \dirname( __FILE__ ) ) . '/activitypub.php';
|
||||||
|
$friends_plugin = \dirname( \dirname( \dirname( __FILE__ ) ) ) . '/friends/friends.php';
|
||||||
|
if ( file_exists( $friends_plugin ) ) {
|
||||||
|
require $friends_plugin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
\tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
\tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );
|
||||||
|
|
||||||
|
|
200
tests/test-class-friends-feed-parser-activitypub.php
Normal file
200
tests/test-class-friends-feed-parser-activitypub.php
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Test_Friends_Feed_Parser_ActivityPub extends \WP_UnitTestCase {
|
||||||
|
public static $users = array();
|
||||||
|
|
||||||
|
public function set_up() {
|
||||||
|
if ( ! class_exists( '\Friends\Friends' ) ) {
|
||||||
|
return $this->markTestSkipped( 'The Friends plugin is not loaded.' );
|
||||||
|
}
|
||||||
|
parent::set_up();
|
||||||
|
|
||||||
|
// Manually activate the REST server.
|
||||||
|
global $wp_rest_server;
|
||||||
|
$wp_rest_server = new \Spy_REST_Server();
|
||||||
|
$this->server = $wp_rest_server;
|
||||||
|
do_action( 'rest_api_init' );
|
||||||
|
|
||||||
|
add_filter(
|
||||||
|
'rest_url',
|
||||||
|
function() {
|
||||||
|
return get_option( 'home' ) . '/wp-json/';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
add_filter( 'pre_http_request', array( get_called_class(), 'pre_http_request' ), 10, 3 );
|
||||||
|
add_filter( 'http_request_host_is_external', array( get_called_class(), 'http_request_host_is_external' ), 10, 2 );
|
||||||
|
add_filter( 'http_request_args', array( get_called_class(), 'http_request_args' ), 10, 2 );
|
||||||
|
add_filter( 'pre_get_remote_metadata_by_actor', array( get_called_class(), 'pre_get_remote_metadata_by_actor' ), 10, 2 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tear_down() {
|
||||||
|
remove_filter( 'pre_http_request', array( get_called_class(), 'pre_http_request' ) );
|
||||||
|
remove_filter( 'http_request_host_is_external', array( get_called_class(), 'http_request_host_is_external' ) );
|
||||||
|
remove_filter( 'http_request_args', array( get_called_class(), 'http_request_args' ) );
|
||||||
|
remove_filter( 'pre_get_remote_metadata_by_actor', array( get_called_class(), 'pre_get_remote_metadata_by_actor' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function pre_get_remote_metadata_by_actor( $pre, $actor ) {
|
||||||
|
if ( isset( self::$users[ $actor ] ) ) {
|
||||||
|
return self::$users[ $actor ];
|
||||||
|
}
|
||||||
|
return $pre;
|
||||||
|
}
|
||||||
|
public static function http_request_host_is_external( $in, $host ) {
|
||||||
|
if ( in_array( $host, array( 'mastodon.local' ), true ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return $in;
|
||||||
|
}
|
||||||
|
public static function http_request_args( $args, $url ) {
|
||||||
|
if ( in_array( parse_url( $url, PHP_URL_HOST ), array( 'mastodon.local' ), true ) ) {
|
||||||
|
$args['reject_unsafe_urls'] = false;
|
||||||
|
}
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
public static function pre_http_request( $preempt, $request, $url ) {
|
||||||
|
$home_url = home_url();
|
||||||
|
|
||||||
|
// Pretend the url now is the requested one.
|
||||||
|
update_option( 'home', $p['scheme'] . '://' . $p['host'] );
|
||||||
|
$rest_prefix = home_url() . '/wp-json';
|
||||||
|
|
||||||
|
if ( false === strpos( $url, $rest_prefix ) ) {
|
||||||
|
// Restore the old home_url.
|
||||||
|
update_option( 'home', $home_url );
|
||||||
|
return $preempt;
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = substr( $url, strlen( $rest_prefix ) );
|
||||||
|
$r = new \WP_REST_Request( $request['method'], $url );
|
||||||
|
if ( ! empty( $request['body'] ) ) {
|
||||||
|
foreach ( $request['body'] as $key => $value ) {
|
||||||
|
$r->set_param( $key, $value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global $wp_rest_server;
|
||||||
|
$response = $wp_rest_server->dispatch( $r );
|
||||||
|
// Restore the old url.
|
||||||
|
update_option( 'home', $home_url );
|
||||||
|
|
||||||
|
return apply_filters(
|
||||||
|
'fake_http_response',
|
||||||
|
array(
|
||||||
|
'headers' => array(
|
||||||
|
'content-type' => 'text/json',
|
||||||
|
),
|
||||||
|
'body' => wp_json_encode( $response->data ),
|
||||||
|
'response' => array(
|
||||||
|
'code' => $response->status,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
$p['scheme'] . '://' . $p['host'],
|
||||||
|
$url,
|
||||||
|
$request
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_incoming_post() {
|
||||||
|
$now = time() - 10;
|
||||||
|
$status_id = 123;
|
||||||
|
|
||||||
|
$friend_name = 'Alex';
|
||||||
|
$actor = 'https://mastodon.local/users/alex';
|
||||||
|
|
||||||
|
$friend_id = $this->factory->user->create(
|
||||||
|
array(
|
||||||
|
'user_login' => 'alex-mastodon.local',
|
||||||
|
'display_name' => $friend_name,
|
||||||
|
'role' => 'friend',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
\Friends\User_Feed::save(
|
||||||
|
new \Friends\User( $friend_id ),
|
||||||
|
$actor,
|
||||||
|
array(
|
||||||
|
'parser' => 'activitypub',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
self::$users[ $actor ] = array(
|
||||||
|
'url' => $actor,
|
||||||
|
'name' => $friend_name,
|
||||||
|
);
|
||||||
|
self::$users['https://mastodon.local/@alex'] = self::$users[ $actor ];
|
||||||
|
|
||||||
|
$posts = get_posts(
|
||||||
|
array(
|
||||||
|
'post_type' => \Friends\Friends::CPT,
|
||||||
|
'author' => $friend_id,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals( 0, count( $posts ) );
|
||||||
|
|
||||||
|
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/' . get_current_user_id() . '/inbox' );
|
||||||
|
$request->set_param( 'type', 'Create' );
|
||||||
|
$request->set_param( 'id', 'test1' );
|
||||||
|
$request->set_param( 'actor', $actor );
|
||||||
|
$date = date( \DATE_W3C, $now++ );
|
||||||
|
$content = 'Test ' . $date . ' ' . rand();
|
||||||
|
$request->set_param(
|
||||||
|
'object',
|
||||||
|
array(
|
||||||
|
'type' => 'Note',
|
||||||
|
'id' => 'test1',
|
||||||
|
'attributedTo' => $actor,
|
||||||
|
'content' => $content,
|
||||||
|
'url' => 'https://mastodon.local/users/alex/statuses/' . ( $status_id++ ),
|
||||||
|
'published' => $date,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = $this->server->dispatch( $request );
|
||||||
|
$this->assertEquals( 202, $response->get_status() );
|
||||||
|
|
||||||
|
$posts = get_posts(
|
||||||
|
array(
|
||||||
|
'post_type' => \Friends\Friends::CPT,
|
||||||
|
'author' => $friend_id,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals( 1, count( $posts ) );
|
||||||
|
$this->assertEquals( $content, $posts[0]->post_content );
|
||||||
|
$this->assertEquals( $friend_id, $posts[0]->post_author );
|
||||||
|
|
||||||
|
$request = new \WP_REST_Request( 'POST', '/activitypub/1.0/users/' . get_current_user_id() . '/inbox' );
|
||||||
|
$request->set_param( 'type', 'Create' );
|
||||||
|
$request->set_param( 'id', 'test1' );
|
||||||
|
$request->set_param( 'actor', 'https://mastodon.local/@alex' );
|
||||||
|
$date = date( \DATE_W3C, $now++ );
|
||||||
|
$content = 'Test ' . $date . ' ' . rand();
|
||||||
|
$request->set_param(
|
||||||
|
'object',
|
||||||
|
array(
|
||||||
|
'type' => 'Note',
|
||||||
|
'id' => 'test2',
|
||||||
|
'attributedTo' => 'https://mastodon.local/@alex',
|
||||||
|
'content' => $content,
|
||||||
|
'url' => 'https://mastodon.local/users/alex/statuses/' . ( $status_id++ ),
|
||||||
|
'published' => $date,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$response = $this->server->dispatch( $request );
|
||||||
|
$this->assertEquals( 202, $response->get_status() );
|
||||||
|
|
||||||
|
$posts = get_posts(
|
||||||
|
array(
|
||||||
|
'post_type' => \Friends\Friends::CPT,
|
||||||
|
'author' => $friend_id,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals( 2, count( $posts ) );
|
||||||
|
$this->assertEquals( $content, $posts[0]->post_content );
|
||||||
|
$this->assertEquals( $friend_id, $posts[0]->post_author );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue