bolded caption with a link. CAP; const IMG_CONTENT = <<<'CAP' pic CAP; const IMG_NAME = 'image.jpg'; const IMG_URL = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . self::IMG_NAME; const IMG_META = array( 'width' => 100, 'height' => 100, 'sizes' => '', ); protected static $large_id; protected static $_sizes; protected static $large_filename = 'test-image-large.jpg'; protected static $post_ids; public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { self::$_sizes = wp_get_additional_image_sizes(); $GLOBALS['_wp_additional_image_sizes'] = array(); $filename = DIR_TESTDATA . '/images/' . self::$large_filename; self::$large_id = $factory->attachment->create_upload_object( $filename ); $post_statuses = array( 'publish', 'future', 'draft', 'auto-draft', 'trash' ); foreach ( $post_statuses as $post_status ) { $date = ''; if ( 'future' === $post_status ) { date_format( date_create( '+1 year' ), 'Y-m-d H:i:s' ); } self::$post_ids[ $post_status ] = $factory->post->create( array( 'post_status' => 'trash' === $post_status ? 'publish' : $post_status, 'post_date' => $date, 'post_name' => "$post_status-post", ) ); // Attachments without media. self::$post_ids[ "$post_status-attachment" ] = $factory->attachment->create_object( array( 'post_parent' => self::$post_ids[ $post_status ], 'post_status' => 'inherit', 'post_name' => "$post_status-attachment", 'post_date' => $date, ) ); } // Trash the trash post. wp_trash_post( self::$post_ids['trash'] ); } public static function wpTearDownAfterClass() { $GLOBALS['_wp_additional_image_sizes'] = self::$_sizes; } public static function tear_down_after_class() { wp_delete_attachment( self::$large_id, true ); parent::tear_down_after_class(); } public function test_img_caption_shortcode_added() { global $shortcode_tags; $this->assertSame( 'img_caption_shortcode', $shortcode_tags['caption'] ); $this->assertSame( 'img_caption_shortcode', $shortcode_tags['wp_caption'] ); } public function test_img_caption_shortcode_with_empty_params() { $result = img_caption_shortcode( array() ); $this->assertSame( '', $result ); } /** * @ticket 33981 */ public function test_img_caption_shortcode_with_empty_params_but_content() { $result = img_caption_shortcode( array(), self::CAPTION ); $this->assertSame( self::CAPTION, $result ); } /** * @ticket 33981 */ public function test_img_caption_shortcode_short_circuit_filter() { add_filter( 'img_caption_shortcode', array( $this, 'return_alt_caption' ) ); $result = img_caption_shortcode( array(), self::CAPTION ); $this->assertSame( self::ALTERNATE_CAPTION, $result ); } /** * Filter used in test_img_caption_shortcode_short_circuit_filter() */ public function return_alt_caption() { return self::ALTERNATE_CAPTION; } /** * @ticket 33981 */ public function test_img_caption_shortcode_empty_width() { $result = img_caption_shortcode( array( 'width' => 0, ), self::CAPTION ); $this->assertSame( self::CAPTION, $result ); } /** * @ticket 33981 */ public function test_img_caption_shortcode_empty_caption() { $result = img_caption_shortcode( array( 'caption' => '', ) ); $this->assertSame( '', $result ); } /** * @ticket 33981 */ public function test_img_caption_shortcode_empty_caption_and_content() { $result = img_caption_shortcode( array( 'caption' => '', ), self::CAPTION ); $this->assertSame( self::CAPTION, $result ); } public function test_img_caption_shortcode_with_old_format() { $result = img_caption_shortcode( array( 'width' => 20, 'caption' => self::CAPTION, ) ); $this->assertSame( 2, substr_count( $result, 'wp-caption' ) ); $this->assertSame( 1, substr_count( $result, 'alignnone' ) ); $this->assertSame( 1, substr_count( $result, self::CAPTION ) ); if ( current_theme_supports( 'html5', 'caption' ) ) { $this->assertSame( 1, substr_count( $result, 'width: 20' ) ); } else { $this->assertSame( 1, substr_count( $result, 'width: 30' ) ); } } public function test_img_caption_shortcode_with_old_format_id_and_align() { $result = img_caption_shortcode( array( 'width' => 20, 'caption' => self::CAPTION, 'id' => '"myId', 'align' => '&myAlignment', ) ); $this->assertSame( 1, substr_count( $result, 'wp-caption &myAlignment' ) ); $this->assertSame( 1, substr_count( $result, 'id="myId"' ) ); $this->assertSame( 1, substr_count( $result, self::CAPTION ) ); } public function test_img_caption_shortcode_with_old_format_and_class() { $result = img_caption_shortcode( array( 'width' => 20, 'class' => 'some-class another-class', 'caption' => self::CAPTION, ) ); $this->assertSame( 1, substr_count( $result, 'wp-caption alignnone some-class another-class' ) ); } public function test_new_img_caption_shortcode_with_html_caption() { $result = img_caption_shortcode( array( 'width' => 20, 'caption' => self::HTML_CONTENT, ) ); $this->assertSame( 1, substr_count( $result, self::HTML_CONTENT ) ); } public function test_new_img_caption_shortcode_new_format() { $result = img_caption_shortcode( array( 'width' => 20 ), self::IMG_CONTENT . self::HTML_CONTENT ); $img_preg = preg_quote( self::IMG_CONTENT ); $content_preg = preg_quote( self::HTML_CONTENT ); $this->assertSame( 1, preg_match_all( "~{$img_preg}.*wp-caption-text~", $result ) ); $this->assertSame( 1, preg_match_all( "~wp-caption-text.*{$content_preg}~", $result ) ); } public function test_new_img_caption_shortcode_new_format_and_linked_image() { $linked_image = "" . self::IMG_CONTENT . ''; $result = img_caption_shortcode( array( 'width' => 20 ), $linked_image . self::HTML_CONTENT ); $img_preg = preg_quote( $linked_image ); $content_preg = preg_quote( self::HTML_CONTENT ); $this->assertSame( 1, preg_match_all( "~{$img_preg}.*wp-caption-text~", $result ) ); $this->assertSame( 1, preg_match_all( "~wp-caption-text.*{$content_preg}~", $result ) ); } public function test_new_img_caption_shortcode_new_format_and_linked_image_with_newline() { $linked_image = "" . self::IMG_CONTENT . ''; $result = img_caption_shortcode( array( 'width' => 20 ), $linked_image . "\n\n" . self::HTML_CONTENT ); $img_preg = preg_quote( $linked_image ); $content_preg = preg_quote( self::HTML_CONTENT ); $this->assertSame( 1, preg_match_all( "~{$img_preg}.*wp-caption-text~", $result ) ); $this->assertSame( 1, preg_match_all( "~wp-caption-text.*{$content_preg}~", $result ) ); } /** * @ticket 34595 */ public function test_img_caption_shortcode_has_aria_describedby() { $result = img_caption_shortcode( array( 'width' => 20, 'id' => 'myId', ), self::IMG_CONTENT . self::HTML_CONTENT ); $this->assertSame( 1, substr_count( $result, 'aria-describedby="caption-myId"' ) ); } public function test_add_remove_oembed_provider() { wp_oembed_add_provider( 'http://foo.bar/*', 'http://foo.bar/oembed' ); $this->assertTrue( wp_oembed_remove_provider( 'http://foo.bar/*' ) ); $this->assertFalse( wp_oembed_remove_provider( 'http://foo.bar/*' ) ); } /** * @ticket 23776 */ public function test_autoembed_empty() { global $wp_embed; $content = ''; $result = $wp_embed->autoembed( $content ); $this->assertSame( $content, $result ); } /** * @ticket 23776 * * @group external-http */ public function test_autoembed_no_paragraphs_around_urls() { global $wp_embed; $content = <<http://some.link/ http://some.other.link/ EOF; $result = $wp_embed->autoembed( $content ); $this->assertSame( $content, $result ); } public function data_autoembed() { return array( // Should embed. array( 'https://w.org', '[embed]', ), array( 'test https://w.org test', 'test [embed] test', ), array( '

https://w.org

', '

[embed]

', ), array( '

https://w.org

', '

[embed]

', ), array( '

test https://w.org test

', '

test [embed] test

', ), array( '

https://w.org

', '

[embed]

', ), // Should NOT embed. array( 'test https://w.org

', ), array( 'https://w.org', ), array( '
https://w.org

', ), array( ' https://w.org', ), ); } /** * @dataProvider data_autoembed */ public function test_autoembed( $content, $result = null ) { $wp_embed = new Test_Autoembed(); $this->assertSame( $wp_embed->autoembed( $content ), $result ? $result : $content ); } public function test_wp_prepare_attachment_for_js() { // Attachment without media. $id = wp_insert_attachment( array( 'post_status' => 'publish', 'post_title' => 'Prepare', 'post_content_filtered' => 'Prepare', 'post_type' => 'post', ) ); $post = get_post( $id ); $prepped = wp_prepare_attachment_for_js( $post ); $this->assertIsArray( $prepped ); $this->assertSame( 0, $prepped['uploadedTo'] ); $this->assertSame( '', $prepped['mime'] ); $this->assertSame( '', $prepped['type'] ); $this->assertSame( '', $prepped['subtype'] ); // #21963, there will be a GUID always, so there will be a URL. $this->assertNotEquals( '', $prepped['url'] ); $this->assertSame( site_url( 'wp-includes/images/media/default.png' ), $prepped['icon'] ); // Fake a mime. $post->post_mime_type = 'image/jpeg'; $prepped = wp_prepare_attachment_for_js( $post ); $this->assertSame( 'image/jpeg', $prepped['mime'] ); $this->assertSame( 'image', $prepped['type'] ); $this->assertSame( 'jpeg', $prepped['subtype'] ); // Fake a mime without a slash. See #WP22532. $post->post_mime_type = 'image'; $prepped = wp_prepare_attachment_for_js( $post ); $this->assertSame( 'image', $prepped['mime'] ); $this->assertSame( 'image', $prepped['type'] ); $this->assertSame( '', $prepped['subtype'] ); // Test that if author is not found, we return "(no author)" as `display_name`. // The previously used test post contains no author, so we can reuse it. $this->assertSame( '(no author)', $prepped['authorName'] ); // Test that if author has HTML entities in display_name, they're decoded correctly. $html_entity_author = self::factory()->user->create( array( 'display_name' => 'You & Me', ) ); $post->post_author = $html_entity_author; $prepped = wp_prepare_attachment_for_js( $post ); $this->assertSame( 'You & Me', $prepped['authorName'] ); } /** * @ticket 38965 */ public function test_wp_prepare_attachment_for_js_without_image_sizes() { // Create the attachement post. $id = wp_insert_attachment( array( 'post_title' => 'Attachment Title', 'post_type' => 'attachment', 'post_parent' => 0, 'post_mime_type' => 'image/jpeg', 'guid' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test-image.jpg', ) ); // Add attachment metadata without sizes. wp_update_attachment_metadata( $id, array( 'width' => 50, 'height' => 50, 'file' => 'test-image.jpg', ) ); $prepped = wp_prepare_attachment_for_js( get_post( $id ) ); $this->assertArrayHasKey( 'sizes', $prepped ); } /** * @ticket 19067 * @expectedDeprecated wp_convert_bytes_to_hr */ public function test_wp_convert_bytes_to_hr() { $kb = 1024; $mb = $kb * 1024; $gb = $mb * 1024; $tb = $gb * 1024; // Test if boundaries are correct. $this->assertSame( '1TB', wp_convert_bytes_to_hr( $tb ) ); $this->assertSame( '1GB', wp_convert_bytes_to_hr( $gb ) ); $this->assertSame( '1MB', wp_convert_bytes_to_hr( $mb ) ); $this->assertSame( '1KB', wp_convert_bytes_to_hr( $kb ) ); $this->assertSame( '1 TB', size_format( $tb ) ); $this->assertSame( '1 GB', size_format( $gb ) ); $this->assertSame( '1 MB', size_format( $mb ) ); $this->assertSame( '1 KB', size_format( $kb ) ); // Now some values around. $hr = wp_convert_bytes_to_hr( $tb + $tb / 2 + $mb ); $this->assertEqualsWithDelta( 1.50000095367, (float) str_replace( ',', '.', $hr ), 0.0001, 'The values should be equal' ); $hr = wp_convert_bytes_to_hr( $tb - $mb - $kb ); $this->assertEqualsWithDelta( 1023.99902248, (float) str_replace( ',', '.', $hr ), 0.0001, 'The values should be equal' ); $hr = wp_convert_bytes_to_hr( $gb + $gb / 2 + $mb ); $this->assertEqualsWithDelta( 1.5009765625, (float) str_replace( ',', '.', $hr ), 0.0001, 'The values should be equal' ); $hr = wp_convert_bytes_to_hr( $gb - $mb - $kb ); $this->assertEqualsWithDelta( 1022.99902344, (float) str_replace( ',', '.', $hr ), 0.0001, 'The values should be equal' ); // Edge. $this->assertSame( '-1B', wp_convert_bytes_to_hr( -1 ) ); $this->assertSame( '0B', wp_convert_bytes_to_hr( 0 ) ); } /** * @ticket 22960 */ public function test_get_attached_images() { $post_id = self::factory()->post->create(); $attachment_id = self::factory()->attachment->create_object( self::IMG_NAME, $post_id, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment', ) ); $images = get_attached_media( 'image', $post_id ); $this->assertEqualSets( $images, array( $attachment_id => get_post( $attachment_id ) ) ); } /** * @ticket 22960 */ public function test_post_galleries_images() { $ids1 = array(); $ids1_srcs = array(); foreach ( range( 1, 6 ) as $i ) { $attachment_id = self::factory()->attachment->create_object( "image$i.jpg", 0, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment', ) ); $metadata = array_merge( array( 'file' => "image$i.jpg" ), self::IMG_META ); wp_update_attachment_metadata( $attachment_id, $metadata ); $ids1[] = $attachment_id; $ids1_srcs[] = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg"; } $ids2 = array(); $ids2_srcs = array(); foreach ( range( 4, 6 ) as $i ) { $attachment_id = self::factory()->attachment->create_object( "image$i.jpg", 0, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment', ) ); $metadata = array_merge( array( 'file' => "image$i.jpg" ), self::IMG_META ); wp_update_attachment_metadata( $attachment_id, $metadata ); $ids2[] = $attachment_id; $ids2_srcs[] = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg"; } $ids1_joined = join( ',', array_slice( $ids1, 0, 3 ) ); $ids2_joined = join( ',', array_slice( $ids2, 3, 3 ) ); $blob = <<post->create( array( 'post_content' => $blob ) ); $srcs = get_post_galleries_images( $post_id ); $this->assertSameSetsWithIndex( $srcs, array( array_slice( $ids1_srcs, 0, 3 ), array_slice( $ids2_srcs, 3, 3 ) ) ); } /** * @ticket 22960 */ public function test_post_gallery_images() { $ids1 = array(); $ids1_srcs = array(); foreach ( range( 1, 3 ) as $i ) { $attachment_id = self::factory()->attachment->create_object( "image$i.jpg", 0, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment', ) ); $metadata = array_merge( array( 'file' => "image$i.jpg" ), self::IMG_META ); wp_update_attachment_metadata( $attachment_id, $metadata ); $ids1[] = $attachment_id; $ids1_srcs[] = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg"; } $ids2 = array(); $ids2_srcs = array(); foreach ( range( 4, 6 ) as $i ) { $attachment_id = self::factory()->attachment->create_object( "image$i.jpg", 0, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment', ) ); $metadata = array_merge( array( 'file' => "image$i.jpg" ), self::IMG_META ); wp_update_attachment_metadata( $attachment_id, $metadata ); $ids2[] = $attachment_id; $ids2_srcs[] = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg"; } $ids1_joined = implode( ',', $ids1 ); $ids2_joined = implode( ',', $ids2 ); $blob = <<post->create( array( 'post_content' => $blob ) ); $srcs = get_post_gallery_images( $post_id ); $this->assertSame( $srcs, $ids1_srcs ); } /** * @ticket 43826 * @group blocks */ public function test_block_post_gallery_images() { // Similar to test_post_gallery_images but with blocks instead of shortcodes $ids = array(); $imgs = array(); $ids_srcs = array(); foreach ( range( 1, 6 ) as $i ) { $attachment_id = self::factory()->attachment->create_object( "image$i.jpg", 0 ); $metadata = array_merge( array( 'file' => "image$i.jpg" ), self::IMG_META ); wp_update_attachment_metadata( $attachment_id, $metadata ); $ids[] = $attachment_id; $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg"; $ids_srcs[] = $url; $imgs[] = '
'; } $imgs1_joined = join( "\n", array_slice( $imgs, 0, 3 ) ); $imgs2_joined = join( "\n", array_slice( $imgs, 3, 3 ) ); $blob = << $imgs1_joined $imgs2_joined BLOB; $post_id = self::factory()->post->create( array( 'post_content' => $blob ) ); $srcs = get_post_gallery_images( $post_id ); $this->assertSameSetsWithIndex( array_slice( $ids_srcs, 0, 3 ), $srcs ); } /** * @ticket 43826 * @group blocks */ public function test_block_post_gallery_images_json() { // Similar to test_block_post_gallery_images, with IDs in the json blob $ids = array(); $imgs = array(); $ids_srcs = array(); foreach ( range( 1, 6 ) as $i ) { $attachment_id = self::factory()->attachment->create_object( "image$i.jpg", 0 ); $metadata = array_merge( array( 'file' => "image$i.jpg" ), self::IMG_META ); wp_update_attachment_metadata( $attachment_id, $metadata ); $ids[] = $attachment_id; $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg"; $ids_srcs[] = $url; $imgs[] = '
'; } $ids1_joined = join( ',', array_slice( $ids, 0, 3 ) ); $ids2_joined = join( ',', array_slice( $ids, 3, 3 ) ); $blob = << BLOB; $post_id = self::factory()->post->create( array( 'post_content' => $blob ) ); $srcs = get_post_gallery_images( $post_id ); $this->assertSameSetsWithIndex( array_slice( $ids_srcs, 0, 3 ), $srcs ); } /** * @ticket 43826 * @group blocks */ public function test_mixed_post_gallery_images() { // Similar to test_post_gallery_images but with a shortcode and a block in the same post $ids = array(); $imgs = array(); $ids_srcs = array(); foreach ( range( 1, 6 ) as $i ) { $attachment_id = self::factory()->attachment->create_object( "image$i.jpg", 0, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment', ) ); $metadata = array_merge( array( 'file' => "image$i.jpg" ), self::IMG_META ); wp_update_attachment_metadata( $attachment_id, $metadata ); $ids[] = $attachment_id; $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg"; $ids_srcs[] = $url; $imgs[] = '
'; } $ids1_joined = join( "\n", array_slice( $ids, 0, 3 ) ); $ids2_joined = join( "\n", array_slice( $ids, 3, 3 ) ); $imgs2_joined = join( "\n", array_slice( $imgs, 3, 3 ) ); $blob = << $imgs2_joined BLOB; $post_id = self::factory()->post->create( array( 'post_content' => $blob ) ); $srcs = get_post_gallery_images( $post_id ); $this->assertSameSetsWithIndex( array_slice( $ids_srcs, 0, 3 ), $srcs ); } /** * @ticket 43826 * @group blocks */ public function test_block_inner_post_gallery_images() { // Make sure get_post_gallery_images() works with gallery blocks that are nested inside something else $ids = array(); $imgs = array(); $ids_srcs = array(); foreach ( range( 1, 3 ) as $i ) { $attachment_id = self::factory()->attachment->create_object( "image$i.jpg", 0, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment', ) ); $metadata = array_merge( array( 'file' => "image$i.jpg" ), self::IMG_META ); wp_update_attachment_metadata( $attachment_id, $metadata ); $ids[] = $attachment_id; $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg"; $ids_srcs[] = $url; $imgs[] = '
'; } $imgs_joined = join( "\n", $imgs ); $blob = << $imgs_joined BLOB; $post_id = self::factory()->post->create( array( 'post_content' => $blob ) ); $srcs = get_post_gallery_images( $post_id ); $this->assertSameSetsWithIndex( $ids_srcs, $srcs ); } /** * @ticket 43826 * @group blocks */ public function test_block_post_gallery_innerblock_images() { // Make sure get_post_gallery_images() works with new version of gallery block with nested image blocks. $ids = array(); $imgs = array(); $ids_srcs = array(); foreach ( range( 1, 3 ) as $i ) { $attachment_id = self::factory()->attachment->create_object( "image$i.jpg", 0, array( 'post_mime_type' => 'image/jpeg', 'post_type' => 'attachment', ) ); $metadata = array_merge( array( 'file' => "image$i.jpg" ), self::IMG_META ); wp_update_attachment_metadata( $attachment_id, $metadata ); $ids[] = $attachment_id; $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg"; $ids_srcs[] = $url; $imgs[] = '
'; } $imgs_joined = join( "\n", $imgs ); $blob = << BLOB; $post_id = self::factory()->post->create( array( 'post_content' => $blob ) ); $srcs = get_post_gallery_images( $post_id ); $this->assertSameSetsWithIndex( $ids_srcs, $srcs ); } public function test_get_media_embedded_in_content() { $object = << OBJ; $embed = << EMBED; $iframe = <<'; $content = "$img\n$img\n$iframe\n$iframe"; // Record how often one of the available img and iframe filters is run. // Both images and iframes support lazy-loading, so that's why this is used here. $img_filter = new MockAction(); add_filter( 'wp_img_tag_add_loading_attr', array( &$img_filter, 'filter' ) ); $iframe_filter = new MockAction(); add_filter( 'wp_iframe_tag_add_loading_attr', array( &$iframe_filter, 'filter' ) ); // Ensure the img and iframe filters only ran once because the content is a single duplicated img tag and a // single duplicate iframe tag. wp_filter_content_tags( $content ); $this->assertSame( 1, $img_filter->get_call_count() ); $this->assertSame( 1, $iframe_filter->get_call_count() ); } /** * @ticket 55510 * @covers ::wp_filter_content_tags */ public function test_wp_filter_content_tags_filter_with_identical_image_tags_custom_attributes() { $img = get_image_tag( self::$large_id, '', '', '', 'large' ); $img = str_replace( '$filtered_image"; } ); // Ensure there is no duplicate wrapping the image. $this->assertStringNotContainsString( '$filtered_image"; } ); // Ensure the output has both instances of the image wrapped with a single . $this->assertSame( "$img\n$img", wp_filter_content_tags( $content ) ); } /** * @ticket 33641 * @ticket 34528 */ public function test_wp_calculate_image_srcset_animated_gifs() { // Mock meta for an animated gif. $image_meta = array( 'width' => 1200, 'height' => 600, 'file' => 'animated.gif', 'sizes' => array( 'thumbnail' => array( 'file' => 'animated-150x150.gif', 'width' => 150, 'height' => 150, 'mime-type' => 'image/gif', ), 'medium' => array( 'file' => 'animated-300x150.gif', 'width' => 300, 'height' => 150, 'mime-type' => 'image/gif', ), 'large' => array( 'file' => 'animated-1024x512.gif', 'width' => 1024, 'height' => 512, 'mime-type' => 'image/gif', ), ), ); $full_src = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file']; $large_src = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['large']['file']; // Test with soft resized size array. $size_array = array( 900, 450 ); // Full size GIFs should not return a srcset. $this->assertFalse( wp_calculate_image_srcset( $size_array, $full_src, $image_meta ) ); // Intermediate sized GIFs should not include the full size in the srcset. $this->assertStringNotContainsString( $full_src, wp_calculate_image_srcset( $size_array, $large_src, $image_meta ) ); } /** * @ticket 35045 * @ticket 33641 * @requires function imagejpeg */ public function test_wp_filter_content_tags_schemes() { $image_meta = wp_get_attachment_metadata( self::$large_id ); $size_array = $this->get_image_size_array_from_meta( $image_meta, 'medium' ); $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta ) ); $sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( self::$large_id, $size_array, $image_meta ) ); // Build HTML for the editor. $img = get_image_tag( self::$large_id, '', '', '', 'medium' ); $img = wp_img_tag_add_loading_attr( $img, 'test' ); $img_https = str_replace( 'http://', 'https://', $img ); $img_relative = str_replace( 'http://', '//', $img ); // Manually add srcset and sizes to the markup from get_image_tag(). $respimg = preg_replace( '|]+) />|', '', $img ); $respimg_https = preg_replace( '|]+) />|', '', $img_https ); $respimg_relative = preg_replace( '|]+) />|', '', $img_relative ); $content = '

Image, http: protocol. Should have srcset and sizes.

%1$s

Image, https: protocol. Should have srcset and sizes.

%2$s

Image, protocol-relative. Should have srcset and sizes.

%3$s'; $unfiltered = sprintf( $content, $img, $img_https, $img_relative ); $expected = sprintf( $content, $respimg, $respimg_https, $respimg_relative ); $expected = wp_img_tag_add_decoding_attr( $expected, 'the_content' ); $actual = wp_filter_content_tags( $unfiltered ); $this->assertSame( $expected, $actual ); } /** * @ticket 34945 * @ticket 33641 */ public function test_wp_get_attachment_image_with_https_on() { // Mock meta for the image. $image_meta = array( 'width' => 1200, 'height' => 600, 'file' => 'test.jpg', 'sizes' => array( 'thumbnail' => array( 'file' => 'test-150x150.jpg', 'width' => 150, 'height' => 150, ), 'medium' => array( 'file' => 'test-300x150.jpg', 'width' => 300, 'height' => 150, ), 'large' => array( 'file' => 'test-1024x512.jpg', 'width' => 1024, 'height' => 512, ), ), ); // Test using the large file size. $size_array = array( 1024, 512 ); $image_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['large']['file']; $_SERVER['HTTPS'] = 'on'; $uploads_url = 'https://' . WP_TESTS_DOMAIN . '/wp-content/uploads/'; $expected = $uploads_url . 'test-1024x512.jpg 1024w, ' . $uploads_url . 'test-300x150.jpg 300w, ' . $uploads_url . 'test.jpg 1200w'; $actual = wp_calculate_image_srcset( $size_array, $image_url, $image_meta ); $this->assertSame( $expected, $actual ); } /** * @ticket 36084 */ public function test_get_image_send_to_editor_defaults() { $id = self::$large_id; $caption = ''; $title = 'A test title value.'; $align = 'left'; // Calculate attachment data (default is medium). $attachment = wp_get_attachment_image_src( $id, 'medium' ); $html = ''; $expected = sprintf( $html, $attachment[0], $attachment[1], $attachment[2], $align, $id ); $this->assertSame( $expected, get_image_send_to_editor( $id, $caption, $title, $align ) ); $this->assertSame( $expected, get_image_send_to_editor( $id, $caption, $title, $align ) ); } /** * @ticket 36084 */ public function test_get_image_send_to_editor_defaults_with_optional_params() { $id = self::$large_id; $caption = 'A test caption.'; $title = 'A test title value.'; $align = 'left'; $url = get_permalink( $id ); $rel = true; $size = 'thumbnail'; $alt = 'An example alt value.'; // Calculate attachment data. $attachment = wp_get_attachment_image_src( $id, $size ); $html = '%4$s'; $html = '[caption id="attachment_%9$d" align="align%7$s" width="%5$d"]' . $html . ' %10$s[/caption]'; $expected = sprintf( $html, $url, 'attachment wp-att-' . $id, $attachment[0], $alt, $attachment[1], $attachment[2], $align, $size, $id, $caption ); $this->assertSame( $expected, get_image_send_to_editor( $id, $caption, $title, $align, $url, $rel, $size, $alt ) ); } /** * @ticket 36084 */ public function test_get_image_send_to_editor_defaults_no_caption_no_rel() { $id = self::$large_id; $caption = ''; $title = 'A test title value.'; $align = 'left'; $url = get_permalink( $id ); $rel = ''; $size = 'thumbnail'; $alt = 'An example alt value.'; // Calculate attachment data. $attachment = wp_get_attachment_image_src( $id, $size ); $html = '%3$s'; $expected = sprintf( $html, $url, $attachment[0], $alt, $attachment[1], $attachment[2], $align, $size, $id ); $this->assertSame( $expected, get_image_send_to_editor( $id, $caption, $title, $align, $url, $rel, $size, $alt ) ); } /** * Tests if wp_get_attachment_image() uses wp_get_attachment_metadata(). * * In this way, the meta data can be filtered using the filter * `wp_get_attachment_metadata`. * * The test checks if the image size that is added in the filter is * used in the output of `wp_get_attachment_image()`. * * @ticket 36246 * @requires function imagejpeg */ public function test_wp_get_attachment_image_should_use_wp_get_attachment_metadata() { add_filter( 'wp_get_attachment_metadata', array( $this, 'filter_36246' ), 10, 2 ); remove_all_filters( 'wp_calculate_image_sizes' ); $basename = wp_basename( self::$large_filename, '.jpg' ); $year_month = gmdate( 'Y/m' ); $uploads_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/'; $expected = ''; $actual = wp_get_attachment_image( self::$large_id, 'testsize' ); remove_filter( 'wp_get_attachment_metadata', array( $this, 'filter_36246' ) ); $this->assertSame( $expected, $actual ); } public function filter_36246( $data, $attachment_id ) { $data['sizes']['testsize'] = array( 'file' => 'test-image-testsize-999x999.jpg', 'width' => 999, 'height' => 999, 'mime-type' => 'image/jpg', ); return $data; } /** * @ticket 50679 */ public function test_wp_get_attachment_metadata_should_return_false_if_no_attachment() { $post_id = self::factory()->post->create(); $data = wp_get_attachment_metadata( $post_id ); $this->assertFalse( $data ); } /** * @ticket 37813 */ public function test_return_type_when_inserting_attachment_with_error_in_data() { $data = array( 'post_status' => 'publish', 'post_content' => 'Attachment content', 'post_title' => 'Attachment Title', 'post_date' => '2012-02-30 00:00:00', ); $attachment_id = wp_insert_attachment( $data, '', 0, true ); $this->assertWPError( $attachment_id ); $this->assertSame( 'invalid_date', $attachment_id->get_error_code() ); $attachment_id = wp_insert_attachment( $data, '', 0 ); $this->assertSame( 0, $attachment_id ); } /** * @ticket 35218 */ public function test_wp_get_media_creation_timestamp_video_asf() { $metadata = array( 'fileformat' => 'asf', 'asf' => array( 'file_properties_object' => array( 'creation_date_unix' => 123, ), ), ); $this->assertSame( 123, wp_get_media_creation_timestamp( $metadata ) ); } /** * @ticket 35218 */ public function test_wp_get_media_creation_timestamp_video_matroska() { $metadata = array( 'fileformat' => 'matroska', 'matroska' => array( 'comments' => array( 'creation_time' => array( '2015-12-24T17:40:09Z', ), ), ), ); $this->assertSame( 1450978809, wp_get_media_creation_timestamp( $metadata ) ); } /** * @ticket 35218 */ public function test_wp_get_media_creation_timestamp_video_quicktime() { $metadata = array( 'fileformat' => 'quicktime', 'quicktime' => array( 'moov' => array( 'subatoms' => array( array( 'creation_time_unix' => 1450978805, ), ), ), ), ); $this->assertSame( 1450978805, wp_get_media_creation_timestamp( $metadata ) ); } /** * @ticket 35218 */ public function test_wp_get_media_creation_timestamp_video_webm() { $metadata = array( 'fileformat' => 'webm', 'matroska' => array( 'info' => array( array( 'DateUTC_unix' => 1265680539, ), ), ), ); $this->assertSame( 1265680539, wp_get_media_creation_timestamp( $metadata ) ); } /** * Test created timestamp is properly read from an MP4 file. * * This MP4 video file has an AAC audio track, so it can be used to test *`wp_read_audio_metadata()`. * * @ticket 42017 */ public function test_wp_read_audio_metadata_adds_creation_date_with_mp4() { $video = DIR_TESTDATA . '/uploads/small-video.mp4'; $metadata = wp_read_audio_metadata( $video ); $this->assertSame( 1269120551, $metadata['created_timestamp'] ); } /** * @ticket 35218 */ public function test_wp_read_video_metadata_adds_creation_date_with_quicktime() { $video = DIR_TESTDATA . '/uploads/small-video.mov'; $metadata = wp_read_video_metadata( $video ); $this->assertSame( 1269120551, $metadata['created_timestamp'] ); } /** * @ticket 35218 */ public function test_wp_read_video_metadata_adds_creation_date_with_mp4() { $video = DIR_TESTDATA . '/uploads/small-video.mp4'; $metadata = wp_read_video_metadata( $video ); $this->assertSame( 1269120551, $metadata['created_timestamp'] ); } /** * @ticket 35218 */ public function test_wp_read_video_metadata_adds_creation_date_with_mkv() { $video = DIR_TESTDATA . '/uploads/small-video.mkv'; $metadata = wp_read_video_metadata( $video ); $this->assertSame( 1269120551, $metadata['created_timestamp'] ); } /** * @ticket 35218 */ public function test_wp_read_video_metadata_adds_creation_date_with_webm() { $video = DIR_TESTDATA . '/uploads/small-video.webm'; $metadata = wp_read_video_metadata( $video ); $this->assertSame( 1269120551, $metadata['created_timestamp'] ); } /** * @ticket 10752 */ public function test_media_handle_upload_uses_post_parent_for_directory_date() { $iptc_file = DIR_TESTDATA . '/images/test-image-iptc.jpg'; // Make a copy of this file as it gets moved during the file upload. $tmp_name = wp_tempnam( $iptc_file ); copy( $iptc_file, $tmp_name ); $_FILES['upload'] = array( 'tmp_name' => $tmp_name, 'name' => 'test-image-iptc.jpg', 'type' => 'image/jpeg', 'error' => 0, 'size' => filesize( $iptc_file ), ); $parent_id = self::factory()->post->create( array( 'post_date' => '2010-01-01' ) ); $post_id = media_handle_upload( 'upload', $parent_id, array(), array( 'action' => 'test_iptc_upload', 'test_form' => false, ) ); unset( $_FILES['upload'] ); $url = wp_get_attachment_url( $post_id ); $uploads_dir = wp_upload_dir( '2010/01' ); $expected = $uploads_dir['url'] . '/test-image-iptc.jpg'; // Clean up. wp_delete_attachment( $post_id, true ); wp_delete_post( $parent_id, true ); $this->assertSame( $expected, $url ); } /** * @ticket 10752 */ public function test_media_handle_upload_ignores_page_parent_for_directory_date() { $iptc_file = DIR_TESTDATA . '/images/test-image-iptc.jpg'; // Make a copy of this file as it gets moved during the file upload. $tmp_name = wp_tempnam( $iptc_file ); copy( $iptc_file, $tmp_name ); $_FILES['upload'] = array( 'tmp_name' => $tmp_name, 'name' => 'test-image-iptc.jpg', 'type' => 'image/jpeg', 'error' => 0, 'size' => filesize( $iptc_file ), ); $parent_id = self::factory()->post->create( array( 'post_date' => '2010-01-01', 'post_type' => 'page', ) ); $parent = get_post( $parent_id ); $post_id = media_handle_upload( 'upload', $parent_id, array(), array( 'action' => 'test_iptc_upload', 'test_form' => false, ) ); unset( $_FILES['upload'] ); $url = wp_get_attachment_url( $post_id ); $uploads_dir = wp_upload_dir( current_time( 'mysql' ) ); $expected = $uploads_dir['url'] . '/test-image-iptc.jpg'; // Clean up. wp_delete_attachment( $post_id, true ); wp_delete_post( $parent_id, true ); $this->assertSame( $expected, $url ); } /** * @ticket 50367 * @requires function imagejpeg */ public function test_wp_filter_content_tags_width_height() { $image_meta = wp_get_attachment_metadata( self::$large_id ); $size_array = $this->get_image_size_array_from_meta( $image_meta, 'medium' ); $img = get_image_tag( self::$large_id, '', '', '', 'medium' ); $img_no_width_height = str_replace( ' width="' . $size_array[0] . '"', '', $img ); $img_no_width_height = str_replace( ' height="' . $size_array[1] . '"', '', $img_no_width_height ); $img_no_width = str_replace( ' width="' . $size_array[0] . '"', '', $img ); $img_no_height = str_replace( ' height="' . $size_array[1] . '"', '', $img ); $hwstring = image_hwstring( $size_array[0], $size_array[1] ); // Manually add width and height to the markup from get_image_tag(). $respimg_no_width_height = str_replace( 'assertSame( $content_filtered, wp_filter_content_tags( $content_unfiltered ) ); remove_filter( 'wp_img_tag_add_loading_attr', '__return_false' ); remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); } /** * @ticket 44427 * @ticket 50367 * @ticket 50756 * @requires function imagejpeg */ public function test_wp_filter_content_tags_loading_lazy() { $image_meta = wp_get_attachment_metadata( self::$large_id ); $size_array = $this->get_image_size_array_from_meta( $image_meta, 'medium' ); $img = get_image_tag( self::$large_id, '', '', '', 'medium' ); $img_xhtml = str_replace( ' />', '/>', $img ); $img_html5 = str_replace( ' />', '>', $img ); $img_no_width_height = str_replace( ' width="' . $size_array[0] . '"', '', $img ); $img_no_width_height = str_replace( ' height="' . $size_array[1] . '"', '', $img_no_width_height ); $iframe = ''; $iframe_no_width_height = ''; $lazy_img = wp_img_tag_add_loading_attr( $img, 'test' ); $lazy_img_xhtml = wp_img_tag_add_loading_attr( $img_xhtml, 'test' ); $lazy_img_html5 = wp_img_tag_add_loading_attr( $img_html5, 'test' ); $lazy_iframe = wp_iframe_tag_add_loading_attr( $iframe, 'test' ); // The following should not be modified because there already is a 'loading' attribute. $img_eager = str_replace( ' />', ' loading="eager" />', $img ); $iframe_eager = str_replace( '">', '" loading="eager">', $iframe ); $content = '

Image, standard.

%1$s

Image, XHTML 1.0 style (no space before the closing slash).

%2$s

Image, HTML 5.0 style.

%3$s

Image, with pre-existing "loading" attribute. Should not be modified.

%4$s

Image, without dimension attributes. Should not be modified.

%5$s

Iframe, standard.

%6$s

Iframe, with pre-existing "loading" attribute. Should not be modified.

%7$s

Iframe, without dimension attributes. Should not be modified.

%8$s'; $content_unfiltered = sprintf( $content, $img, $img_xhtml, $img_html5, $img_eager, $img_no_width_height, $iframe, $iframe_eager, $iframe_no_width_height ); $content_filtered = sprintf( $content, $lazy_img, $lazy_img_xhtml, $lazy_img_html5, $img_eager, $img_no_width_height, $lazy_iframe, $iframe_eager, $iframe_no_width_height ); $content_filtered = wp_img_tag_add_decoding_attr( $content_filtered, 'the_content' ); // Do not add width, height, srcset, and sizes. add_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' ); add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); $this->assertSame( $content_filtered, wp_filter_content_tags( $content_unfiltered ) ); remove_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' ); remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); } /** * @ticket 44427 * @ticket 50756 */ public function test_wp_filter_content_tags_loading_lazy_opted_in() { $img = get_image_tag( self::$large_id, '', '', '', 'medium' ); $lazy_img = wp_img_tag_add_loading_attr( $img, 'test' ); $lazy_img = wp_img_tag_add_decoding_attr( $lazy_img, 'the_content' ); $iframe = ''; $lazy_iframe = wp_iframe_tag_add_loading_attr( $iframe, 'test' ); $content = '

Image, standard.

%1$s

Iframe, standard.

%2$s'; $content_unfiltered = sprintf( $content, $img, $iframe ); $content_filtered = sprintf( $content, $lazy_img, $lazy_iframe ); // Do not add srcset and sizes while testing. add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); // Enable globally for all tags. add_filter( 'wp_lazy_loading_enabled', '__return_true' ); $this->assertSame( $content_filtered, wp_filter_content_tags( $content_unfiltered ) ); remove_filter( 'wp_lazy_loading_enabled', '__return_true' ); remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); } /** * @ticket 44427 * @ticket 50756 */ public function test_wp_filter_content_tags_loading_lazy_opted_out() { $img = get_image_tag( self::$large_id, '', '', '', 'medium' ); $img = wp_img_tag_add_decoding_attr( $img, 'the_content' ); $iframe = ''; $content = '

Image, standard.

%1$s

Iframe, standard.

%2$s'; $content = sprintf( $content, $img, $iframe ); // Do not add srcset and sizes while testing. add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); // Disable globally for all tags. add_filter( 'wp_lazy_loading_enabled', '__return_false' ); $this->assertSame( $content, wp_filter_content_tags( $content ) ); remove_filter( 'wp_lazy_loading_enabled', '__return_false' ); remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); } /** * @ticket 44427 * @ticket 50367 */ public function test_wp_img_tag_add_loading_attr() { $img = ' width='; $img = wp_img_tag_add_loading_attr( $img, 'test' ); $this->assertStringContainsString( ' loading="lazy"', $img ); } /** * @ticket 44427 * @ticket 50367 */ public function test_wp_img_tag_add_loading_attr_without_src() { $img = ' width='; $img = wp_img_tag_add_loading_attr( $img, 'test' ); $this->assertStringNotContainsString( ' loading=', $img ); } /** * @ticket 44427 * @ticket 50367 */ public function test_wp_img_tag_add_loading_attr_with_single_quotes() { $img = " width="; $img = wp_img_tag_add_loading_attr( $img, 'test' ); $this->assertStringNotContainsString( ' loading=', $img ); // Test specifically that the attribute is not there with double-quotes, // to avoid regressions. $this->assertStringNotContainsString( ' loading="lazy"', $img ); } /** * @ticket 44427 * @ticket 50425 */ public function test_wp_img_tag_add_loading_attr_opt_out() { $img = ' width='; add_filter( 'wp_img_tag_add_loading_attr', '__return_false' ); $this->assertStringNotContainsString( ' loading=', $img ); } /** * Test that decoding="async" is not applied to img tags with single quotes. * * @ticket 56969 */ public function test_wp_img_tag_add_decoding_attr_with_single_quotes() { $img = ""; $img = wp_img_tag_add_decoding_attr( $img, 'test' ); $this->assertStringNotContainsString( ' decoding="async"', $img ); } /** * Test that decoding="async" is not applied to img tags inside JSON. * * @ticket 56969 */ public function test_decoding_async_not_applied_to_json() { $content = '{"image": "\"\""}'; $content = wp_filter_content_tags( $content ); $this->assertStringNotContainsString( ' decoding="async"', $content ); } /** * @ticket 50756 */ public function test_wp_iframe_tag_add_loading_attr() { $iframe = ''; $iframe = wp_iframe_tag_add_loading_attr( $iframe, 'test' ); $this->assertStringContainsString( ' loading="lazy"', $iframe ); } /** * @ticket 50756 */ public function test_wp_iframe_tag_add_loading_attr_without_src() { $iframe = ''; $iframe = wp_iframe_tag_add_loading_attr( $iframe, 'test' ); $this->assertStringNotContainsString( ' loading=', $iframe ); } /** * @ticket 50756 */ public function test_wp_iframe_tag_add_loading_attr_with_single_quotes() { $iframe = ""; $iframe = wp_iframe_tag_add_loading_attr( $iframe, 'test' ); $this->assertStringNotContainsString( ' loading=', $iframe ); // Test specifically that the attribute is not there with double-quotes, // to avoid regressions. $this->assertStringNotContainsString( ' loading="lazy"', $iframe ); } /** * @ticket 50756 */ public function test_wp_iframe_tag_add_loading_attr_opt_out() { $iframe = ''; add_filter( 'wp_iframe_tag_add_loading_attr', '__return_false' ); $iframe = wp_iframe_tag_add_loading_attr( $iframe, 'test' ); $this->assertStringNotContainsString( ' loading=', $iframe ); } /** * @ticket 52768 */ public function test_wp_iframe_tag_add_loading_attr_skip_wp_embed() { $iframe = ''; $fallback = '
Fallback content.
'; $iframe = wp_filter_oembed_result( $fallback . $iframe, (object) array( 'type' => 'rich' ), 'https://www.example.com' ); $iframe = wp_iframe_tag_add_loading_attr( $iframe, 'test' ); $this->assertStringNotContainsString( ' loading=', $iframe ); } /** * @ticket 44427 * @ticket 50425 */ public function test_wp_get_attachment_image_loading() { $img = wp_get_attachment_image( self::$large_id ); $this->assertStringContainsString( ' loading="lazy"', $img ); } /** * @ticket 44427 * @ticket 50425 */ public function test_wp_get_attachment_image_loading_opt_out() { add_filter( 'wp_lazy_loading_enabled', '__return_false' ); $img = wp_get_attachment_image( self::$large_id ); // There should not be any loading attribute in this case. $this->assertStringNotContainsString( ' loading=', $img ); } /** * @ticket 44427 * @ticket 50425 */ public function test_wp_get_attachment_image_loading_opt_out_individual() { // The default is already tested above, the filter below ensures that // lazy-loading is definitely enabled globally for images. add_filter( 'wp_lazy_loading_enabled', '__return_true' ); $img = wp_get_attachment_image( self::$large_id, 'thumbnail', false, array( 'loading' => false ) ); // There should not be any loading attribute in this case. $this->assertStringNotContainsString( ' loading=', $img ); } /** * @ticket 57086 * * @dataProvider data_wp_get_attachment_image_decoding_attr * * @covers ::wp_get_attachment_image */ public function test_wp_get_attachment_image_decoding_attr( $decoding, $expected ) { if ( 'no value' === $decoding ) { $image = wp_get_attachment_image( self::$large_id, 'thumbnail', false, array() ); } else { $image = wp_get_attachment_image( self::$large_id, 'thumbnail', false, array( 'decoding' => $decoding ) ); } if ( 'no value' === $expected ) { $this->assertStringNotContainsString( ' decoding=', $image ); } else { $this->assertStringContainsString( ' decoding="' . esc_attr( $expected ) . '"', $image ); } } /** * Data provider for test_wp_get_attachment_image_decoding_attr(). * * @return array[] */ public function data_wp_get_attachment_image_decoding_attr() { return array( 'default' => array( 'decoding' => 'no value', 'expected' => 'async', ), 'async' => array( 'decoding' => 'async', 'expected' => 'async', ), 'sync' => array( 'decoding' => 'sync', 'expected' => 'sync', ), 'auto' => array( 'decoding' => 'auto', 'expected' => 'auto', ), 'empty' => array( 'decoding' => '', 'expected' => 'no value', ), 'false' => array( 'decoding' => false, 'expected' => 'no value', ), 'null' => array( 'decoding' => null, 'expected' => 'no value', ), 'zero' => array( 'decoding' => 0, 'expected' => 'no value', ), 'zero string' => array( 'decoding' => '0', 'expected' => 'no value', ), 'zero float' => array( 'decoding' => 0.0, 'expected' => 'no value', ), 'invalid' => array( 'decoding' => 'invalid', 'expected' => 'no value', ), ); } /** * @ticket 44427 * @ticket 50425 * @ticket 50756 * @dataProvider data_wp_lazy_loading_enabled_tag_name_defaults * * @param string $tag_name Tag name. * @param bool $expected Expected return value. */ public function test_wp_lazy_loading_enabled_tag_name_defaults( $tag_name, $expected ) { if ( $expected ) { $this->assertTrue( wp_lazy_loading_enabled( $tag_name, 'the_content' ) ); } else { $this->assertFalse( wp_lazy_loading_enabled( $tag_name, 'the_content' ) ); } } public function data_wp_lazy_loading_enabled_tag_name_defaults() { return array( 'img => true' => array( 'img', true ), 'iframe => true' => array( 'iframe', true ), 'arbitrary tag => false' => array( 'blink', false ), ); } /** * @ticket 50425 * @ticket 53463 * @ticket 53675 * @dataProvider data_wp_lazy_loading_enabled_context_defaults * * @param string $context Function context. * @param bool $expected Expected return value. */ public function test_wp_lazy_loading_enabled_context_defaults( $context, $expected ) { if ( $expected ) { $this->assertTrue( wp_lazy_loading_enabled( 'img', $context ) ); } else { $this->assertFalse( wp_lazy_loading_enabled( 'img', $context ) ); } } public function data_wp_lazy_loading_enabled_context_defaults() { return array( 'wp_get_attachment_image => true' => array( 'wp_get_attachment_image', true ), 'the_content => true' => array( 'the_content', true ), 'the_excerpt => true' => array( 'the_excerpt', true ), 'widget_text_content => true' => array( 'widget_text_content', true ), 'widget_block_content => true' => array( 'widget_block_content', true ), 'get_avatar => true' => array( 'get_avatar', true ), 'arbitrary context => true' => array( 'something_completely_arbitrary', true ), 'the_post_thumbnail => true' => array( 'the_post_thumbnail', true ), ); } /** * @ticket 50543 */ public function test_wp_image_file_matches_image_meta() { $image_meta = wp_get_attachment_metadata( self::$large_id ); $image_src_full = wp_get_attachment_image_url( self::$large_id, 'full' ); $image_src_medium = wp_get_attachment_image_url( self::$large_id, 'medium' ); $this->assertTrue( wp_image_file_matches_image_meta( $image_src_full, $image_meta ) ); $this->assertTrue( wp_image_file_matches_image_meta( $image_src_medium, $image_meta ) ); } /** * @ticket 50543 */ public function test_wp_image_file_matches_image_meta_no_subsizes() { $image_meta = wp_get_attachment_metadata( self::$large_id ); $image_src = wp_get_attachment_image_url( self::$large_id, 'full' ); $image_meta['sizes'] = array(); $this->assertTrue( wp_image_file_matches_image_meta( $image_src, $image_meta ) ); } /** * @ticket 50543 */ public function test_wp_image_file_matches_image_meta_invalid_meta() { $image_meta = ''; // Attachment is not an image. $image_src = self::IMG_URL; $this->assertFalse( wp_image_file_matches_image_meta( $image_src, $image_meta ) ); } /** * @ticket 50543 */ public function test_wp_image_file_matches_image_meta_different_meta() { $image_meta = wp_get_attachment_metadata( self::$large_id ); $image_src = self::IMG_URL; // Different image. $this->assertFalse( wp_image_file_matches_image_meta( $image_src, $image_meta ) ); } /** * @ticket 50543 */ public function test_wp_image_file_matches_image_meta_original_image() { $image_meta = wp_get_attachment_metadata( self::$large_id ); $image_src = wp_get_original_image_url( self::$large_id ); $this->assertTrue( wp_image_file_matches_image_meta( $image_src, $image_meta ) ); } /** * @ticket 22101 */ public function test_gallery_shortcode_when_is_feed_true() { $this->go_to( '/?feed=rss2' ); // Default: Links to image attachment page URL. $actual = gallery_shortcode( array( 'ids' => self::$large_id, ) ); $this->assertStringContainsString( '?attachment_id=', $actual ); // File: Links to image file URL. $actual = gallery_shortcode( array( 'ids' => self::$large_id, 'link' => 'file', ) ); $this->assertSame( 2, substr_count( $actual, '.jpg' ) ); // None: Does not link. $actual = gallery_shortcode( array( 'ids' => self::$large_id, 'link' => 'none', ) ); $this->assertStringNotContainsString( 'set_permalink_structure( '/%postname%' ); $post = get_post( self::$post_ids[ $post_key ] ); /* * The dataProvider runs before the fixures are set up, therefore the * post object IDs are placeholders that needs to be replaced. */ $expected_url = home_url( str_replace( '%ID%', $post->ID, $expected_url ) ); $this->go_to( get_permalink( $post ) ); $this->assertSame( $expected_url, get_permalink( $post ) ); if ( $expected_404 ) { $this->assertQueryTrue( 'is_404' ); } else { $this->assertQueryTrue( 'is_attachment', 'is_single', 'is_singular' ); } $this->assertSame( 'attachment', $post->post_type ); } /** * Data provider for test_attachment_permalinks_based_on_parent_status(). * * @return array[] { * @type string $post_key Post as keyed in the shared fixture array. * @type string $expected_url Expected permalink. * $type bool $expected_404 Whether the page is expected to return a 404 result. * } */ public function data_attachment_permalinks_based_on_parent_status() { return array( array( 'draft-attachment', '/?attachment_id=%ID%', true ), array( 'publish-attachment', '/publish-post/publish-attachment', false ), array( 'future-attachment', '/future-post/future-attachment', false ), array( 'auto-draft-attachment', '/?attachment_id=%ID%', true ), array( 'trash-attachment', '/?attachment_id=%ID%', false ), ); } /** * @ticket 53675 * @dataProvider data_wp_get_loading_attr_default * * @param string $context */ public function test_wp_get_loading_attr_default( $context ) { global $wp_query, $wp_the_query; // Return 'lazy' by default. $this->assertSame( 'lazy', wp_get_loading_attr_default( 'test' ) ); $this->assertSame( 'lazy', wp_get_loading_attr_default( 'wp_get_attachment_image' ) ); // Return 'lazy' if not in the loop or the main query. $this->assertSame( 'lazy', wp_get_loading_attr_default( $context ) ); $wp_query = new WP_Query( array( 'post__in' => array( self::$post_ids['publish'] ) ) ); $this->reset_content_media_count(); $this->reset_omit_loading_attr_filter(); while ( have_posts() ) { the_post(); // Return 'lazy' if in the loop but not in the main query. $this->assertSame( 'lazy', wp_get_loading_attr_default( $context ) ); // Set as main query. $wp_the_query = $wp_query; // For contexts other than for the main content, still return 'lazy' even in the loop // and in the main query, and do not increase the content media count. $this->assertSame( 'lazy', wp_get_loading_attr_default( 'wp_get_attachment_image' ) ); // Return `false` if in the loop and in the main query and it is the first element. $this->assertFalse( wp_get_loading_attr_default( $context ) ); // Return 'lazy' if in the loop and in the main query for any subsequent elements. $this->assertSame( 'lazy', wp_get_loading_attr_default( $context ) ); // Yes, for all subsequent elements. $this->assertSame( 'lazy', wp_get_loading_attr_default( $context ) ); } } public function data_wp_get_loading_attr_default() { return array( array( 'the_content' ), array( 'the_post_thumbnail' ), ); } /** * @ticket 53675 */ public function test_wp_omit_loading_attr_threshold_filter() { global $wp_query, $wp_the_query; $wp_query = new WP_Query( array( 'post__in' => array( self::$post_ids['publish'] ) ) ); $wp_the_query = $wp_query; $this->reset_content_media_count(); $this->reset_omit_loading_attr_filter(); // Use the filter to alter the threshold for not lazy-loading to the first three elements. add_filter( 'wp_omit_loading_attr_threshold', function() { return 3; } ); while ( have_posts() ) { the_post(); // Due to the filter, now the first three elements should not be lazy-loaded, i.e. return `false`. for ( $i = 0; $i < 3; $i++ ) { $this->assertFalse( wp_get_loading_attr_default( 'the_content' ) ); } // For following elements, lazy-load them again. $this->assertSame( 'lazy', wp_get_loading_attr_default( 'the_content' ) ); } } /** * @ticket 53675 */ public function test_wp_filter_content_tags_with_wp_get_loading_attr_default() { global $wp_query, $wp_the_query; $img1 = get_image_tag( self::$large_id, '', '', '', 'large' ); $iframe1 = ''; $img2 = get_image_tag( self::$large_id, '', '', '', 'medium' ); $img3 = get_image_tag( self::$large_id, '', '', '', 'thumbnail' ); $iframe2 = ''; $lazy_img2 = wp_img_tag_add_loading_attr( $img2, 'the_content' ); $lazy_img3 = wp_img_tag_add_loading_attr( $img3, 'the_content' ); $lazy_iframe2 = wp_iframe_tag_add_loading_attr( $iframe2, 'the_content' ); // Use a threshold of 2. add_filter( 'wp_omit_loading_attr_threshold', function() { return 2; } ); // Following the threshold of 2, the first two content media elements should not be lazy-loaded. $content_unfiltered = $img1 . $iframe1 . $img2 . $img3 . $iframe2; $content_expected = $img1 . $iframe1 . $lazy_img2 . $lazy_img3 . $lazy_iframe2; $content_expected = wp_img_tag_add_decoding_attr( $content_expected, 'the_content' ); $wp_query = new WP_Query( array( 'post__in' => array( self::$post_ids['publish'] ) ) ); $wp_the_query = $wp_query; $this->reset_content_media_count(); $this->reset_omit_loading_attr_filter(); while ( have_posts() ) { the_post(); add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); $content_filtered = wp_filter_content_tags( $content_unfiltered, 'the_content' ); remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); } // After filtering, the first image should not be lazy-loaded while the other ones should be. $this->assertSame( $content_expected, $content_filtered ); } /** * @ticket 53675 */ public function test_wp_omit_loading_attr_threshold() { $this->reset_omit_loading_attr_filter(); // Apply filter, ensure default value of 1. $omit_threshold = wp_omit_loading_attr_threshold(); $this->assertSame( 1, $omit_threshold ); // Add a filter that changes the value to 3. However, the filter is not applied a subsequent time in a single // page load by default, so the value is still 1. add_filter( 'wp_omit_loading_attr_threshold', function() { return 3; } ); $omit_threshold = wp_omit_loading_attr_threshold(); $this->assertSame( 1, $omit_threshold ); // Only by enforcing a fresh check, the filter gets re-applied. $omit_threshold = wp_omit_loading_attr_threshold( true ); $this->assertSame( 3, $omit_threshold ); } private function reset_content_media_count() { // Get current value without increasing. $content_media_count = wp_increase_content_media_count( 0 ); // Decrease it by its current value to "reset" it back to 0. wp_increase_content_media_count( - $content_media_count ); } private function reset_omit_loading_attr_filter() { // Add filter to "reset" omit threshold back to null (unset). add_filter( 'wp_omit_loading_attr_threshold', '__return_null', 100 ); // Force filter application to re-run. wp_omit_loading_attr_threshold( true ); // Clean up the above filter. remove_filter( 'wp_omit_loading_attr_threshold', '__return_null', 100 ); } /** * Test that generated files with the `image_editor_output_format` applied use the correct * quality level based on their mime type. * * @ticket 56442 */ public function test_quality_with_image_conversion_file_sizes() { add_filter( 'image_editor_output_format', array( $this, 'image_editor_output_jpeg' ) ); $temp_dir = get_temp_dir(); $file = $temp_dir . '/33772.jpg'; copy( DIR_TESTDATA . '/images/33772.jpg', $file ); // Set JPEG output quality very low and WebP quality very high, this should force all generated WebP images to // be larger than the the matching generated JPEGs. add_filter( 'wp_editor_set_quality', array( $this, 'image_editor_change_quality_low_jpeg' ), 10, 2 ); $editor = wp_get_image_editor( $file ); // Verify that the selected editor supports WebP output. if ( ! $editor->supports_mime_type( 'image/webp' ) ) { $this->markTestSkipped( 'WebP is not supported by the selected image editor.' ); } $attachment_id = self::factory()->attachment->create_object( array( 'post_mime_type' => 'image/jpeg', 'file' => $file, ) ); add_filter( 'big_image_size_threshold', array( $this, 'add_big_image_size_threshold' ) ); // Generate all sizes as JPEGs. $jpeg_sizes = wp_generate_attachment_metadata( $attachment_id, $file ); remove_filter( 'image_editor_output_format', array( $this, 'image_editor_output_jpeg' ) ); // Generate all sizes as WebP. add_filter( 'image_editor_output_format', array( $this, 'image_editor_output_webp' ) ); $webp_sizes = wp_generate_attachment_metadata( $attachment_id, $file ); remove_filter( 'image_editor_output_format', array( $this, 'image_editor_output_webp' ) ); // The main (scaled) image: the JPEG should be smaller than the WebP. $this->assertLessThan( $webp_sizes['filesize'], $jpeg_sizes['filesize'], 'The JPEG should be smaller than the WebP.' ); // Sub-sizes: for each size, the JPEGs should be smaller than the WebP. $sizes_to_compare = array_intersect_key( $jpeg_sizes['sizes'], $webp_sizes['sizes'] ); foreach ( $sizes_to_compare as $size => $size_data ) { $this->assertLessThan( $webp_sizes['sizes'][ $size ]['filesize'], $jpeg_sizes['sizes'][ $size ]['filesize'] ); } } /** * Add threshold to create a `-scaled` output image for testing. */ public function add_big_image_size_threshold() { return 1000; } /** * Output JPEG files. */ public function image_editor_output_jpeg() { return array( 'image/jpeg' => 'image/jpeg' ); } /** * Output WebP files. */ public function image_editor_output_webp() { return array( 'image/jpeg' => 'image/webp' ); } /** * Changes the quality using very low quality for JPEGs and very high quality * for WebPs, used to verify the filter is applying correctly. * * @param int $quality Default quality. * @param string $mime_type Image mime-type. * @return int The changed quality. */ public function image_editor_change_quality_low_jpeg( $quality, $mime_type ) { if ( 'image/jpeg' === $mime_type ) { return 1; } elseif ( 'image/webp' === $mime_type ) { return 100; } else { return 30; } } } /** * Helper class for `test_autoembed`. */ class Test_Autoembed extends WP_Embed { public function shortcode( $attr, $url = '' ) { return '[embed]'; } }