From 29a334b1ed701db0ececf7a8db921683bafec36b Mon Sep 17 00:00:00 2001 From: peptiderepo <273788462+peptiderepo@users.noreply.github.com> Date: Fri, 12 Jun 2026 14:08:36 +0700 Subject: [PATCH] test: fix BoardDataProviderTest WP_Query/WP_Post stub incompatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Functions\when('WP_Query') cannot intercept 'new WP_Query()' class instantiation — Brain\Monkey only patches global functions, not constructor calls. The board data provider's instanceof WP_Post check also filtered out all stdClass mocks. Fix: - Add WP_Query:: static FIFO to bootstrap so tests can inject WP_Post arrays per-test without Brain\Monkey. - Add WP_Post stub class to bootstrap (safe: not a function, no Patchwork conflict). - Update BoardDataProviderTest to use WP_Post instances + queue instead of Functions\when('WP_Query'). Agent-Session: phase2-admin-m1-engineer --- tests/bootstrap.php | 46 ++++++++++++++++++++-- tests/unit/Admin/BoardDataProviderTest.php | 40 +++++++++---------- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 3de8303..c4d1b67 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -103,12 +103,17 @@ if ( ! defined( 'OBJECT' ) ) { /** * Minimal WP_Query stub for unit tests. * - * IdeaScorer uses WP_Query to check for existing posts. - * This stub returns empty results by default. + * IdeaScorer uses WP_Query to check for existing posts with empty results. + * Board data provider tests inject posts via WP_Query::$_test_posts_queue + * (static FIFO): push arrays of WP_Post objects before instantiating the + * provider, and each new WP_Query() call will dequeue one batch. */ if ( ! class_exists( 'WP_Query' ) ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound class WP_Query { + /** @var array FIFO queue of post-arrays for tests. */ + public static $_test_posts_queue = []; + /** @var array */ public $posts = []; /** @var int */ @@ -117,7 +122,11 @@ if ( ! class_exists( 'WP_Query' ) ) { public $have_posts = false; public function __construct( $args = [] ) { - // No-op for testing — returns no posts. + if ( ! empty( self::$_test_posts_queue ) ) { + $this->posts = array_shift( self::$_test_posts_queue ); + $this->found_posts = count( $this->posts ); + $this->have_posts = $this->found_posts > 0; + } } public function have_posts(): bool { @@ -165,3 +174,34 @@ if ( ! class_exists( 'WP_Error' ) ) { } } } + +/** + * Minimal WP_Post stub for unit tests. + * + * Board data provider tests return WP_Post instances from WP_Query. + * Class defined here so instanceof checks in production code work correctly. + */ +if ( ! class_exists( 'WP_Post' ) ) { + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound + class WP_Post { + /** @var int */ + public $ID = 0; + /** @var string */ + public $post_title = ''; + /** @var string */ + public $post_status = 'publish'; + /** @var string */ + public $post_date_gmt = ''; + /** @var string */ + public $post_modified_gmt = ''; + + /** + * @param array $data + */ + public function __construct( array $data = [] ) { + foreach ( $data as $key => $value ) { + $this->$key = $value; + } + } + } +} diff --git a/tests/unit/Admin/BoardDataProviderTest.php b/tests/unit/Admin/BoardDataProviderTest.php index ecb49b0..8adc485 100644 --- a/tests/unit/Admin/BoardDataProviderTest.php +++ b/tests/unit/Admin/BoardDataProviderTest.php @@ -25,6 +25,9 @@ class BoardDataProviderTest extends BaseTestCase { $this->wpdb = $this->create_mock_wpdb(); $GLOBALS['wpdb'] = $this->wpdb; + // Reset WP_Query test queue before each test. + \WP_Query::$_test_posts_queue = []; + Functions\when( 'get_option' )->alias( function ( string $name, $default = false ) { $map = array( @@ -38,9 +41,6 @@ class BoardDataProviderTest extends BaseTestCase { // Transient stub: by default no active run. Functions\when( 'get_transient' )->justReturn( false ); - // WP_Query stub: return empty by default; individual tests override. - Functions\when( 'WP_Query' )->justReturn( (object) array( 'posts' => array() ) ); - // Admin URL stub. Functions\when( 'admin_url' )->alias( function ( string $path = '' ) { @@ -55,6 +55,7 @@ class BoardDataProviderTest extends BaseTestCase { } protected function tearDown(): void { + \WP_Query::$_test_posts_queue = []; unset( $GLOBALS['wpdb'] ); parent::tearDown(); } @@ -139,15 +140,14 @@ class BoardDataProviderTest extends BaseTestCase { * Draft posts with the _prautoblogger_generated meta appear in In Review. */ public function test_in_review_cards_from_draft_posts(): void { - $post = new \stdClass(); - $post->ID = 42; - $post->post_title = 'Test Draft Post'; - $post->post_date_gmt = '2026-06-12 10:00:00'; + $post = new \WP_Post(); + $post->ID = 42; + $post->post_title = 'Test Draft Post'; + $post->post_date_gmt = '2026-06-12 10:00:00'; + $post->post_status = 'draft'; - // WP_Query returns our fake post. - Functions\when( 'WP_Query' )->justReturn( - (object) array( 'posts' => array( $post ) ) - ); + // Inject post into WP_Query queue: first WP_Query() call returns this post. + \WP_Query::$_test_posts_queue[] = array( $post ); Functions\when( 'get_post_meta' )->alias( function ( $post_id, $key, $single ) use ( $post ) { @@ -183,14 +183,14 @@ class BoardDataProviderTest extends BaseTestCase { * Published posts within the window appear in Published. */ public function test_published_cards_within_window(): void { - $post = new \stdClass(); - $post->ID = 77; - $post->post_title = 'Published Article'; - $post->post_date_gmt = gmdate( 'Y-m-d H:i:s', time() - DAY_IN_SECONDS ); + $post = new \WP_Post(); + $post->ID = 77; + $post->post_title = 'Published Article'; + $post->post_date_gmt = gmdate( 'Y-m-d H:i:s', time() - DAY_IN_SECONDS ); + $post->post_status = 'publish'; - Functions\when( 'WP_Query' )->justReturn( - (object) array( 'posts' => array( $post ) ) - ); + // Inject post into WP_Query queue: first WP_Query() call returns this post. + \WP_Query::$_test_posts_queue[] = array( $post ); Functions\when( 'get_post_meta' )->alias( function ( $post_id, $key, $single ) use ( $post ) { @@ -269,8 +269,6 @@ class BoardDataProviderTest extends BaseTestCase { $this->wpdb->method( 'prepare' )->willReturn( 'SELECT 1' ); $this->wpdb->method( 'get_results' )->willReturn( array() ); - Functions\when( 'WP_Query' )->justReturn( (object) array( 'posts' => array() ) ); - $provider = new \PRAutoBlogger_Board_Data_Provider(); $snapshot = $provider->get_board_snapshot(); @@ -286,8 +284,6 @@ class BoardDataProviderTest extends BaseTestCase { $this->wpdb->method( 'prepare' )->willReturn( 'SELECT 1' ); $this->wpdb->method( 'get_results' )->willReturn( array() ); - Functions\when( 'WP_Query' )->justReturn( (object) array( 'posts' => array() ) ); - $provider = new \PRAutoBlogger_Board_Data_Provider(); $snapshot = $provider->get_board_snapshot();