diff --git a/composer.json b/composer.json index ee97807..d091876 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,7 @@ ], "test-debug": [ "@prepare-test", - "@test-events-manager" + "@test-vs-event-list" ], "test-vs-event-list": "phpunit --filter=vs_event_list", "test-the-events-calendar": "phpunit --filter=the_events_calendar", diff --git a/includes/activitypub/transformer/class-event.php b/includes/activitypub/transformer/class-event.php index f796e14..4dc96e1 100644 --- a/includes/activitypub/transformer/class-event.php +++ b/includes/activitypub/transformer/class-event.php @@ -35,7 +35,7 @@ class Event extends Post { * * @return string The User-URL. */ - protected function get_actor() { + protected function get_actor(): ?string { return $this->get_attributed_to(); } @@ -46,14 +46,14 @@ class Event extends Post { * * @return string The Event Object-Type. */ - protected function get_type() { + protected function get_type(): string { return 'Event'; } /** * Get a sane default for whether comments are enabled. */ - protected function get_comments_enabled() { + protected function get_comments_enabled(): ?bool { return comments_open( $this->wp_object ); } @@ -64,7 +64,7 @@ class Event extends Post { * * @return string The name. */ - protected function get_name() { + protected function get_name(): string { return $this->wp_object->post_title; } @@ -86,7 +86,7 @@ class Event extends Post { * * @return string */ - public function get_join_mode() { + public function get_join_mode(): ?string { return 'external'; } @@ -96,16 +96,16 @@ class Event extends Post { * Currently we don't handle joins, we always mark events as external. * We just link back to the events HTML representation on our WordPress site. * - * @return string|null The external participation URL. + * @return ?string The external participation URL. */ - public function get_external_participation_url(): string|null { + public function get_external_participation_url(): ?string { return 'external' === $this->get_join_mode() ? $this->get_url() : null; } /** * Set the event category, via the mapping setting. */ - public function get_category() { + public function get_category(): ?string { $current_category_mapping = \get_option( 'activitypub_event_extensions_event_category_mappings', array() ); $terms = \get_the_terms( $this->wp_object, $this->wp_taxonomy ); @@ -123,7 +123,7 @@ class Event extends Post { * * @return Event_Object */ - public function to_object() { + public function to_object(): Event_Object { $activitypub_object = new Event_Object(); $activitypub_object = $this->transform_object_properties( $activitypub_object ); diff --git a/includes/activitypub/transformer/class-vs-event-list.php b/includes/activitypub/transformer/class-vs-event-list.php index 2f0cd56..f6f9b61 100644 --- a/includes/activitypub/transformer/class-vs-event-list.php +++ b/includes/activitypub/transformer/class-vs-event-list.php @@ -27,7 +27,6 @@ if ( ! defined( 'ABSPATH' ) ) { * @since 1.0.0 */ final class VS_Event_List extends Event_Transformer { - /** * The target transformer ActivityPub Event object. * @@ -35,19 +34,6 @@ final class VS_Event_List extends Event_Transformer { */ protected $ap_object; - /** - * Get transformer name. - * - * Retrieve the transformers name. - * - * @since 1.0.0 - * @access public - * @return string Widget name. - */ - public function get_transformer_name(): string { - return 'activitypub-event-transformers/vs-event'; - } - /** * Returns the ActivityStreams 2.0 Object-Type for an Event. * @@ -64,21 +50,28 @@ final class VS_Event_List extends Event_Transformer { * * @return Place The Place. */ - public function get_location(): Place { + public function get_location(): ?Place { $address = get_post_meta( $this->wp_object->ID, 'event-location', true ); - $place = new Place(); - $place->set_type( 'Place' ); - $place->set_name( $address ); - $place->set_address( $address ); - return $place; + if ( $address ) { + $place = new Place(); + $place->set_type( 'Place' ); + $place->set_name( $address ); + $place->set_address( $address ); + return $place; + } else { + return null; + } } /** * Get the end time from the events metadata. */ - protected function get_end_time(): string { + protected function get_end_time(): ?string { + if ( 'yes' === get_post_meta( $this->wp_object->ID, 'event-hide-end-time', true ) ) { + return null; + } $end_time = get_post_meta( $this->wp_object->ID, 'event-date', true ); - return \gmdate( 'Y-m-d\TH:i:s\Z', $end_time ); + return $end_time ? \gmdate( 'Y-m-d\TH:i:s\Z', $end_time ) : null; } /** @@ -86,28 +79,32 @@ final class VS_Event_List extends Event_Transformer { */ protected function get_start_time(): string { $start_time = get_post_meta( $this->wp_object->ID, 'event-start-date', true ); - return \gmdate( 'Y-m-d\TH:i:s\Z', $start_time ); + return $start_time ? \gmdate( 'Y-m-d\TH:i:s\Z', $start_time ) : null; } /** * Get the event link from the events metadata. + * + * @return ?array Associated array of an ActivityStreams Link object with the events URL. */ - private function get_event_link(): array { - $event_link = get_post_meta( $this->wp_object->ID, 'event-link', true ); + private function get_event_link(): ?array { + $event_link = get_post_meta( $this->wp_object->ID, 'event-link', true ); + $event_link_label = get_post_meta( $this->wp_object->ID, 'event-link-label', true ) ?? 'Event Link'; if ( $event_link ) { return array( 'type' => 'Link', - 'name' => 'Website', + 'name' => $event_link_label, 'href' => \esc_url( $event_link ), 'mediaType' => 'text/html', ); } + return null; } /** * Overrides/extends the get_attachments function to also add the event Link. */ - protected function get_attachment() { + protected function get_attachment(): ?array { $attachments = parent::get_attachment(); if ( count( $attachments ) ) { $attachments[0]['type'] = 'Document'; @@ -128,7 +125,7 @@ final class VS_Event_List extends Event_Transformer { * * @return string $summary The custom event summary. */ - public function get_summary() { + public function get_summary(): ?string { if ( $this->wp_object->excerpt ) { $excerpt = $this->wp_object->post_excerpt; } elseif ( get_post_meta( $this->wp_object->ID, 'event-summary', true ) ) { diff --git a/tests/test-class-plugin-vs-event-list copy.php b/tests/test-class-plugin-vs-event-list copy.php deleted file mode 100644 index df669f2..0000000 --- a/tests/test-class-plugin-vs-event-list copy.php +++ /dev/null @@ -1,63 +0,0 @@ -activate_activitypub_support_for_active_event_plugins(); - - // Delete all posts afterwards. - _delete_all_posts(); - } - - /** - * Test that the right transformer gets applied. - */ - public function test_transformer_class() { - // We only test for one event plugin being active at the same time, - // even though we support multiple onces in theory. - // But testing all combinations is beyond scope. - $active_event_plugins = \Activitypub_Event_Extensions\Setup::get_instance()->get_active_event_plugins(); - $this->assertEquals( 1, count( $active_event_plugins ) ); - - // Enable ActivityPub support for the event plugin. - $this->assertContains( 'event', get_option( 'activitypub_support_post_types' ) ); - - // Insert a new Event. - $wp_post_id = wp_insert_post( - array( - 'post_title' => 'VSEL Test Event', - 'post_status' => 'published', - 'post_type' => 'event', - 'meta_input' => array( - 'event-start-time' => strtotime( '+10 days 15:00:00' ), - ), - ) - ); - - $wp_object = get_post( $wp_post_id ); - - // Call the transformer Factory. - $transformer = \Activitypub\Transformer\Factory::get_transformer( $wp_object ); - - // Check that we got the right transformer. - $this->assertInstanceOf( \Activitypub_Event_Extensions\Activitypub\Transformer\VS_Event_List::class, $transformer ); - } -} diff --git a/tests/test-class-plugin-vs-event-list.php b/tests/test-class-plugin-vs-event-list.php new file mode 100644 index 0000000..7321887 --- /dev/null +++ b/tests/test-class-plugin-vs-event-list.php @@ -0,0 +1,166 @@ +activate_activitypub_support_for_active_event_plugins(); + + // Delete all posts afterwards. + _delete_all_posts(); + } + + /** + * Test that the right transformer gets applied. + */ + public function test_transformer_class() { + // We only test for one event plugin being active at the same time, + // even though we support multiple onces in theory. + // But testing all combinations is beyond scope. + $active_event_plugins = \Activitypub_Event_Extensions\Setup::get_instance()->get_active_event_plugins(); + $this->assertEquals( 1, count( $active_event_plugins ) ); + + // Enable ActivityPub support for the event plugin. + $this->assertContains( 'event', get_option( 'activitypub_support_post_types' ) ); + + // Insert a new Event. + $wp_post_id = wp_insert_post( + array( + 'post_title' => 'VSEL Test Event', + 'post_status' => 'published', + 'post_type' => 'event', + 'meta_input' => array( + 'event-start-date' => strtotime( '+10 days 15:00:00' ), + ), + ) + ); + + $wp_object = get_post( $wp_post_id ); + + // Call the transformer Factory. + $transformer = \Activitypub\Transformer\Factory::get_transformer( $wp_object ); + + // Check that we got the right transformer. + $this->assertInstanceOf( \Activitypub_Event_Extensions\Activitypub\Transformer\VS_Event_List::class, $transformer ); + } + + /** + * Test the transformation to ActivityStreams of minimal event. + */ + public function test_transform_of_minimal_event() { + // Insert a new Event. + $wp_post_id = wp_insert_post( + array( + 'post_title' => 'VSEL Test Event', + 'post_status' => 'published', + 'post_type' => 'event', + 'meta_input' => array( + 'event-start-date' => strtotime( '+10 days 15:00:00' ), + ), + ) + ); + + // Transform the event to ActivityStreams. + $event_array = \Activitypub\Transformer\Factory::get_transformer( get_post( $wp_post_id ) )->to_object()->to_array(); + + // Check that the event ActivityStreams representation contains everything as expected. + $this->assertEquals( 'Event', $event_array['type'] ); + $this->assertEquals( 'VSEL Test Event', $event_array['name'] ); + $this->assertEquals( '', $event_array['content'] ); + $this->assertEquals( gmdate( 'Y-m-d', strtotime( '+10 days 15:00:00' ) ) . 'T15:00:00Z', $event_array['startTime'] ); + $this->assertArrayNotHasKey( 'endTime', $event_array ); + $this->assertEquals( comments_open( $wp_post_id ), $event_array['commentsEnabled'] ); + $this->assertEquals( comments_open( $wp_post_id ) ? 'allow_all' : 'closed', $event_array['repliesModerationOption'] ); + $this->assertEquals( 'external', $event_array['joinMode'] ); + $this->assertEquals( esc_url( get_permalink( $wp_post_id ) ), $event_array['externalParticipationUrl'] ); + $this->assertArrayNotHasKey( 'location', $event_array ); + $this->assertEquals( 'MEETING', $event_array['category'] ); + } + + /** + * Test the transformation to ActivityStreams of minimal event. + */ + public function test_transform_of_full_event() { + // Insert a new Event. + $wp_post_id = wp_insert_post( + array( + 'post_title' => 'VSEL Test Event', + 'post_status' => 'published', + 'post_type' => 'event', + 'meta_input' => array( + 'event-start-date' => strtotime( '+10 days 15:00:00' ), + 'event-date' => strtotime( '+10 days 16:00:00' ), + 'event-link' => 'https://event-federation.eu/vsel-test-event', + 'event-link-label' => 'Website', + ), + ) + ); + + // Transform the event to ActivityStreams. + $event_array = \Activitypub\Transformer\Factory::get_transformer( get_post( $wp_post_id ) )->to_object()->to_array(); + + // Check that the event ActivityStreams representation contains everything as expected. + $this->assertEquals( 'Event', $event_array['type'] ); + $this->assertEquals( 'VSEL Test Event', $event_array['name'] ); + $this->assertEquals( '', $event_array['content'] ); + $this->assertEquals( gmdate( 'Y-m-d', strtotime( '+10 days 15:00:00' ) ) . 'T15:00:00Z', $event_array['startTime'] ); + $this->assertEquals( gmdate( 'Y-m-d', strtotime( '+10 days 15:00:00' ) ) . 'T16:00:00Z', $event_array['endTime'] ); + $this->assertEquals( comments_open( $wp_post_id ), $event_array['commentsEnabled'] ); + $this->assertEquals( comments_open( $wp_post_id ) ? 'allow_all' : 'closed', $event_array['repliesModerationOption'] ); + $this->assertEquals( 'external', $event_array['joinMode'] ); + $this->assertEquals( esc_url( get_permalink( $wp_post_id ) ), $event_array['externalParticipationUrl'] ); + $this->assertArrayNotHasKey( 'location', $event_array ); + $this->assertEquals( 'MEETING', $event_array['category'] ); + $this->assertContains( + array( + 'type' => 'Link', + 'name' => 'Website', + 'href' => 'https://event-federation.eu/vsel-test-event', + 'mediaType' => 'text/html', + ), + $event_array['attachment'] + ); + } + + /** + * Test the transformation to ActivityStreams of event with hidden end time. + */ + public function test_transform_of_event_with_hidden_end_time() { + // Insert a new Event. + $wp_post_id = wp_insert_post( + array( + 'post_title' => 'VSEL Test Event', + 'post_status' => 'published', + 'post_type' => 'event', + 'meta_input' => array( + 'event-start-date' => strtotime( '+10 days 15:00:00' ), + 'event-date' => strtotime( '+10 days 16:00:00' ), + 'event-hide-end-time' => 'yes', + ), + ) + ); + + // Transform the event to ActivityStreams. + $event_array = \Activitypub\Transformer\Factory::get_transformer( get_post( $wp_post_id ) )->to_object()->to_array(); + + // Check that the event ActivityStreams representation contains everything as expected. + $this->assertArrayNotHasKey( 'endTime', $event_array ); + } +}