From 63bf5d26cedd80b2087bf7fe93323b44b54f288f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Menrath?= Date: Fri, 11 Oct 2024 19:05:20 +0200 Subject: [PATCH] add tests --- .forgejo/workflows/phpunit.yml | 5 + composer.json | 3 +- includes/class-reminder.php | 25 +++- includes/class-settings.php | 2 +- templates/settings.php | 10 +- tests/bootstrap.php | 6 +- tests/test-class-plugin-events-manger.php | 2 +- tests/test-class-plugin-gatherpress.php | 4 +- tests/test-class-reminder.php | 168 ++++++++++++++++++++++ 9 files changed, 208 insertions(+), 17 deletions(-) create mode 100644 tests/test-class-reminder.php diff --git a/.forgejo/workflows/phpunit.yml b/.forgejo/workflows/phpunit.yml index b67d8e9..125474c 100644 --- a/.forgejo/workflows/phpunit.yml +++ b/.forgejo/workflows/phpunit.yml @@ -74,6 +74,11 @@ jobs: if: steps.cache-wordpress.outputs.cache-hit != 'false' run: bash bin/install-wp-tests.sh wordpress_test root root 127.0.0.1 6.6 false true true true + - name: Run Feature tests of the ActivityPub Event Bridge + run: cd /workspace/Event-Federation/wordpress-activitypub-event-bridge/ && ./vendor/bin/phpunit --filter=reminder + env: + PHP_VERSION: ${{ matrix.php-version }} + - name: Run Integration tests for The Events Calendar run: cd /workspace/Event-Federation/wordpress-activitypub-event-bridge/ && ./vendor/bin/phpunit --filter=the_events_calendar env: diff --git a/composer.json b/composer.json index 1b3bb36..30c3b01 100644 --- a/composer.json +++ b/composer.json @@ -55,8 +55,9 @@ ], "test-debug": [ "@prepare-test", - "@test-wp-event-manager" + "@test-features" ], + "test-features": "phpunit --filter=reminder", "test-vs-event-list": "phpunit --filter=vs_event_list", "test-the-events-calendar": "phpunit --filter=the_events_calendar", "test-gatherpress": "phpunit --filter=gatherpress", diff --git a/includes/class-reminder.php b/includes/class-reminder.php index e9b83df..eb2e8a1 100644 --- a/includes/class-reminder.php +++ b/includes/class-reminder.php @@ -31,7 +31,9 @@ class Reminder { */ public static function init() { // Post transitions. - \add_action( 'transition_post_status', array( self::class, 'maybe_schedule_event_post_announcement' ), 33, 3 ); + \add_action( 'transition_post_status', array( self::class, 'maybe_schedule_event_reminder' ), 33, 3 ); + + \add_action( 'delete_post', array( self::class, 'unschedule_event_reminder' ), 33, 1 ); // Send an event reminder. \add_action( 'activitypub_event_bridge_send_event_reminder', array( self::class, 'send_event_reminder' ), 10, 1 ); @@ -90,10 +92,10 @@ class Reminder { * @param string $old_status Old post status. * @param WP_Post $post Post object. */ - public static function maybe_schedule_event_post_announcement( $new_status, $old_status, $post ): void { + public static function maybe_schedule_event_reminder( $new_status, $old_status, $post ): void { $reminder_time_gap = (int) get_post_meta( $post->ID, 'activitypub_event_bridge_reminder_time_gap', true ); - if ( '' === $reminder_time_gap ) { + if ( ! $reminder_time_gap ) { $reminder_time_gap = \get_option( 'activitypub_event_bridge_reminder_time_gap', 0 ); } @@ -117,6 +119,10 @@ class Reminder { return; } + if ( 'trash' === $new_status ) { + self::unschedule_event_reminder( $post->ID ); + } + // Do not schedule a reminder if the event is not published. if ( 'publish' !== $new_status ) { return; @@ -147,6 +153,17 @@ class Reminder { \wp_schedule_single_event( $schedule_time, $hook, $args ); } + /** + * Unschedule the event reminder. + * + * @param int $post_id The WordPress post ID of the event post. + */ + public static function unschedule_event_reminder( $post_id ): void { + $hook = 'activitypub_event_bridge_send_event_reminder'; + $args = array( $post_id ); + \wp_clear_scheduled_hook( $hook, $args ); + } + /** * Send a reminder for an event post. * @@ -165,7 +182,7 @@ class Reminder { $user_id = $transformer->get_wp_user_id(); - if ( is_user_disabled( $user_id ) ) { + if ( $user_id > 0 && is_user_disabled( $user_id ) ) { return; } diff --git a/includes/class-settings.php b/includes/class-settings.php index 64deec4..7d5bb8d 100644 --- a/includes/class-settings.php +++ b/includes/class-settings.php @@ -68,7 +68,7 @@ class Settings { array( 'type' => 'array', 'description' => \__( 'Time gap in seconds when a reminder is triggered that the event is about to start.', 'activitypub' ), - 'default' => array(), + 'default' => 0, // Zero leads to this feature being deactivated. 'sanitize_callback' => 'absint', ) ); diff --git a/templates/settings.php b/templates/settings.php index 3f4366b..c01d762 100644 --- a/templates/settings.php +++ b/templates/settings.php @@ -32,11 +32,11 @@ $current_category_mapping = \get_option( 'activitypub_event_bridge_event_ $reminder_time_gap = \get_option( 'activitypub_event_bridge_reminder_time_gap', 0 ); $reminder_time_gap_choices = array( - 0 => __( 'Disabled', 'activitypub-event-bridge' ), - 21600 => __( '6 hours', 'activitypub-event-bridge' ), - 86400 => __( '1 day', 'activitypub-event-bridge' ), - 259200 => __( '3 days', 'activitypub-event-bridge' ), - 604800 => __( '1 week', 'activitypub-event-bridge' ), + 0 => __( 'Disabled', 'activitypub-event-bridge' ), + HOUR_IN_SECONDS * 6 => __( '6 hours', 'activitypub-event-bridge' ), + DAY_IN_SECONDS => __( '1 day', 'activitypub-event-bridge' ), + DAY_IN_SECONDS * 3 => __( '3 days', 'activitypub-event-bridge' ), + WEEK_IN_SECONDS => __( '1 week', 'activitypub-event-bridge' ), ) ?> diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 359543a..560ce4a 100755 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -46,9 +46,6 @@ function _manually_load_plugin() { $plugin_file = null; // See if we want to run integration tests for a specific event-plugin. switch ( $activitypub_event_extension_integration_filter ) { - case 'the_events_calendar': - $plugin_file = 'the-events-calendar/the-events-calendar.php'; - break; case 'vs_event_list': $plugin_file = 'very-simple-event-list/vsel.php'; break; @@ -61,6 +58,9 @@ function _manually_load_plugin() { case 'wp_event_manager': $plugin_file = 'wp-event-manager/wp-event-manager.php'; break; + default: + // By default we test other stuff using The Events Calendar. + $plugin_file = 'the-events-calendar/the-events-calendar.php'; } if ( $plugin_file ) { diff --git a/tests/test-class-plugin-events-manger.php b/tests/test-class-plugin-events-manger.php index 665b3c8..c27f9c5 100644 --- a/tests/test-class-plugin-events-manger.php +++ b/tests/test-class-plugin-events-manger.php @@ -16,7 +16,7 @@ class Test_Events_Manager extends WP_UnitTestCase { parent::set_up(); if ( ! class_exists( 'EM_Events' ) ) { - self::markTestSkipped( 'VS Event List plugin is not active.' ); + self::markTestSkipped( 'Events Manager plugin is not active.' ); } // For tests allow every user to create new events. diff --git a/tests/test-class-plugin-gatherpress.php b/tests/test-class-plugin-gatherpress.php index 1fffa4b..377e368 100644 --- a/tests/test-class-plugin-gatherpress.php +++ b/tests/test-class-plugin-gatherpress.php @@ -1,12 +1,12 @@ 'Minimal Venue', + 'status' => 'publish', + ); + + public const MOCKUP_EVENT = array( + 'title' => 'My Event', + 'content' => 'Come to my event!', + 'start_date' => '+10 days 15:00:00', + 'duration' => HOUR_IN_SECONDS, + 'status' => 'publish', + ); + + /** + * Override the setup function, so that tests don't run if the Events Calendar is not active. + */ + public function set_up() { + parent::set_up(); + + if ( ! class_exists( '\Tribe__Events__Main' ) ) { + self::markTestSkipped( 'The Events Calendar is not active.' ); + } + + // For tests allow every user to create new events. + update_option( 'dbem_events_anonymous_submissions', true ); + + // Make sure that ActivityPub support is enabled for Events Manager. + $aec = \ActivityPub_Event_Bridge\Setup::get_instance(); + $aec->activate_activitypub_support_for_active_event_plugins(); + + // Delete all posts afterwards. + _delete_all_posts(); + } + + public function test_event_reminder_not_being_scheduled_by_default() { + // Create a The Events Calendar Event. + $wp_object = tribe_events() + ->set_args( self::MOCKUP_EVENT ) + ->create(); + + $scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) ); + + $this->assertEquals( false, $scheduled_event ); + } + + public function test_event_reminder_scheduled_with_site_wide_option() { + \update_option( 'activitypub_event_bridge_reminder_time_gap', DAY_IN_SECONDS ); + // Create a The Events Calendar Event. + $wp_object = tribe_events() + ->set_args( self::MOCKUP_EVENT ) + ->create(); + + $scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) ); + + $this->assertNotEquals( false, $scheduled_event ); + $this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - DAY_IN_SECONDS, $scheduled_event->timestamp ); + $this->assertEquals( false, $scheduled_event->schedule ); + $this->assertEquals( 'activitypub_event_bridge_send_event_reminder', $scheduled_event->hook ); + } + + public function test_event_reminder_scheduled_with_per_event_override() { + \update_option( 'activitypub_event_bridge_reminder_time_gap', DAY_IN_SECONDS ); + + // Create a The Events Calendar Event. + $wp_object = tribe_events() + ->set_args( + array_merge( + self::MOCKUP_EVENT, + array( 'activitypub_event_bridge_reminder_time_gap' => DAY_IN_SECONDS * 3 ), + ) + ) + ->create(); + + $scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) ); + + $this->assertNotEquals( false, $scheduled_event ); + $this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - DAY_IN_SECONDS * 3, $scheduled_event->timestamp ); + $this->assertEquals( false, $scheduled_event->schedule ); + $this->assertEquals( 'activitypub_event_bridge_send_event_reminder', $scheduled_event->hook ); + + // Now update the option once more to see if the schedule got updated too. + $post_id = array_key_first( + tribe_events( $wp_object->ID ) + ->set_args( + array( 'activitypub_event_bridge_reminder_time_gap' => HOUR_IN_SECONDS ), + ) + ->save() + ); + + $scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $post_id ) ); + $this->assertNotEquals( false, $scheduled_event ); + $this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - HOUR_IN_SECONDS, $scheduled_event->timestamp ); + } + + public function test_event_reminder_deleted_event() { + \update_option( 'activitypub_event_bridge_reminder_time_gap', DAY_IN_SECONDS ); + + // Create a The Events Calendar Event. + $wp_object = tribe_events() + ->set_args( + array_merge( + self::MOCKUP_EVENT, + array( 'activitypub_event_bridge_reminder_time_gap' => DAY_IN_SECONDS * 3 ), + ) + ) + ->create(); + + $scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) ); + + $this->assertNotEquals( false, $scheduled_event ); + $this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - DAY_IN_SECONDS * 3, $scheduled_event->timestamp ); + $this->assertEquals( false, $scheduled_event->schedule ); + $this->assertEquals( 'activitypub_event_bridge_send_event_reminder', $scheduled_event->hook ); + + // Now delete the event. + tribe_events( $wp_object->ID )->delete(); + + $scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) ); + $this->assertEquals( false, $scheduled_event ); + } + + public function test_event_reminder_event_moved_to_trash() { + \update_option( 'activitypub_event_bridge_reminder_time_gap', DAY_IN_SECONDS ); + + // Create a The Events Calendar Event. + $wp_object = tribe_events() + ->set_args( + array_merge( + self::MOCKUP_EVENT, + array( 'activitypub_event_bridge_reminder_time_gap' => DAY_IN_SECONDS * 3 ), + ) + ) + ->create(); + + $scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) ); + + $this->assertNotEquals( false, $scheduled_event ); + $this->assertEquals( strtotime( self::MOCKUP_EVENT['start_date'] ) - DAY_IN_SECONDS * 3, $scheduled_event->timestamp ); + $this->assertEquals( false, $scheduled_event->schedule ); + $this->assertEquals( 'activitypub_event_bridge_send_event_reminder', $scheduled_event->hook ); + + // Now move the event to the trash. + $post_id = array_key_first( + tribe_events( $wp_object->ID ) + ->set_args( + array( 'post_status' => 'trash' ), + ) + ->save() + ); + + $scheduled_event = \wp_get_scheduled_event( 'activitypub_event_bridge_send_event_reminder', array( $wp_object->ID ) ); + $this->assertEquals( false, $scheduled_event ); + } +}