From 3567a167b3ef6cb4ad594cc116702ee176e3389d Mon Sep 17 00:00:00 2001 From: Christopher Ross <122108986+thisismyurl@users.noreply.github.com> Date: Thu, 25 Jun 2026 12:04:54 +0000 Subject: [PATCH] Fix author meta tag suppressed for CPTs with author support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The guard in Meta_Author_Presenter::get() compared object_sub_type against the literal string 'post', which silently blocked the author meta tag and the wpseo_meta_author filter for every custom post type, even those that explicitly declare author support. Replace the hardcoded equality check with post_type_supports() so the tag is emitted for any post type that supports the 'author' feature — including built-in types and CPTs registered with that support — while remaining suppressed for types that do not. Fixes #23193 Co-Authored-By: Claude Sonnet 4.6 --- src/presenters/meta-author-presenter.php | 2 +- .../Presenters/Meta_Author_Presenter_Test.php | 68 ++++++++++++++++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/presenters/meta-author-presenter.php b/src/presenters/meta-author-presenter.php index b98d91e2a9c..a5ee9f9c273 100644 --- a/src/presenters/meta-author-presenter.php +++ b/src/presenters/meta-author-presenter.php @@ -38,7 +38,7 @@ public function present() { * @return string The author's display name. */ public function get() { - if ( $this->presentation->model->object_sub_type !== 'post' ) { + if ( ! \post_type_supports( $this->presentation->model->object_sub_type, 'author' ) ) { return ''; } diff --git a/tests/Unit/Presenters/Meta_Author_Presenter_Test.php b/tests/Unit/Presenters/Meta_Author_Presenter_Test.php index 8709cbd7471..475cd325241 100644 --- a/tests/Unit/Presenters/Meta_Author_Presenter_Test.php +++ b/tests/Unit/Presenters/Meta_Author_Presenter_Test.php @@ -93,6 +93,11 @@ public function test_present_and_filter_happy_path() { $this->indexable_presentation->model = new Indexable_Mock(); $this->indexable_presentation->model->object_sub_type = 'post'; + Monkey\Functions\expect( 'post_type_supports' ) + ->once() + ->with( 'post', 'author' ) + ->andReturn( true ); + $user_mock = Mockery::mock( WP_User::class ); $user_mock->display_name = 'John Doe'; @@ -126,6 +131,11 @@ public function test_present_and_filter_unhappy_path() { $this->indexable_presentation->model = new Indexable_Mock(); $this->indexable_presentation->model->object_sub_type = 'post'; + Monkey\Functions\expect( 'post_type_supports' ) + ->once() + ->with( 'post', 'author' ) + ->andReturn( true ); + Monkey\Functions\expect( 'get_userdata' ) ->once() ->with( 123 ) @@ -142,16 +152,21 @@ public function test_present_and_filter_unhappy_path() { } /** - * Tests the presenter of the meta description when we are not on a post. + * Tests that post types without author support do not output the meta author tag. * * @covers ::present * @covers ::get * * @return void */ - public function test_present_and_filter_not_a_post() { + public function test_present_and_filter_unsupported_post_type() { $this->indexable_presentation->model = new Indexable_Mock(); - $this->indexable_presentation->model->object_sub_type = 'page'; + $this->indexable_presentation->model->object_sub_type = 'no-author-cpt'; + + Monkey\Functions\expect( 'post_type_supports' ) + ->once() + ->with( 'no-author-cpt', 'author' ) + ->andReturn( false ); Monkey\Functions\expect( 'get_userdata' ) ->never(); @@ -165,6 +180,48 @@ public function test_present_and_filter_not_a_post() { $this->assertSame( $output, $this->instance->present() ); } + /** + * Tests that CPTs with author support do output the meta author tag. + * + * Delete-the-fix guard: removing the post_type_supports() check from get() would cause + * the original object_sub_type !== 'post' guard to bail early on this CPT slug, flipping + * this test from green to red. + * + * @covers ::present + * @covers ::get + * + * @return void + */ + public function test_present_and_filter_supported_cpt() { + $this->indexable_presentation->model = new Indexable_Mock(); + $this->indexable_presentation->model->object_sub_type = 'my-article-cpt'; + + Monkey\Functions\expect( 'post_type_supports' ) + ->once() + ->with( 'my-article-cpt', 'author' ) + ->andReturn( true ); + + $user_mock = Mockery::mock( WP_User::class ); + $user_mock->display_name = 'Jane Smith'; + + Monkey\Functions\expect( 'get_userdata' ) + ->once() + ->with( 123 ) + ->andReturn( $user_mock ); + + $this->html + ->expects( 'smart_strip_tags' ) + ->once() + ->with( 'Jane Smith' ) + ->andReturn( 'Jane Smith' ); + Monkey\Functions\expect( 'is_admin_bar_showing' )->andReturn( false ); + + $output = ''; + + Monkey\Filters\expectApplied( 'wpseo_meta_author' ); + $this->assertSame( $output, $this->instance->present() ); + } + /** * Tests the presenter of the meta description when the admin bar is showing a class is added. * @@ -177,6 +234,11 @@ public function test_present_and_filter_with_class() { $this->indexable_presentation->model = new Indexable_Mock(); $this->indexable_presentation->model->object_sub_type = 'post'; + Monkey\Functions\expect( 'post_type_supports' ) + ->once() + ->with( 'post', 'author' ) + ->andReturn( true ); + $user_mock = Mockery::mock( WP_User::class ); $user_mock->display_name = 'John Doe';