-
Notifications
You must be signed in to change notification settings - Fork 82
Follow[ers|ing]: Avoid errors when getting avatar url #2088
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
68dae04
Add unit tests for Followers table column_username method
obenland 9fc7915
Complete Followers table test with real prepare_items() integration
obenland 1f29e2d
Add Following table test with real prepare_items() integration
obenland 9aee20d
Fix Following table icon processing and improve test formatting
obenland 1b4ce1b
Add changelog
matticbot 3b6c223
Merge branch 'trunk' into add-followers-table-tests
obenland 1c64aa3
Add test for icon arrays in Following table
obenland b56c32b
Fix object_to_uri to handle Image objects with URL arrays
obenland 855650c
Merge branch 'trunk' into add-followers-table-tests
obenland File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: minor | ||
Type: added | ||
|
||
Add comprehensive unit tests for Followers and Following table classes with proper ActivityPub icon object handling. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -223,7 +223,7 @@ public function prepare_items() { | |
|
||
$this->items[] = array( | ||
'id' => $follower->ID, | ||
'icon' => $actor->get_icon()['url'] ?? '', | ||
'icon' => object_to_uri( $actor->get_icon() ?? '' ), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, nice solution! never thought about using it here! |
||
'post_title' => $actor->get_name() ?? $actor->get_preferred_username(), | ||
'username' => $actor->get_preferred_username(), | ||
'url' => $url, | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
<?php | ||
/** | ||
* Test file for Followers Table. | ||
* | ||
* @package Activitypub | ||
*/ | ||
|
||
namespace Activitypub\Tests\WP_Admin\Table; | ||
|
||
use Activitypub\WP_Admin\Table\Followers; | ||
use Activitypub\Collection\Followers as Follower_Collection; | ||
|
||
/** | ||
* Test class for Followers Table. | ||
* | ||
* @coversDefaultClass \Activitypub\WP_Admin\Table\Followers | ||
*/ | ||
class Test_Followers extends \WP_UnitTestCase { | ||
|
||
/** | ||
* Followers table instance. | ||
* | ||
* @var Followers | ||
*/ | ||
private $followers_table; | ||
|
||
/** | ||
* Set up before each test. | ||
*/ | ||
public function set_up() { | ||
parent::set_up(); | ||
|
||
// Set up global screen mock. | ||
set_current_screen( 'users_page_activitypub-followers-list' ); | ||
|
||
// Set current user. | ||
wp_set_current_user( 1 ); | ||
|
||
// Create followers table instance. | ||
$this->followers_table = new Followers(); | ||
} | ||
|
||
/** | ||
* Test column_username with actor having icon object. | ||
* | ||
* @covers ::column_username | ||
* @covers ::prepare_items | ||
*/ | ||
public function test_column_username_with_icon_object() { | ||
// Mock remote metadata for the actor with icon object. | ||
$actor_url = 'https://example.com/users/testuser'; | ||
$actor_data = array( | ||
'name' => 'Test User', | ||
'icon' => array( | ||
'type' => 'Image', | ||
'url' => 'https://secure.gravatar.com/avatar/example?s=120&d=mm&r=g', | ||
), | ||
'url' => $actor_url, | ||
'id' => 'https://example.com/users/testuser', | ||
'preferredUsername' => 'testuser', | ||
'inbox' => 'https://example.com/users/testuser/inbox', | ||
); | ||
|
||
// Mock the remote metadata call using the correct filter. | ||
add_filter( | ||
'pre_get_remote_metadata_by_actor', | ||
function ( $value, $actor ) use ( $actor_url, $actor_data ) { | ||
if ( $actor === $actor_url ) { | ||
return $actor_data; | ||
} | ||
return $value; | ||
}, | ||
10, | ||
2 | ||
); | ||
|
||
// Add the follower. | ||
Follower_Collection::add_follower( get_current_user_id(), $actor_url ); | ||
|
||
// Use the real prepare_items() method. | ||
$this->followers_table->prepare_items(); | ||
|
||
// Verify we have items. | ||
$this->assertNotEmpty( $this->followers_table->items ); | ||
|
||
// Get the first item and test column_username. | ||
$item = $this->followers_table->items[0]; | ||
$result = $this->followers_table->column_username( $item ); | ||
|
||
// Verify the icon URL was extracted from the object by object_to_uri() and properly rendered. | ||
$this->assertStringContainsString( 'src="https://secure.gravatar.com/avatar/example?s=120&d=mm&r=g"', $result ); | ||
|
||
// Verify that the icon was processed correctly: from object to URL. | ||
$this->assertEquals( 'https://secure.gravatar.com/avatar/example?s=120&d=mm&r=g', $item['icon'] ); | ||
|
||
// Clean up. | ||
\remove_all_filters( 'pre_get_remote_metadata_by_actor' ); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
<?php | ||
/** | ||
* Test file for Following Table. | ||
* | ||
* @package Activitypub | ||
*/ | ||
|
||
namespace Activitypub\Tests\WP_Admin\Table; | ||
|
||
use Activitypub\Collection\Actors; | ||
use Activitypub\Collection\Following as Following_Collection; | ||
use Activitypub\WP_Admin\Table\Following; | ||
|
||
/** | ||
* Test class for Following Table. | ||
* | ||
* @coversDefaultClass \Activitypub\WP_Admin\Table\Following | ||
*/ | ||
class Test_Following extends \WP_UnitTestCase { | ||
|
||
/** | ||
* Following table instance. | ||
* | ||
* @var Following | ||
*/ | ||
private $following_table; | ||
|
||
/** | ||
* Set up before each test. | ||
*/ | ||
public function set_up() { | ||
parent::set_up(); | ||
|
||
// Set up global screen mock. | ||
set_current_screen( 'users_page_activitypub-following-list' ); | ||
|
||
// Set current user. | ||
wp_set_current_user( 1 ); | ||
|
||
// Create following table instance. | ||
$this->following_table = new Following(); | ||
} | ||
|
||
/** | ||
* Test column_username with actor having icon object using real prepare_items(). | ||
* | ||
* This test uses Following::follow() to create a real following and uses | ||
* the actual prepare_items() method to test the complete data flow from | ||
* ActivityPub actor with icon object to the final column output. | ||
* | ||
* @covers ::column_username | ||
* @covers ::prepare_items | ||
*/ | ||
public function test_column_username_with_icon_object() { | ||
// Mock remote metadata for the actor with icon object. | ||
$actor_url = 'https://example.com/users/testuser'; | ||
$actor_data = array( | ||
'name' => 'Test User', | ||
'icon' => array( | ||
'type' => 'Image', | ||
'url' => 'https://secure.gravatar.com/avatar/example?s=120&d=mm&r=g', | ||
), | ||
'url' => $actor_url, | ||
'id' => 'https://example.com/users/testuser', | ||
'preferredUsername' => 'testuser', | ||
'inbox' => 'https://example.com/users/testuser/inbox', | ||
); | ||
|
||
// Mock the remote metadata call using the correct filter. | ||
add_filter( | ||
'pre_get_remote_metadata_by_actor', | ||
function ( $value, $actor ) use ( $actor_url, $actor_data ) { | ||
if ( $actor === $actor_url ) { | ||
return $actor_data; | ||
} | ||
return $value; | ||
}, | ||
10, | ||
2 | ||
); | ||
|
||
// Add the actor first, then follow them. | ||
$actor_post_id = Actors::upsert( $actor_data ); | ||
|
||
// Follow the actor using the proper method. | ||
Following_Collection::follow( $actor_post_id, get_current_user_id() ); | ||
|
||
// Use the real prepare_items() method. | ||
$this->following_table->prepare_items(); | ||
|
||
// Verify we have items. | ||
$this->assertNotEmpty( $this->following_table->items ); | ||
|
||
// Get the first item and test column_username. | ||
$item = $this->following_table->items[0]; | ||
$result = $this->following_table->column_username( $item ); | ||
|
||
// Verify the icon URL was extracted from the object by object_to_uri() and properly rendered. | ||
$this->assertStringContainsString( 'src="https://secure.gravatar.com/avatar/example?s=120&d=mm&r=g"', $result ); | ||
|
||
// Verify that the icon was processed correctly: from object to URL. | ||
$this->assertEquals( 'https://secure.gravatar.com/avatar/example?s=120&d=mm&r=g', $item['icon'] ); | ||
|
||
// Clean up. | ||
\remove_all_filters( 'pre_get_remote_metadata_by_actor' ); | ||
obenland marked this conversation as resolved.
Show resolved
Hide resolved
|
||
wp_delete_post( $actor_post_id, true ); | ||
} | ||
|
||
/** | ||
* Test prepare_items with actor having icon array of URLs. | ||
* | ||
* This test verifies that when an icon field contains an array of URLs, | ||
* the object_to_uri() function correctly extracts the first URL from the array. | ||
* | ||
* @covers ::prepare_items | ||
*/ | ||
public function test_prepare_items_with_icon_array_of_urls() { | ||
// Mock remote metadata for the actor with icon as direct array of URLs. | ||
$actor_url = 'https://example.com/users/arrayuser'; | ||
$actor_data = array( | ||
'name' => 'Array User', | ||
'icon' => array( | ||
'url' => array( | ||
'https://example.com/storage/profile.webp', | ||
), | ||
'type' => 'Image', | ||
'mediaType' => 'image/webp', | ||
), | ||
'url' => $actor_url, | ||
'id' => 'https://example.com/users/arrayuser', | ||
'preferredUsername' => 'arrayuser', | ||
'inbox' => 'https://example.com/users/arrayuser/inbox', | ||
); | ||
|
||
// Mock the remote metadata call using the correct filter. | ||
add_filter( | ||
'pre_get_remote_metadata_by_actor', | ||
function ( $value, $actor ) use ( $actor_url, $actor_data ) { | ||
if ( $actor === $actor_url ) { | ||
return $actor_data; | ||
} | ||
return $value; | ||
}, | ||
10, | ||
2 | ||
); | ||
|
||
// Add the actor first, then follow them. | ||
$actor_post_id = Actors::upsert( $actor_data ); | ||
|
||
// Follow the actor using the proper method. | ||
Following_Collection::follow( $actor_post_id, get_current_user_id() ); | ||
|
||
// Use the real prepare_items() method. | ||
$this->following_table->prepare_items(); | ||
|
||
// Verify that the icon array was processed correctly: from array to first URL. | ||
$this->assertEquals( 'https://example.com/storage/profile.webp', $this->following_table->items[0]['icon'] ); | ||
|
||
// Clean up. | ||
\remove_all_filters( 'pre_get_remote_metadata_by_actor' ); | ||
wp_delete_post( $actor_post_id, true ); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just wanted to suggest that :)
nice 👍