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
*/
public static function delete_events_by_event_source( $event_source_id ) {
$args = array(
'author' => 0, // Currently we do not use a special user or special users.
'posts_per_page' => -1, // Retrieve all matching posts.
'meta_key' => '_event_bridge_for_activitypub_event_source',
'meta_query' => array(
array(
'key' => '_event_bridge_for_activitypub_event_source',
'value' => $event_source_id,
'compare' => '=',
),
),
global $wpdb;
$results = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s",
'_event_bridge_for_activitypub_event_source',
esc_sql( $event_source_id )
)
);
$query = new \WP_Query( $args );
// If no matching posts are found, return early.
if ( ! $query->have_posts() ) {
if ( empty( $results ) || ! $results ) {
return;
}
// Loop through the posts and delete them permanently.
foreach ( $query->posts as $post ) {
foreach ( $results as $post ) {
// 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 ) {
// 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.
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.

View file

@ -30,6 +30,15 @@ class Test_Event_Sources extends \WP_UnitTestCase {
'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.
*
@ -312,4 +321,96 @@ class Test_Event_Sources extends \WP_UnitTestCase {
\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' );
}
}