Fix deletion of cached event when event source is removed, added tests.
Some checks failed
PHP Code Checker / PHP Code Checker (pull_request) Failing after 47s
PHPUnit / PHPUnit – PHP 7.4 (pull_request) Successful in 1m8s
PHPUnit / PHPUnit – PHP 8.0 (pull_request) Successful in 1m4s
PHPUnit / PHPUnit – PHP 8.1 (pull_request) Successful in 1m3s
PHPUnit / PHPUnit – PHP 8.3 (pull_request) Has been cancelled
PHPUnit / PHPUnit – PHP 8.4 (pull_request) Has been cancelled
PHPUnit / PHPUnit – PHP 8.2 (pull_request) Has been cancelled

This commit is contained in:
André Menrath 2025-01-03 10:07:00 +01:00
parent f683893284
commit b7747de5ac
2 changed files with 113 additions and 18 deletions

View file

@ -245,34 +245,28 @@ class Event_Sources {
* @return void * @return void
*/ */
public static function delete_events_by_event_source( $event_source_id ) { public static function delete_events_by_event_source( $event_source_id ) {
$args = array( global $wpdb;
'author' => 0, // Currently we do not use a special user or special users. $results = $wpdb->get_results(
'posts_per_page' => -1, // Retrieve all matching posts. $wpdb->prepare(
'meta_key' => '_event_bridge_for_activitypub_event_source', "SELECT * FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s",
'meta_query' => array( '_event_bridge_for_activitypub_event_source',
array( esc_sql( $event_source_id )
'key' => '_event_bridge_for_activitypub_event_source', )
'value' => $event_source_id,
'compare' => '=',
),
),
); );
$query = new \WP_Query( $args );
// If no matching posts are found, return early. // If no matching posts are found, return early.
if ( ! $query->have_posts() ) { if ( empty( $results ) || ! $results ) {
return; return;
} }
// Loop through the posts and delete them permanently. // Loop through the posts and delete them permanently.
foreach ( $query->posts as $post ) { foreach ( $results as $post ) {
// Check if the post has a thumbnail. // Check if the post has a thumbnail.
$thumbnail_id = get_post_thumbnail_id( $post->ID ); $thumbnail_id = get_post_thumbnail_id( $post->post_id );
if ( $thumbnail_id ) { if ( $thumbnail_id ) {
// Remove the thumbnail from the post. // Remove the thumbnail from the post.
\delete_post_thumbnail( $post->ID ); \delete_post_thumbnail( $post->post_id );
// Delete the attachment (and its files) from the media library. // Delete the attachment (and its files) from the media library.
if ( self::is_attachment_featured_image( $thumbnail_id ) ) { if ( self::is_attachment_featured_image( $thumbnail_id ) ) {
@ -280,7 +274,7 @@ class Event_Sources {
} }
} }
\wp_delete_post( $post->ID, true ); \wp_delete_post( $post->post_id , true );
} }
// Clean up the query. // Clean up the query.

View file

@ -30,6 +30,15 @@ class Test_Event_Sources extends \WP_UnitTestCase {
'summary' => 'Just a random organizer of events in the Fediverse', 'summary' => 'Just a random organizer of events in the Fediverse',
); );
const FOLLOWED_ACTOR_2 = array(
'id' => 'https://remote.example/@organizer2',
'type' => 'Person',
'inbox' => 'https://remote.example/@organizer2/inbox',
'outbox' => 'https://remote.example/@organizer2/outbox',
'name' => 'The Second Organizer',
'summary' => 'Just a second random organizer of events in the Fediverse',
);
/** /**
* REST Server. * REST Server.
* *
@ -312,4 +321,96 @@ class Test_Event_Sources extends \WP_UnitTestCase {
\remove_filter( 'activitypub_defer_signature_verification', '__return_true' ); \remove_filter( 'activitypub_defer_signature_verification', '__return_true' );
} }
/**
* Test receiving "Accept" of "Follow".
*/
public function test_delete_cached_events_of_removed_event_sources() {
\add_filter( 'activitypub_defer_signature_verification', '__return_true' );
// Check that we have three event posts.
$event_query = Event_Query::get_instance();
$the_query = $event_query->get_upcoming_events();
$this->assertEquals( 0, $the_query->post_count );
// Add second event source.
\Event_Bridge_For_ActivityPub\ActivityPub\Model\Event_Source::init_from_array( self::FOLLOWED_ACTOR_2 )->save();
\Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources::delete_event_source_transients();
// Receive first event of first Organizer.
$json = array(
'id' => 'https://remote.example/@organizer/events/new-year-party#create',
'type' => 'Create',
'actor' => 'https://remote.example/@organizer',
'object' => array(
'id' => 'https://remote.example/@organizer/events/new-year-party',
'type' => 'Event',
'name' => 'Fediverse Party',
'startTime' => \gmdate( 'Y-m-d\TH:i:s\Z', time() + WEEK_IN_SECONDS ),
'endTime' => \gmdate( 'Y-m-d\TH:i:s\Z', time() + WEEK_IN_SECONDS + HOUR_IN_SECONDS ),
'to' => 'https://www.w3.org/ns/activitystreams#Public',
'published' => '2020-01-01T00:00:00Z',
),
);
$request = new WP_REST_Request( 'POST', '/activitypub/1.0/users/0/inbox' );
$request->set_header( 'Content-Type', 'application/activity+json' );
$request->set_body( \wp_json_encode( $json ) );
$response = \rest_do_request( $request );
$this->assertEquals( 202, $response->get_status() );
$the_query = $event_query->get_upcoming_events();
$this->assertEquals( 1, $the_query->post_count );
// Second event of first organizer.
$json = array(
'id' => 'https://remote.example/@organizer/events/birthday-party#create',
'type' => 'Create',
'actor' => 'https://remote.example/@organizer',
'object' => array(
'id' => 'https://remote.example/@organizer/events/birthday-party',
'type' => 'Event',
'name' => 'Fediverse Party',
'startTime' => \gmdate( 'Y-m-d\TH:i:s\Z', time() + 2* WEEK_IN_SECONDS ),
'endTime' => \gmdate( 'Y-m-d\TH:i:s\Z', time() + 2* WEEK_IN_SECONDS + HOUR_IN_SECONDS ),
'to' => 'https://www.w3.org/ns/activitystreams#Public',
'published' => '2020-01-01T00:00:00Z',
),
);
$request->set_body( \wp_json_encode( $json ) );
$response = \rest_do_request( $request );
$this->assertEquals( 202, $response->get_status() );
$the_query = $event_query->get_upcoming_events();
$this->assertEquals( 2, $the_query->post_count );
// Receive event of other organizer.
$json = array(
'id' => 'https://remote.example/@organizer2/events/concert#create',
'type' => 'Create',
'actor' => 'https://remote.example/@organizer2',
'object' => array(
'id' => 'https://remote.example/@organizer2/events/concert',
'type' => 'Event',
'name' => 'Concert',
'startTime' => \gmdate( 'Y-m-d\TH:i:s\Z', time() + 3 * WEEK_IN_SECONDS ),
'endTime' => \gmdate( 'Y-m-d\TH:i:s\Z', time() + 3 * WEEK_IN_SECONDS + HOUR_IN_SECONDS ),
'to' => 'https://www.w3.org/ns/activitystreams#Public',
'published' => '2020-01-01T00:00:00Z',
),
);
$request->set_body( \wp_json_encode( $json ) );
$response = \rest_do_request( $request );
$this->assertEquals( 202, $response->get_status() );
$the_query = $event_query->get_upcoming_events();
$this->assertEquals( 3, $the_query->post_count );
// Remove first event source.
$result = \Event_Bridge_For_ActivityPub\ActivityPub\Collection\Event_Sources::remove_event_source( 'https://remote.example/@organizer' );
// Verify that event posts got deleted.
$the_query = $event_query->get_upcoming_events();
$this->assertEquals( 1, $the_query->post_count );
\remove_filter( 'activitypub_defer_signature_verification', '__return_true' );
}
} }