Testing a regular link. But we should throw in some markup and maybe even an . . It definitely does not like data URIs. @ The parser only extracts wp_allowed_protocols() protocols, not something like phone. [caption id='example']Here is a caption shortcode.[/caption] There are two types of [gallery] shortcodes; one like that, and another with IDs specified. Audio shortcodes: [audio src='http://example.com/source.mp3'] [audio src='http://example.com/source.wav' loop='on' autoplay='off' preload='metadata']. The following shortcode should be picked up by the shortcode extractor, but not the audio extractor, because it has an unrecognised file extension (for an audio file). [audio src='http://example.com/not_audio.gif'] This should be picked up, too. Video shortcodes: [video src='http://example.com/source.ogv'] [video src='http://example.com/source.webm' loop='on' autoplay='off' preload='metadata'] The following shortcode should be picked up by the shortcode extractor, but not the video extractor, because it has an unrecognised file extension (for a video file). [video src='http://example.com/not_video.mp3'] "; } /** * General. */ public function test_check_media_extraction_return_types() { $media = self::$media_extractor->extract( self::$richtext ); foreach ( array( 'has', 'embeds', 'images', 'links', 'mentions', 'shortcodes', 'audio' ) as $key ) { $this->assertArrayHasKey( $key, $media ); $this->assertInternalType( 'array', $media[ $key ] ); } foreach ( $media['has'] as $item ) { $this->assertInternalType( 'int', $item ); } foreach ( $media['links'] as $item ) { $this->assertArrayHasKey( 'url', $item ); $this->assertInternalType( 'string', $item['url'] ); $this->assertNotEmpty( $item['url'] ); } foreach ( $media['mentions'] as $item ) { $this->assertArrayHasKey( 'name', $item ); $this->assertInternalType( 'string', $item['name'] ); $this->assertNotEmpty( $item['name'] ); } foreach ( $media['images'] as $item ) { $this->assertArrayHasKey( 'height', $item ); $this->assertInternalType( 'int', $item['height'] ); $this->assertArrayHasKey( 'width', $item ); $this->assertInternalType( 'int', $item['width'] ); $this->assertArrayHasKey( 'source', $item ); $this->assertInternalType( 'string', $item['source'] ); $this->assertNotEmpty( $item['source'] ); $this->assertArrayHasKey( 'url', $item ); $this->assertInternalType( 'string', $item['url'] ); $this->assertNotEmpty( $item['url'] ); } foreach ( $media['shortcodes'] as $shortcode_type => $item ) { $this->assertArrayHasKey( 'attributes', $item ); $this->assertInternalType( 'array', $item['attributes'] ); $this->assertArrayHasKey( 'content', $item ); $this->assertInternalType( 'string', $item['content'] ); $this->assertArrayHasKey( 'type', $item ); $this->assertInternalType( 'string', $item['type'] ); $this->assertArrayHasKey( 'original', $item ); $this->assertInternalType( 'string', $item['original'] ); } foreach ( $media['embeds'] as $item ) { $this->assertArrayHasKey( 'url', $item ); $this->assertInternalType( 'string', $item['url'] ); $this->assertNotEmpty( $item['url'] ); } foreach ( $media['audio'] as $item ) { $this->assertArrayHasKey( 'url', $item ); $this->assertInternalType( 'string', $item['url'] ); $this->assertNotEmpty( $item['url'] ); $this->assertArrayHasKey( 'source', $item ); $this->assertInternalType( 'string', $item['source'] ); $this->assertNotEmpty( $item['source'] ); } } public function test_check_media_extraction_counts_are_correct() { $media = self::$media_extractor->extract( self::$richtext ); $types = array_keys( $media ); foreach ( $types as $type ) { if ( $type === 'has' ) { continue; } $this->assertArrayHasKey( $type, $media['has'] ); $this->assertSame( count( $media[ $type ] ), $media['has'][ $type ], "Difference with the 'has' count for {$type}." ); } } public function test_extract_multiple_media_types_from_content() { self::factory()->user->create( array( 'user_login' => 'paulgibbs' ) ); $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::LINKS | BP_Media_Extractor::MENTIONS ); $this->assertNotEmpty( $media['links'] ); $this->assertNotEmpty( $media['mentions'] ); $this->assertArrayNotHasKey( 'shortcodes', $media ); } public function test_extract_media_from_a_wp_post() { $post_id = self::factory()->post->create( array( 'post_content' => self::$richtext ) ); $media = self::$media_extractor->extract( get_post( $post_id ), BP_Media_Extractor::LINKS ); $this->assertArrayHasKey( 'links', $media ); $this->assertSame( 'https://example.com', $media['links'][0]['url'] ); $this->assertSame( 'http://example.com', $media['links'][1]['url'] ); } /** * Link extraction. */ public function test_extract_links_from_content() { $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::LINKS ); $this->assertArrayHasKey( 'links', $media ); $this->assertSame( 'https://example.com', $media['links'][0]['url'] ); $this->assertSame( 'http://example.com', $media['links'][1]['url'] ); } public function test_extract_no_links_from_content_with_invalid_links() { $richtext = "This is some sample text, with links, but not the kinds we want. Empty links should be ignore and weird protocols should be ignored, too. "; $media = self::$media_extractor->extract( $richtext, BP_Media_Extractor::LINKS ); $this->assertSame( 0, $media['has']['links'] ); } /** * at-mentions extraction. */ public function test_extract_mentions_from_content_with_activity_enabled() { self::factory()->user->create( array( 'user_login' => 'paulgibbs' ) ); $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::MENTIONS ); $this->assertArrayHasKey( 'user_id', $media['mentions'][0] ); $this->assertSame( 'paulgibbs', $media['mentions'][0]['name'] ); } public function test_extract_mentions_from_content_with_activity_disabled() { self::factory()->user->create( array( 'user_login' => 'paulgibbs' ) ); $was_activity_enabled = false; // Turn activity off. if ( isset( buddypress()->active_components['activity'] ) ) { unset( buddypress()->active_components['activity'] ); $was_activity_enabled = true; } $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::MENTIONS ); $this->assertArrayNotHasKey( 'user_id', $media['mentions'][0] ); $this->assertSame( 'paulgibbs', $media['mentions'][0]['name'] ); // Turn activity on. if ( $was_activity_enabled ) { buddypress()->active_components['activity'] = 1; } } /** * Shortcodes extraction. */ public function test_extract_shortcodes_from_content() { $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::SHORTCODES ); $this->assertArrayHasKey( 'shortcodes', $media ); $this->assertSame( 'caption', $media['shortcodes'][0]['type'] ); $this->assertSame( 'Here is a caption shortcode.', $media['shortcodes'][0]['content'] ); $this->assertSame( 'example', $media['shortcodes'][0]['attributes']['id'] ); $this->assertSame( 'gallery', $media['shortcodes'][1]['type'] ); $this->assertEmpty( $media['shortcodes'][1]['content'] ); $this->assertSame( 'audio', $media['shortcodes'][2]['type'] ); $this->assertEmpty( $media['shortcodes'][2]['content'] ); $this->assertSame( 'http://example.com/source.mp3', $media['shortcodes'][2]['attributes']['src'] ); $this->assertSame( 'audio', $media['shortcodes'][3]['type'] ); $this->assertEmpty( $media['shortcodes'][3]['content'] ); $this->assertSame( 'http://example.com/source.wav', $media['shortcodes'][3]['attributes']['src'] ); $this->assertSame( 'on', $media['shortcodes'][3]['attributes']['loop'] ); $this->assertSame( 'off', $media['shortcodes'][3]['attributes']['autoplay'] ); $this->assertSame( 'metadata', $media['shortcodes'][3]['attributes']['preload'] ); } public function test_extract_no_shortcodes_from_content_with_unregistered_shortcodes() { $richtext = 'This sample text has some made-up [fake]shortcodes[/fake].'; $media = self::$media_extractor->extract( $richtext, BP_Media_Extractor::SHORTCODES ); $this->assertSame( 0, $media['has']['shortcodes'] ); } /** * oEmbeds extraction. */ public function test_extract_oembeds_from_content() { $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::EMBEDS ); $this->assertArrayHasKey( 'embeds', $media ); $this->assertSame( 'https://www.youtube.com/watch?v=2mjvfnUAfyo', $media['embeds'][0]['url'] ); $this->assertSame( 'http://www.youtube.com/watch?v=KaOC9danxNo', $media['embeds'][1]['url'] ); } /** * Images extraction (src tags). */ // both quote styles public function test_extract_images_from_content_with_src_tags() { $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::IMAGES ); $this->assertArrayHasKey( 'images', $media ); $media = array_values( wp_list_filter( $media['images'], array( 'source' => 'html' ) ) ); $this->assertSame( 'http://example.com/image.gif', $media[0]['url'] ); $this->assertSame( 'http://example.com/image-in-a-link.gif', $media[1]['url'] ); } // empty src attributes, data: URIs public function test_extract_no_images_from_content_with_invalid_src_tags() { $richtext = 'This sample text will contain images with invalid src tags, like this: or . '; $media = self::$media_extractor->extract( $richtext, BP_Media_Extractor::IMAGES ); $this->assertArrayHasKey( 'images', $media ); $this->assertSame( 0, $media['has']['images'] ); } /** * Images extraction (galleries). */ public function test_extract_images_from_content_with_galleries_variant_no_ids() { // To test the [gallery] shortcode, we need to create a post and an attachment. $post_id = self::factory()->post->create( array( 'post_content' => self::$richtext ) ); $attachment_id = self::factory()->attachment->create_object( 'image.jpg', $post_id, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment' ) ); wp_update_attachment_metadata( $attachment_id, array( 'width' => 100, 'height' => 100 ) ); // Extract the gallery images. $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::IMAGES, array( 'post' => get_post( $post_id ), ) ); $this->assertArrayHasKey( 'images', $media ); $media = array_values( wp_list_filter( $media['images'], array( 'source' => 'galleries' ) ) ); $this->assertCount( 1, $media ); $this->assertSame( WP_CONTENT_URL . '/uploads/image.jpg', $media[0]['url'] ); } public function test_extract_images_from_content_with_galleries_variant_ids() { $attachment_ids = array( 'large' => 0, 'canola' => 0, ); $attachment_ids['large'] = self::factory()->attachment->create_upload_object( BP_TESTS_DIR . 'assets/test-image-large.jpg' ); $attachment_ids['canola'] = self::factory()->attachment->create_upload_object( BP_TESTS_DIR . 'assets/canola.jpg' ); $attachments = join( ',', $attachment_ids ); $post_id = self::factory()->post->create( array( 'post_content' => "[gallery ids='{$attachments}']" ) ); // Extract the gallery images. $media = self::$media_extractor->extract( '', BP_Media_Extractor::IMAGES, array( 'post' => get_post( $post_id ), ) ); $this->assertArrayHasKey( 'images', $media ); $media = array_values( wp_list_filter( $media['images'], array( 'source' => 'galleries' ) ) ); $this->assertCount( 2, $media ); $expected_urls = array( 'large' => wp_get_attachment_url( $attachment_ids['large'] ), 'canola' => wp_get_attachment_url( $attachment_ids['canola'] ), ); $this->assertSame( $expected_urls['large'], $media[0]['url'] ); $this->assertSame( $expected_urls['canola'], $media[1]['url'] ); } public function test_extract_no_images_from_content_with_invalid_galleries_variant_no_ids() { $post_id = self::factory()->post->create( array( 'post_content' => self::$richtext ) ); $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::IMAGES, array( 'post' => get_post( $post_id ), ) ); $this->assertArrayHasKey( 'images', $media ); $media = array_values( wp_list_filter( $media['images'], array( 'source' => 'galleries' ) ) ); $this->assertCount( 0, $media ); } public function test_extract_no_images_from_content_with_invalid_galleries_variant_ids() { $post_id = self::factory()->post->create( array( 'post_content' => '[gallery ids="117,4529"]' ) ); $media = self::$media_extractor->extract( '', BP_Media_Extractor::IMAGES, array( 'post' => get_post( $post_id ), ) ); $this->assertArrayHasKey( 'images', $media ); $media = array_values( wp_list_filter( $media['images'], array( 'source' => 'galleries' ) ) ); $this->assertCount( 0, $media ); } /** * Images extraction (thumbnail). */ public function test_extract_no_images_from_content_with_featured_image() { $post_id = self::factory()->post->create( array( 'post_content' => self::$richtext ) ); $thumbnail_id = self::factory()->attachment->create_object( 'image.jpg', $post_id, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment' ) ); set_post_thumbnail( $post_id, $thumbnail_id ); // Extract the gallery images. $media = self::$media_extractor->extract( '', BP_Media_Extractor::IMAGES, array( 'post' => get_post( $post_id ), ) ); $this->assertArrayHasKey( 'images', $media ); $media = array_values( wp_list_filter( $media['images'], array( 'source' => 'featured_images' ) ) ); $this->assertCount( 1, $media ); $this->assertSame( WP_CONTENT_URL . '/uploads/image.jpg', $media[0]['url'] ); } public function test_extract_images_from_content_without_featured_image() { $post_id = self::factory()->post->create( array( 'post_content' => self::$richtext ) ); $media = self::$media_extractor->extract( '', BP_Media_Extractor::IMAGES, array( 'post' => get_post( $post_id ), ) ); $this->assertArrayHasKey( 'images', $media ); $media = array_values( wp_list_filter( $media['images'], array( 'source' => 'featured_images' ) ) ); $this->assertCount( 0, $media ); } /** * Audio extraction. */ public function test_extract_audio_from_content() { $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::AUDIO ); $this->assertArrayHasKey( 'audio', $media ); $this->assertCount( 3, $media['audio'] ); $this->assertSame( 'shortcodes', $media['audio'][0]['source'] ); $this->assertSame( 'shortcodes', $media['audio'][1]['source'] ); $this->assertSame( 'html', $media['audio'][2]['source'] ); $this->assertSame( 'http://example.com/source.mp3', $media['audio'][0]['url'] ); $this->assertSame( 'http://example.com/source.wav', $media['audio'][1]['url'] ); $this->assertSame( 'http://example.com/more_audio.mp3', $media['audio'][2]['url'] ); } public function test_extract_audio_shortcode_with_no_src_param() { $richtext = '[audio http://example.com/a-song.mp3]'; $media = self::$media_extractor->extract( $richtext, BP_Media_Extractor::AUDIO ); $this->assertArrayHasKey( 'audio', $media ); $this->assertCount( 1, $media['audio'] ); $this->assertSame( 'http://example.com/a-song.mp3', $media['audio'][0]['url'] ); } public function test_extract_no_audio_from_invalid_content() { $richtext = '[audio src="http://example.com/not_audio.gif"] Hello.'; $media = self::$media_extractor->extract( $richtext, BP_Media_Extractor::AUDIO ); $this->assertSame( 0, $media['has']['audio'] ); } public function test_extract_no_audio_from_empty_audio_shortcode() { $media = self::$media_extractor->extract( '[audio]', BP_Media_Extractor::AUDIO ); $this->assertSame( 0, $media['has']['audio'] ); } /** * Video extraction. */ public function test_extract_video_from_content() { $media = self::$media_extractor->extract( self::$richtext, BP_Media_Extractor::VIDEOS ); $this->assertArrayHasKey( 'videos', $media ); $this->assertCount( 2, $media['videos'] ); $this->assertSame( 'shortcodes', $media['videos'][0]['source'] ); $this->assertSame( 'shortcodes', $media['videos'][1]['source'] ); $this->assertSame( 'http://example.com/source.ogv', $media['videos'][0]['url'] ); $this->assertSame( 'http://example.com/source.webm', $media['videos'][1]['url'] ); } public function test_extract_video_shortcode_with_no_src_param() { $richtext = '[video http://example.com/source.ogv]'; $media = self::$media_extractor->extract( $richtext, BP_Media_Extractor::VIDEOS ); $this->assertArrayHasKey( 'videos', $media ); $this->assertCount( 1, $media['videos'] ); $this->assertSame( 'http://example.com/source.ogv', $media['videos'][0]['url'] ); } public function test_extract_no_video_from_invalid_content() { $richtext = '[video src="http://example.com/not_video.mp3"]'; $media = self::$media_extractor->extract( $richtext, BP_Media_Extractor::VIDEOS ); $this->assertSame( 0, $media['has']['videos'] ); } public function test_extract_no_videos_from_empty_video_shortcodes() { $media = self::$media_extractor->extract( '[video]', BP_Media_Extractor::VIDEOS ); $this->assertSame( 0, $media['has']['videos'] ); } }