mirror of
https://github.com/Automattic/wordpress-activitypub
synced 2024-10-18 12:23:32 +00:00
Enable Mastodon Apps: Add followers_count to internal accounts (#676)
* Mock http requests, add followers_count to account object * Remove one more MockAction * Add one more assert * cleanup * cleanup * use Users class, to check if user is really an ActivityPub user --------- Co-authored-by: Matthias Pfefferle <pfefferle@users.noreply.github.com>
This commit is contained in:
parent
e560d1b5b6
commit
dad6b73cdb
3 changed files with 166 additions and 62 deletions
|
@ -3,6 +3,7 @@ namespace Activitypub\Integration;
|
|||
|
||||
use DateTime;
|
||||
use Activitypub\Webfinger as Webfinger_Util;
|
||||
use Activitypub\Collection\Users;
|
||||
use Activitypub\Collection\Followers;
|
||||
use Enable_Mastodon_Apps\Entity\Account;
|
||||
|
||||
|
@ -21,6 +22,7 @@ class Enable_Mastodon_Apps {
|
|||
*/
|
||||
public static function init() {
|
||||
\add_filter( 'mastodon_api_account_followers', array( self::class, 'api_account_followers' ), 10, 2 );
|
||||
\add_filter( 'mastodon_api_account', array( self::class, 'api_account_add_followers' ), 20, 2 );
|
||||
\add_filter( 'mastodon_api_account', array( self::class, 'api_account_external' ), 10, 2 );
|
||||
}
|
||||
|
||||
|
@ -84,6 +86,21 @@ class Enable_Mastodon_Apps {
|
|||
return $followers;
|
||||
}
|
||||
|
||||
public static function api_account_add_followers( $account, $user_id ) {
|
||||
if ( ! $account instanceof Account ) {
|
||||
return $account;
|
||||
}
|
||||
|
||||
$user = Users::get_by_id( $user_id );
|
||||
|
||||
if ( ! $user || is_wp_error( $user ) ) {
|
||||
return $account;
|
||||
}
|
||||
|
||||
$account->followers_count = Followers::count_followers( $user_id );
|
||||
return $account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve external accounts for Mastodon API
|
||||
*
|
||||
|
@ -106,7 +123,7 @@ class Enable_Mastodon_Apps {
|
|||
$acct = Webfinger_Util::uri_to_acct( $uri );
|
||||
$data = get_remote_metadata_by_actor( $uri );
|
||||
|
||||
if ( ! $data ) {
|
||||
if ( ! $data || is_wp_error( $data ) ) {
|
||||
return $user_data;
|
||||
}
|
||||
|
||||
|
@ -121,7 +138,9 @@ class Enable_Mastodon_Apps {
|
|||
$account->acct = $acct;
|
||||
$account->display_name = $data['name'];
|
||||
$account->url = $uri;
|
||||
$account->note = $data['summary'];
|
||||
if ( ! empty( $data['summary'] ) ) {
|
||||
$account->note = $data['summary'];
|
||||
}
|
||||
|
||||
if ( isset( $data['icon']['type'] ) && isset( $data['icon']['url'] ) && 'Image' === $data['icon']['type'] ) {
|
||||
$account->avatar = $data['icon']['url'];
|
||||
|
|
|
@ -64,9 +64,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
public function test_get_followers() {
|
||||
$followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' );
|
||||
|
||||
$pre_http_request = new MockAction();
|
||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||
|
||||
foreach ( $followers as $follower ) {
|
||||
$response = \Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
}
|
||||
|
@ -86,9 +83,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
}
|
||||
|
||||
public function test_add_follower() {
|
||||
$pre_http_request = new MockAction();
|
||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||
|
||||
$follower = 'https://12345.example.com';
|
||||
$follower2 = 'https://user2.example.com';
|
||||
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
|
@ -103,9 +97,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
}
|
||||
|
||||
public function test_add_follower_error() {
|
||||
$pre_http_request = new MockAction();
|
||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||
|
||||
$follower = 'error@example.com';
|
||||
|
||||
$result = \Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
|
@ -127,9 +118,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
$followers = array( 'https://example.com/author/jon' );
|
||||
$followers2 = array( 'https://user2.example.com' );
|
||||
|
||||
$pre_http_request = new MockAction();
|
||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||
|
||||
foreach ( $followers as $follower ) {
|
||||
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
}
|
||||
|
@ -162,9 +150,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
);
|
||||
$followers2 = array( 'https://user2.example.com' );
|
||||
|
||||
$pre_http_request = new MockAction();
|
||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||
|
||||
foreach ( $followers as $follower ) {
|
||||
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
|
@ -200,9 +185,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
public function test_get_outdated_followers() {
|
||||
$followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' );
|
||||
|
||||
$pre_http_request = new MockAction();
|
||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||
|
||||
foreach ( $followers as $follower ) {
|
||||
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
}
|
||||
|
@ -240,9 +222,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
public function test_get_faulty_followers() {
|
||||
$followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' );
|
||||
|
||||
$pre_http_request = new MockAction();
|
||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||
|
||||
foreach ( $followers as $follower ) {
|
||||
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
}
|
||||
|
@ -272,9 +251,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
}
|
||||
|
||||
public function test_add_duplicate_follower() {
|
||||
$pre_http_request = new MockAction();
|
||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||
|
||||
$follower = 'https://12345.example.com';
|
||||
|
||||
\Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
|
@ -295,9 +271,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
}
|
||||
|
||||
public function test_migration() {
|
||||
$pre_http_request = new MockAction();
|
||||
add_filter( 'pre_http_request', array( $pre_http_request, 'filter' ), 10, 3 );
|
||||
|
||||
$followers = array(
|
||||
'https://example.com/author/jon',
|
||||
'https://example.og/errors',
|
||||
|
@ -405,36 +378,6 @@ class Test_Activitypub_Followers extends WP_UnitTestCase {
|
|||
$this->assertCount( 30, $followers );
|
||||
}
|
||||
|
||||
public static function http_request_host_is_external( $in, $host ) {
|
||||
if ( in_array( $host, array( 'example.com', 'example.org' ), true ) ) {
|
||||
return true;
|
||||
}
|
||||
return $in;
|
||||
}
|
||||
|
||||
public static function http_request_args( $args, $url ) {
|
||||
if ( in_array( wp_parse_url( $url, PHP_URL_HOST ), array( 'example.com', 'example.org' ), true ) ) {
|
||||
$args['reject_unsafe_urls'] = false;
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
public static function pre_http_request( $preempt, $request, $url ) {
|
||||
return array(
|
||||
'headers' => array(
|
||||
'content-type' => 'text/json',
|
||||
),
|
||||
'body' => '',
|
||||
'response' => array(
|
||||
'code' => 202,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public static function http_response( $response, $args, $url ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
public static function pre_get_remote_metadata_by_actor( $pre, $actor ) {
|
||||
if ( isset( self::$users[ $actor ] ) ) {
|
||||
return self::$users[ $actor ];
|
||||
|
|
|
@ -1,15 +1,75 @@
|
|||
<?php
|
||||
class Test_Enable_Mastodon_Apps extends WP_UnitTestCase {
|
||||
public static $users = array(
|
||||
'username@example.org' => array(
|
||||
'id' => 'https://example.org/users/username',
|
||||
'url' => 'https://example.org/users/username',
|
||||
'inbox' => 'https://example.org/users/username/inbox',
|
||||
'name' => 'username',
|
||||
'preferredUsername' => 'username',
|
||||
'published' => '2024-01-01T00:00:00+00:00',
|
||||
),
|
||||
'jon@example.com' => array(
|
||||
'id' => 'https://example.com/author/jon',
|
||||
'url' => 'https://example.com/author/jon',
|
||||
'inbox' => 'https://example.com/author/jon/inbox',
|
||||
'name' => 'jon',
|
||||
'preferredUsername' => 'jon',
|
||||
),
|
||||
'doe@example.org' => array(
|
||||
'id' => 'https://example.org/author/doe',
|
||||
'url' => 'https://example.org/author/doe',
|
||||
'inbox' => 'https://example.org/author/doe/inbox',
|
||||
'name' => 'doe',
|
||||
'preferredUsername' => 'doe',
|
||||
),
|
||||
'sally@example.org' => array(
|
||||
'id' => 'http://sally.example.org',
|
||||
'url' => 'http://sally.example.org',
|
||||
'inbox' => 'http://sally.example.org/inbox',
|
||||
'name' => 'jon',
|
||||
'preferredUsername' => 'jon',
|
||||
),
|
||||
'12345@example.com' => array(
|
||||
'id' => 'https://12345.example.com',
|
||||
'url' => 'https://12345.example.com',
|
||||
'inbox' => 'https://12345.example.com/inbox',
|
||||
'name' => '12345',
|
||||
'preferredUsername' => '12345',
|
||||
),
|
||||
'user2@example.com' => array(
|
||||
'id' => 'https://user2.example.com',
|
||||
'url' => 'https://user2.example.com',
|
||||
'inbox' => 'https://user2.example.com/inbox',
|
||||
'name' => 'úser2',
|
||||
'preferredUsername' => 'user2',
|
||||
),
|
||||
'error@example.com' => array(
|
||||
'url' => 'https://error.example.com',
|
||||
'name' => 'error',
|
||||
'preferredUsername' => 'error',
|
||||
),
|
||||
);
|
||||
|
||||
public function set_up() {
|
||||
parent::set_up();
|
||||
|
||||
if ( ! class_exists( '\Enable_Mastodon_Apps\Entity\Entity' ) ) {
|
||||
self::markTestSkipped( 'The Enable_Mastodon_Apps plugin is not active.' );
|
||||
}
|
||||
add_filter( 'pre_get_remote_metadata_by_actor', array( get_called_class(), 'pre_get_remote_metadata_by_actor' ), 10, 2 );
|
||||
add_filter( 'pre_http_request', array( $this, 'pre_http_request' ), 10, 3 );
|
||||
_delete_all_posts();
|
||||
}
|
||||
|
||||
public function tear_down() {
|
||||
remove_filter( 'pre_get_remote_metadata_by_actor', array( get_called_class(), 'pre_get_remote_metadata_by_actor' ) );
|
||||
remove_filter( 'pre_http_request', array( $this, 'pre_http_request' ), 10, 3 );
|
||||
parent::tear_down();
|
||||
}
|
||||
|
||||
public function test_api_account_external() {
|
||||
$account = apply_filters( 'mastodon_api_account', array(), 'alex@kirk.at' );
|
||||
$account = apply_filters( 'mastodon_api_account', array(), 'username@example.org' );
|
||||
$this->assertNotEmpty( $account );
|
||||
$account = $account->jsonSerialize();
|
||||
$this->assertArrayHasKey( 'id', $account );
|
||||
|
@ -17,7 +77,89 @@ class Test_Enable_Mastodon_Apps extends WP_UnitTestCase {
|
|||
$this->assertArrayHasKey( 'acct', $account );
|
||||
$this->assertArrayHasKey( 'display_name', $account );
|
||||
$this->assertArrayHasKey( 'url', $account );
|
||||
$this->assertEquals( 'https://alex.kirk.at/author/alex/', $account['url'] );
|
||||
$this->assertEquals( 'Alex Kirk', $account['display_name'] );
|
||||
$this->assertEquals( 'https://example.org/users/username', $account['url'] );
|
||||
$this->assertEquals( 'username', $account['display_name'] );
|
||||
}
|
||||
|
||||
public function test_api_account_followers_internal() {
|
||||
$followers = array( 'https://example.com/author/jon', 'https://example.org/author/doe', 'http://sally.example.org' );
|
||||
|
||||
foreach ( $followers as $follower ) {
|
||||
$response = \Activitypub\Collection\Followers::add_follower( 1, $follower );
|
||||
}
|
||||
|
||||
$account = new \Enable_Mastodon_Apps\Entity\Account();
|
||||
$this->assertEquals( 0, $account->followers_count );
|
||||
|
||||
$account = apply_filters( 'mastodon_api_account', $account, 1 );
|
||||
$this->assertEquals( 3, $account->followers_count );
|
||||
}
|
||||
|
||||
public static function pre_http_request( $preempt, $request, $url ) {
|
||||
switch( $url ) {
|
||||
case 'https://example.org/.well-known/webfinger?resource=acct%3Ausername%40example.org':
|
||||
case 'https://example.org/.well-known/webfinger?resource=https%3A%2F%2Fexample.org%2Fusers%2Fusername':
|
||||
return array(
|
||||
'headers' => array(
|
||||
'content-type' => 'text/json',
|
||||
),
|
||||
'body' => json_encode( array(
|
||||
'subject' => 'acct:username@example.org',
|
||||
'links' => array(
|
||||
array(
|
||||
'rel' => 'self',
|
||||
'type' => 'application/activity+json',
|
||||
'href' => 'https://example.org/users/username',
|
||||
),
|
||||
),
|
||||
) ),
|
||||
'response' => array(
|
||||
'code' => 200,
|
||||
),
|
||||
);
|
||||
|
||||
case 'https://example.org/users/username':
|
||||
return array(
|
||||
'headers' => array(
|
||||
'content-type' => 'application/activity+json',
|
||||
),
|
||||
'body' => json_encode( self::$users['username@example.org'] ),
|
||||
'response' => array(
|
||||
'code' => 200,
|
||||
),
|
||||
);
|
||||
}
|
||||
return $preempt;
|
||||
}
|
||||
|
||||
public static function http_response( $response, $args, $url ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
public static function pre_get_remote_metadata_by_actor( $pre, $actor ) {
|
||||
if ( isset( self::$users[ $actor ] ) ) {
|
||||
return self::$users[ $actor ];
|
||||
}
|
||||
foreach ( self::$users as $username => $data ) {
|
||||
if ( $data['url'] === $actor ) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
return $pre;
|
||||
}
|
||||
|
||||
public function extract_name_from_uri_content_provider() {
|
||||
return array(
|
||||
array( 'https://example.com/@user', 'user' ),
|
||||
array( 'https://example.com/@user/', 'user' ),
|
||||
array( 'https://example.com/users/user', 'user' ),
|
||||
array( 'https://example.com/users/user/', 'user' ),
|
||||
array( 'https://example.com/@user?as=asasas', 'user' ),
|
||||
array( 'https://example.com/@user#asass', 'user' ),
|
||||
array( '@user@example.com', 'user' ),
|
||||
array( 'acct:user@example.com', 'user' ),
|
||||
array( 'user@example.com', 'user' ),
|
||||
array( 'https://example.com', 'https://example.com' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue