From b6392f5cfd6fdf13dfdc6c8ad440f4c1ee5f5a2e Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Mon, 20 Apr 2026 12:21:34 +0530 Subject: [PATCH 1/9] Embeds: Fix get_site_icon_url() dropping fallback when attachment URL fails --- src/wp-includes/embed.php | 18 +++++++++++++++--- src/wp-includes/general-template.php | 5 ++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/embed.php b/src/wp-includes/embed.php index 3fb8968c7c62c..24e6abf2b4de1 100644 --- a/src/wp-includes/embed.php +++ b/src/wp-includes/embed.php @@ -1233,11 +1233,23 @@ function print_embed_sharing_dialog() { * @since 4.5.0 */ function the_embed_site_title() { + $site_icon_url = get_site_icon_url( 32, includes_url( 'images/w-logo-blue.png' ) ); + $site_icon_url_2x = get_site_icon_url( 64, includes_url( 'images/w-logo-blue.png' ) ); + + $icon_img = ''; + if ( $site_icon_url ) { + $srcset = $site_icon_url_2x ? sprintf( ' srcset="%s 2x"', esc_url( $site_icon_url_2x ) ) : ''; + $icon_img = sprintf( + '', + esc_url( $site_icon_url ), + $srcset + ); + } + $site_title = sprintf( - '%s', + '%s%s', esc_url( home_url() ), - esc_url( get_site_icon_url( 32, includes_url( 'images/w-logo-blue.png' ) ) ), - esc_url( get_site_icon_url( 64, includes_url( 'images/w-logo-blue.png' ) ) ), + $icon_img, esc_html( get_bloginfo( 'name' ) ) ); diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 47e2aeb2ebb05..1ba2912953ae8 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -978,7 +978,10 @@ function get_site_icon_url( $size = 512, $url = '', $blog_id = 0 ) { } else { $size_data = array( $size, $size ); } - $url = wp_get_attachment_image_url( $site_icon_id, $size_data ); + $attachment_url = wp_get_attachment_image_url( $site_icon_id, $size_data ); + if ( $attachment_url ) { + $url = $attachment_url; + } } if ( $switched_blog ) { From 38f40662565c5de0d4ba854a01a614db099ec5b9 Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Mon, 20 Apr 2026 12:54:20 +0530 Subject: [PATCH 2/9] Embeds: Move 2x site icon URL fetch inside if condition --- src/wp-includes/embed.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/embed.php b/src/wp-includes/embed.php index 24e6abf2b4de1..f46377294d38a 100644 --- a/src/wp-includes/embed.php +++ b/src/wp-includes/embed.php @@ -1233,13 +1233,13 @@ function print_embed_sharing_dialog() { * @since 4.5.0 */ function the_embed_site_title() { - $site_icon_url = get_site_icon_url( 32, includes_url( 'images/w-logo-blue.png' ) ); - $site_icon_url_2x = get_site_icon_url( 64, includes_url( 'images/w-logo-blue.png' ) ); + $site_icon_url = get_site_icon_url( 32, includes_url( 'images/w-logo-blue.png' ) ); $icon_img = ''; if ( $site_icon_url ) { - $srcset = $site_icon_url_2x ? sprintf( ' srcset="%s 2x"', esc_url( $site_icon_url_2x ) ) : ''; - $icon_img = sprintf( + $site_icon_url_2x = get_site_icon_url( 64, includes_url( 'images/w-logo-blue.png' ) ); + $srcset = $site_icon_url_2x ? sprintf( ' srcset="%s 2x"', esc_url( $site_icon_url_2x ) ) : ''; + $icon_img = sprintf( '', esc_url( $site_icon_url ), $srcset From 8548ea959edeb14e8e8621fc0fd13ebbb24ee0ec Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Tue, 21 Apr 2026 12:03:19 +0530 Subject: [PATCH 3/9] Embeds: Skip srcset when 1x and 2x site icon URLs are identical --- src/wp-includes/embed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/embed.php b/src/wp-includes/embed.php index f46377294d38a..b53c00f67ddc7 100644 --- a/src/wp-includes/embed.php +++ b/src/wp-includes/embed.php @@ -1238,7 +1238,7 @@ function the_embed_site_title() { $icon_img = ''; if ( $site_icon_url ) { $site_icon_url_2x = get_site_icon_url( 64, includes_url( 'images/w-logo-blue.png' ) ); - $srcset = $site_icon_url_2x ? sprintf( ' srcset="%s 2x"', esc_url( $site_icon_url_2x ) ) : ''; + $srcset = ( $site_icon_url_2x && $site_icon_url !== $site_icon_url_2x ) ? sprintf( ' srcset="%s 2x"', esc_url( $site_icon_url_2x ) ) : ''; $icon_img = sprintf( '', esc_url( $site_icon_url ), From 0c97d2769312227fbe90ed586fab4a5fac5115ab Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Wed, 22 Apr 2026 13:14:19 +0530 Subject: [PATCH 4/9] Tests: Add coverage for get_site_icon_url() and the_embed_site_title() fixes --- tests/phpunit/tests/general/template.php | 133 +++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/tests/phpunit/tests/general/template.php b/tests/phpunit/tests/general/template.php index d3b35a2c46c2b..23c689466c162 100644 --- a/tests/phpunit/tests/general/template.php +++ b/tests/phpunit/tests/general/template.php @@ -122,6 +122,27 @@ public function test_get_site_icon_url() { $this->assertEmpty( get_site_icon_url(), 'Site icon URL should not be set after removal.' ); } + /** + * @ticket 65098 + * @group site_icon + * @covers ::get_site_icon_url + * @requires function imagejpeg + */ + public function test_get_site_icon_url_returns_fallback_when_attachment_url_fails() { + $this->set_site_icon(); + + $fallback = 'https://example.com/fallback-icon.png'; + add_filter( 'wp_get_attachment_image_src', '__return_false' ); + + try { + $url = get_site_icon_url( 32, $fallback ); + } finally { + remove_filter( 'wp_get_attachment_image_src', '__return_false' ); + } + + $this->assertSame( $fallback, $url, 'Fallback URL should be returned when attachment URL lookup fails.' ); + } + /** * @group site_icon * @covers ::site_icon_url @@ -807,4 +828,116 @@ public function test_get_the_archive_title_is_correct_for_author_queries() { $this->assertSame( $user_with_posts->display_name, $title_when_posts ); $this->assertSame( $user_with_no_posts->display_name, $title_when_no_posts ); } + + /** + * @ticket 65098 + * @group site_icon + * @covers ::the_embed_site_title + * @requires function imagejpeg + */ + public function test_the_embed_site_title_contains_site_icon_when_set() { + $this->set_site_icon(); + + $url_32 = get_site_icon_url( 32 ); + $url_64 = get_site_icon_url( 64 ); + + ob_start(); + the_embed_site_title(); + $output = ob_get_clean(); + + $this->assertStringContainsString( 'wp-embed-site-icon', $output, 'Output should contain site icon img tag.' ); + $this->assertStringContainsString( esc_url( $url_32 ), $output, 'Output should contain 32px site icon URL.' ); + $this->assertStringContainsString( esc_url( $url_64 ), $output, 'Output should contain 64px site icon URL in srcset.' ); + } + + /** + * @ticket 65098 + * @group site_icon + * @covers ::the_embed_site_title + * @requires function imagejpeg + */ + public function test_the_embed_site_title_uses_fallback_when_attachment_url_fails() { + $this->set_site_icon(); + + // Simulate wp_get_attachment_image_url() failing. + add_filter( 'wp_get_attachment_image_src', '__return_false' ); + + try { + ob_start(); + the_embed_site_title(); + $output = ob_get_clean(); + } finally { + remove_filter( 'wp_get_attachment_image_src', '__return_false' ); + } + + $fallback = includes_url( 'images/w-logo-blue.png' ); + $this->assertStringContainsString( 'wp-embed-site-icon', $output, 'Output should contain site icon img tag with fallback.' ); + $this->assertStringContainsString( esc_url( $fallback ), $output, 'Output should contain fallback URL when attachment URL fails.' ); + $this->assertStringNotContainsString( 'src=""', $output, 'Output should not contain empty src attribute.' ); + } + + /** + * @ticket 65098 + * @group site_icon + * @covers ::the_embed_site_title + */ + public function test_the_embed_site_title_omits_img_when_url_is_empty() { + // Force get_site_icon_url() to return empty string via filter. + add_filter( 'get_site_icon_url', '__return_empty_string' ); + + try { + ob_start(); + the_embed_site_title(); + $output = ob_get_clean(); + } finally { + remove_filter( 'get_site_icon_url', '__return_empty_string' ); + } + + $this->assertStringNotContainsString( 'wp-embed-site-icon', $output, 'img tag should be omitted when URL is empty.' ); + $this->assertStringNotContainsString( 'src=""', $output, 'Output should not contain empty src attribute.' ); + $this->assertStringContainsString( get_bloginfo( 'name' ), $output, 'Site name should still be present.' ); + } + + /** + * @ticket 65098 + * @group site_icon + * @covers ::the_embed_site_title + */ + public function test_the_embed_site_title_omits_srcset_when_1x_and_2x_urls_are_identical() { + // Force both sizes to return the same URL. + $svg_url = 'https://example.com/icon.svg'; + $filter = static function () use ( $svg_url ) { + return $svg_url; + }; + + add_filter( 'get_site_icon_url', $filter ); + + try { + ob_start(); + the_embed_site_title(); + $output = ob_get_clean(); + } finally { + remove_filter( 'get_site_icon_url', $filter ); + } + + $this->assertStringNotContainsString( 'srcset=', $output, 'srcset should be omitted when 1x and 2x URLs are identical.' ); + $this->assertStringContainsString( esc_url( $svg_url ), $output, '1x URL should still be present in src.' ); + } + + /** + * @ticket 65098 + * @group site_icon + * @covers ::the_embed_site_title + */ + public function test_the_embed_site_title_uses_fallback_without_srcset_when_no_site_icon_set() { + ob_start(); + the_embed_site_title(); + $output = ob_get_clean(); + + $fallback = includes_url( 'images/w-logo-blue.png' ); + + $this->assertStringContainsString( 'wp-embed-site-icon', $output, 'Fallback icon img should be present when no site icon is set.' ); + $this->assertStringContainsString( esc_url( $fallback ), $output, 'Output should contain fallback icon URL.' ); + $this->assertStringNotContainsString( 'srcset=', $output, 'srcset should be omitted when 1x and 2x fallback URLs are identical.' ); + } } From 07015615138ff83cd63d8789140ea87d8a353f50 Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Thu, 23 Apr 2026 13:04:17 +0530 Subject: [PATCH 5/9] Tests: Use get_echo() helper and remove manual filter cleanup in site icon tests --- tests/phpunit/tests/general/template.php | 43 ++++-------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/tests/phpunit/tests/general/template.php b/tests/phpunit/tests/general/template.php index 23c689466c162..f697721e2e441 100644 --- a/tests/phpunit/tests/general/template.php +++ b/tests/phpunit/tests/general/template.php @@ -133,12 +133,7 @@ public function test_get_site_icon_url_returns_fallback_when_attachment_url_fail $fallback = 'https://example.com/fallback-icon.png'; add_filter( 'wp_get_attachment_image_src', '__return_false' ); - - try { - $url = get_site_icon_url( 32, $fallback ); - } finally { - remove_filter( 'wp_get_attachment_image_src', '__return_false' ); - } + $url = get_site_icon_url( 32, $fallback ); $this->assertSame( $fallback, $url, 'Fallback URL should be returned when attachment URL lookup fails.' ); } @@ -841,9 +836,7 @@ public function test_the_embed_site_title_contains_site_icon_when_set() { $url_32 = get_site_icon_url( 32 ); $url_64 = get_site_icon_url( 64 ); - ob_start(); - the_embed_site_title(); - $output = ob_get_clean(); + $output = get_echo( 'the_embed_site_title' ); $this->assertStringContainsString( 'wp-embed-site-icon', $output, 'Output should contain site icon img tag.' ); $this->assertStringContainsString( esc_url( $url_32 ), $output, 'Output should contain 32px site icon URL.' ); @@ -861,14 +854,7 @@ public function test_the_embed_site_title_uses_fallback_when_attachment_url_fail // Simulate wp_get_attachment_image_url() failing. add_filter( 'wp_get_attachment_image_src', '__return_false' ); - - try { - ob_start(); - the_embed_site_title(); - $output = ob_get_clean(); - } finally { - remove_filter( 'wp_get_attachment_image_src', '__return_false' ); - } + $output = get_echo( 'the_embed_site_title' ); $fallback = includes_url( 'images/w-logo-blue.png' ); $this->assertStringContainsString( 'wp-embed-site-icon', $output, 'Output should contain site icon img tag with fallback.' ); @@ -884,14 +870,7 @@ public function test_the_embed_site_title_uses_fallback_when_attachment_url_fail public function test_the_embed_site_title_omits_img_when_url_is_empty() { // Force get_site_icon_url() to return empty string via filter. add_filter( 'get_site_icon_url', '__return_empty_string' ); - - try { - ob_start(); - the_embed_site_title(); - $output = ob_get_clean(); - } finally { - remove_filter( 'get_site_icon_url', '__return_empty_string' ); - } + $output = get_echo( 'the_embed_site_title' ); $this->assertStringNotContainsString( 'wp-embed-site-icon', $output, 'img tag should be omitted when URL is empty.' ); $this->assertStringNotContainsString( 'src=""', $output, 'Output should not contain empty src attribute.' ); @@ -911,14 +890,7 @@ public function test_the_embed_site_title_omits_srcset_when_1x_and_2x_urls_are_i }; add_filter( 'get_site_icon_url', $filter ); - - try { - ob_start(); - the_embed_site_title(); - $output = ob_get_clean(); - } finally { - remove_filter( 'get_site_icon_url', $filter ); - } + $output = get_echo( 'the_embed_site_title' ); $this->assertStringNotContainsString( 'srcset=', $output, 'srcset should be omitted when 1x and 2x URLs are identical.' ); $this->assertStringContainsString( esc_url( $svg_url ), $output, '1x URL should still be present in src.' ); @@ -930,10 +902,7 @@ public function test_the_embed_site_title_omits_srcset_when_1x_and_2x_urls_are_i * @covers ::the_embed_site_title */ public function test_the_embed_site_title_uses_fallback_without_srcset_when_no_site_icon_set() { - ob_start(); - the_embed_site_title(); - $output = ob_get_clean(); - + $output = get_echo( 'the_embed_site_title' ); $fallback = includes_url( 'images/w-logo-blue.png' ); $this->assertStringContainsString( 'wp-embed-site-icon', $output, 'Fallback icon img should be present when no site icon is set.' ); From a4595185934ec112e0d43373468dce951a1d36cc Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Fri, 24 Apr 2026 11:59:43 +0530 Subject: [PATCH 6/9] Embeds: Extract fallback icon URL to variable for reuse --- src/wp-includes/embed.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/embed.php b/src/wp-includes/embed.php index b53c00f67ddc7..c6d9433f37677 100644 --- a/src/wp-includes/embed.php +++ b/src/wp-includes/embed.php @@ -1233,11 +1233,12 @@ function print_embed_sharing_dialog() { * @since 4.5.0 */ function the_embed_site_title() { - $site_icon_url = get_site_icon_url( 32, includes_url( 'images/w-logo-blue.png' ) ); + $fallback_icon_url = includes_url( 'images/w-logo-blue.png' ); + $site_icon_url = get_site_icon_url( 32, $fallback_icon_url ); $icon_img = ''; if ( $site_icon_url ) { - $site_icon_url_2x = get_site_icon_url( 64, includes_url( 'images/w-logo-blue.png' ) ); + $site_icon_url_2x = get_site_icon_url( 64, $fallback_icon_url ); $srcset = ( $site_icon_url_2x && $site_icon_url !== $site_icon_url_2x ) ? sprintf( ' srcset="%s 2x"', esc_url( $site_icon_url_2x ) ) : ''; $icon_img = sprintf( '', From cef1f4fa25e9fa81bfbd7d8dd19d9b7075b4ea2b Mon Sep 17 00:00:00 2001 From: Sukhendu Sekhar Guria Date: Fri, 24 Apr 2026 12:21:23 +0530 Subject: [PATCH 7/9] Tests: Use WP_HTML_Tag_Processor for img attribute assertions --- tests/phpunit/tests/general/template.php | 41 +++++++++++++++--------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/tests/phpunit/tests/general/template.php b/tests/phpunit/tests/general/template.php index f697721e2e441..4ad61d22a3a4b 100644 --- a/tests/phpunit/tests/general/template.php +++ b/tests/phpunit/tests/general/template.php @@ -836,11 +836,13 @@ public function test_the_embed_site_title_contains_site_icon_when_set() { $url_32 = get_site_icon_url( 32 ); $url_64 = get_site_icon_url( 64 ); - $output = get_echo( 'the_embed_site_title' ); + $output = get_echo( 'the_embed_site_title' ); + $processor = new WP_HTML_Tag_Processor( $output ); - $this->assertStringContainsString( 'wp-embed-site-icon', $output, 'Output should contain site icon img tag.' ); - $this->assertStringContainsString( esc_url( $url_32 ), $output, 'Output should contain 32px site icon URL.' ); - $this->assertStringContainsString( esc_url( $url_64 ), $output, 'Output should contain 64px site icon URL in srcset.' ); + $this->assertTrue( $processor->next_tag( 'IMG' ), 'Expected IMG tag.' ); + $this->assertTrue( $processor->has_class( 'wp-embed-site-icon' ), 'Expected IMG to have wp-embed-site-icon class.' ); + $this->assertSame( $url_32, $processor->get_attribute( 'src' ), 'Output should contain 32px site icon URL in src.' ); + $this->assertStringContainsString( $url_64, $processor->get_attribute( 'srcset' ), 'Output should contain 64px site icon URL in srcset.' ); } /** @@ -856,10 +858,12 @@ public function test_the_embed_site_title_uses_fallback_when_attachment_url_fail add_filter( 'wp_get_attachment_image_src', '__return_false' ); $output = get_echo( 'the_embed_site_title' ); - $fallback = includes_url( 'images/w-logo-blue.png' ); - $this->assertStringContainsString( 'wp-embed-site-icon', $output, 'Output should contain site icon img tag with fallback.' ); - $this->assertStringContainsString( esc_url( $fallback ), $output, 'Output should contain fallback URL when attachment URL fails.' ); - $this->assertStringNotContainsString( 'src=""', $output, 'Output should not contain empty src attribute.' ); + $fallback = includes_url( 'images/w-logo-blue.png' ); + $processor = new WP_HTML_Tag_Processor( $output ); + + $this->assertTrue( $processor->next_tag( 'IMG' ), 'Expected IMG tag with fallback.' ); + $this->assertTrue( $processor->has_class( 'wp-embed-site-icon' ), 'Expected IMG to have wp-embed-site-icon class.' ); + $this->assertSame( $fallback, $processor->get_attribute( 'src' ), 'Output should contain fallback URL in src when attachment URL fails.' ); } /** @@ -872,8 +876,9 @@ public function test_the_embed_site_title_omits_img_when_url_is_empty() { add_filter( 'get_site_icon_url', '__return_empty_string' ); $output = get_echo( 'the_embed_site_title' ); - $this->assertStringNotContainsString( 'wp-embed-site-icon', $output, 'img tag should be omitted when URL is empty.' ); - $this->assertStringNotContainsString( 'src=""', $output, 'Output should not contain empty src attribute.' ); + $processor = new WP_HTML_Tag_Processor( $output ); + + $this->assertFalse( $processor->next_tag( 'IMG' ), 'IMG tag should be omitted when URL is empty.' ); $this->assertStringContainsString( get_bloginfo( 'name' ), $output, 'Site name should still be present.' ); } @@ -892,8 +897,11 @@ public function test_the_embed_site_title_omits_srcset_when_1x_and_2x_urls_are_i add_filter( 'get_site_icon_url', $filter ); $output = get_echo( 'the_embed_site_title' ); - $this->assertStringNotContainsString( 'srcset=', $output, 'srcset should be omitted when 1x and 2x URLs are identical.' ); - $this->assertStringContainsString( esc_url( $svg_url ), $output, '1x URL should still be present in src.' ); + $processor = new WP_HTML_Tag_Processor( $output ); + + $this->assertTrue( $processor->next_tag( 'IMG' ), 'Expected IMG tag.' ); + $this->assertSame( $svg_url, $processor->get_attribute( 'src' ), '1x URL should be present in src.' ); + $this->assertNull( $processor->get_attribute( 'srcset' ), 'srcset should be omitted when 1x and 2x URLs are identical.' ); } /** @@ -905,8 +913,11 @@ public function test_the_embed_site_title_uses_fallback_without_srcset_when_no_s $output = get_echo( 'the_embed_site_title' ); $fallback = includes_url( 'images/w-logo-blue.png' ); - $this->assertStringContainsString( 'wp-embed-site-icon', $output, 'Fallback icon img should be present when no site icon is set.' ); - $this->assertStringContainsString( esc_url( $fallback ), $output, 'Output should contain fallback icon URL.' ); - $this->assertStringNotContainsString( 'srcset=', $output, 'srcset should be omitted when 1x and 2x fallback URLs are identical.' ); + $processor = new WP_HTML_Tag_Processor( $output ); + + $this->assertTrue( $processor->next_tag( 'IMG' ), 'Expected IMG tag with fallback.' ); + $this->assertTrue( $processor->has_class( 'wp-embed-site-icon' ), 'Expected IMG to have wp-embed-site-icon class.' ); + $this->assertSame( $fallback, $processor->get_attribute( 'src' ), 'Output should contain fallback icon URL in src.' ); + $this->assertNull( $processor->get_attribute( 'srcset' ), 'srcset should be omitted when 1x and 2x fallback URLs are identical.' ); } } From 8775c72b9eee6ec333da2cf06c87f6a2345cfc65 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 24 Apr 2026 10:41:08 -0700 Subject: [PATCH 8/9] Improve static analysis for PHPStan --- tests/phpunit/tests/general/template.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/phpunit/tests/general/template.php b/tests/phpunit/tests/general/template.php index 4ad61d22a3a4b..bbf798f126578 100644 --- a/tests/phpunit/tests/general/template.php +++ b/tests/phpunit/tests/general/template.php @@ -128,7 +128,7 @@ public function test_get_site_icon_url() { * @covers ::get_site_icon_url * @requires function imagejpeg */ - public function test_get_site_icon_url_returns_fallback_when_attachment_url_fails() { + public function test_get_site_icon_url_returns_fallback_when_attachment_url_fails(): void { $this->set_site_icon(); $fallback = 'https://example.com/fallback-icon.png'; @@ -830,7 +830,7 @@ public function test_get_the_archive_title_is_correct_for_author_queries() { * @covers ::the_embed_site_title * @requires function imagejpeg */ - public function test_the_embed_site_title_contains_site_icon_when_set() { + public function test_the_embed_site_title_contains_site_icon_when_set(): void { $this->set_site_icon(); $url_32 = get_site_icon_url( 32 ); @@ -842,7 +842,9 @@ public function test_the_embed_site_title_contains_site_icon_when_set() { $this->assertTrue( $processor->next_tag( 'IMG' ), 'Expected IMG tag.' ); $this->assertTrue( $processor->has_class( 'wp-embed-site-icon' ), 'Expected IMG to have wp-embed-site-icon class.' ); $this->assertSame( $url_32, $processor->get_attribute( 'src' ), 'Output should contain 32px site icon URL in src.' ); - $this->assertStringContainsString( $url_64, $processor->get_attribute( 'srcset' ), 'Output should contain 64px site icon URL in srcset.' ); + $srcset = $processor->get_attribute( 'srcset' ); + $this->assertIsString( $srcset, 'Expected srcset to be present.' ); + $this->assertStringContainsString( $url_64, $srcset, 'Output should contain 64px site icon URL in srcset.' ); } /** @@ -851,7 +853,7 @@ public function test_the_embed_site_title_contains_site_icon_when_set() { * @covers ::the_embed_site_title * @requires function imagejpeg */ - public function test_the_embed_site_title_uses_fallback_when_attachment_url_fails() { + public function test_the_embed_site_title_uses_fallback_when_attachment_url_fails(): void { $this->set_site_icon(); // Simulate wp_get_attachment_image_url() failing. @@ -871,7 +873,7 @@ public function test_the_embed_site_title_uses_fallback_when_attachment_url_fail * @group site_icon * @covers ::the_embed_site_title */ - public function test_the_embed_site_title_omits_img_when_url_is_empty() { + public function test_the_embed_site_title_omits_img_when_url_is_empty(): void { // Force get_site_icon_url() to return empty string via filter. add_filter( 'get_site_icon_url', '__return_empty_string' ); $output = get_echo( 'the_embed_site_title' ); @@ -887,7 +889,7 @@ public function test_the_embed_site_title_omits_img_when_url_is_empty() { * @group site_icon * @covers ::the_embed_site_title */ - public function test_the_embed_site_title_omits_srcset_when_1x_and_2x_urls_are_identical() { + public function test_the_embed_site_title_omits_srcset_when_1x_and_2x_urls_are_identical(): void { // Force both sizes to return the same URL. $svg_url = 'https://example.com/icon.svg'; $filter = static function () use ( $svg_url ) { @@ -909,7 +911,7 @@ public function test_the_embed_site_title_omits_srcset_when_1x_and_2x_urls_are_i * @group site_icon * @covers ::the_embed_site_title */ - public function test_the_embed_site_title_uses_fallback_without_srcset_when_no_site_icon_set() { + public function test_the_embed_site_title_uses_fallback_without_srcset_when_no_site_icon_set(): void { $output = get_echo( 'the_embed_site_title' ); $fallback = includes_url( 'images/w-logo-blue.png' ); From d4d3ed00ac3048328542b10d3e63981f3c0f2351 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 24 Apr 2026 10:41:19 -0700 Subject: [PATCH 9/9] Add missing typing for get_echo() --- tests/phpunit/includes/utils.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/includes/utils.php b/tests/phpunit/includes/utils.php index 014f4b83c2301..62cc7805f4898 100644 --- a/tests/phpunit/includes/utils.php +++ b/tests/phpunit/includes/utils.php @@ -432,10 +432,19 @@ function dmp_filter( $a ) { return $a; } -function get_echo( $callback, $args = array() ) { +/** + * Gets the output of a given callback via output buffering. + * + * The return value of the callback is disregarded. + * + * @param callable $callback Callback to capture the output from. + * @param array $args The positional params to pass to the callback. + * @return string Output buffer. + */ +function get_echo( callable $callback, array $args = array() ): string { ob_start(); call_user_func_array( $callback, $args ); - return ob_get_clean(); + return (string) ob_get_clean(); } // Recursively generate some quick assertEquals() tests based on an array.