getProperty( 'cache' ); $cache->setAccessible( true ); $cache->setValue( null, null ); WPDO_Entity_Registry::init(); } private function set_post_mode( string $mode ): void { $ref = new ReflectionClass( WPDO_Mode_Manager::class ); $cache = $ref->getProperty( 'cache' ); $cache->setAccessible( true ); $cache->setValue( null, array( 'post' => $mode, 'user' => 'aeav_only', 'term' => 'dual_write', 'comment' => 'dual_write', ) ); } private function make_query( array $vars ): WP_Query { $q = new WP_Query(); foreach ( $vars as $k => $v ) { $q->set( $k, $v ); } return $q; } // ── pre_get_posts gate (mode-aware) ─────────────────────────────────────── public function test_pass_through_when_mode_disabled(): void { $this->set_post_mode( 'disabled' ); $router = new WPDO_Post_Query_Router(); $query = $this->make_query( array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => '_price', 'value' => '50', 'compare' => '>=' ), ), ) ); $original = $query->get( 'meta_query' ); $router->pre_get_posts( $query ); $this->assertSame( $original, $query->get( 'meta_query' ), 'mode=disabled: meta_query must be untouched.' ); $this->assertSame( '', $query->get( 'wpdo_post_clauses' ) ); } public function test_pass_through_when_mode_dual_write(): void { $this->set_post_mode( 'dual_write' ); $router = new WPDO_Post_Query_Router(); $query = $this->make_query( array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => '_price', 'value' => '50', 'compare' => '>=' ), ), ) ); $original = $query->get( 'meta_query' ); $router->pre_get_posts( $query ); $this->assertSame( $original, $query->get( 'meta_query' ), 'mode=dual_write: wp_postmeta is still source-of-truth, no rewrite.' ); } // ── pre_get_posts rewrite (mode=aeav_only) ─────────────────────────────── public function test_rewrites_meta_query_when_mode_aeav_only(): void { $this->set_post_mode( 'aeav_only' ); $router = new WPDO_Post_Query_Router(); $query = $this->make_query( array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => '_price', 'value' => '50', 'compare' => '>=' ), ), ) ); $router->pre_get_posts( $query ); // Original meta_query stripped of registered keys. $remaining = $query->get( 'meta_query' ); $this->assertEmpty( $remaining, 'aeav_only: registered keys removed from meta_query.' ); // Routed clauses captured under wpdo_post_clauses query var. $routed = $query->get( 'wpdo_post_clauses' ); $this->assertIsArray( $routed ); $this->assertNotEmpty( $routed ); } public function test_keeps_unmanaged_keys_in_meta_query(): void { $this->set_post_mode( 'aeav_only' ); $router = new WPDO_Post_Query_Router(); $query = $this->make_query( array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => '_price', 'value' => '50', 'compare' => '>=' ), array( 'key' => 'unmanaged_attr', 'value' => 'x' ), ), ) ); $router->pre_get_posts( $query ); $remaining = $query->get( 'meta_query' ); $this->assertCount( 1, $remaining ); // Original index preserved (k=1 since k=0 was the routed _price clause). $first_clause = reset( $remaining ); $this->assertSame( 'unmanaged_attr', $first_clause['key'], 'Unmanaged key remains in meta_query (Hook Bus pass-through).' ); } public function test_skips_admin_requests(): void { $this->set_post_mode( 'aeav_only' ); $prev_admin = $GLOBALS['_wp_is_admin'] ?? false; $GLOBALS['_wp_is_admin'] = true; $router = new WPDO_Post_Query_Router(); $query = $this->make_query( array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => '_price', 'value' => '50', 'compare' => '>=' ), ), ) ); $original = $query->get( 'meta_query' ); $router->pre_get_posts( $query ); $this->assertSame( $original, $query->get( 'meta_query' ), 'is_admin requests should not be rewritten.' ); $GLOBALS['_wp_is_admin'] = $prev_admin; } // ── posts_join / posts_where (SQL emission) ────────────────────────────── public function test_posts_join_emits_left_join_for_each_routed_post_type(): void { $this->set_post_mode( 'aeav_only' ); $router = new WPDO_Post_Query_Router(); $query = $this->make_query( array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => '_price', 'value' => '50' ), ), 'wpdo_post_clauses' => array(), ) ); $router->pre_get_posts( $query ); $join = $router->posts_join( '', $query ); $this->assertStringContainsString( 'LEFT JOIN', $join ); $this->assertStringContainsString( 'wpdo_post_wc_product', $join ); } public function test_posts_where_appends_condition_for_routed_clause(): void { $this->set_post_mode( 'aeav_only' ); $router = new WPDO_Post_Query_Router(); $query = $this->make_query( array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => '_price', 'value' => '99', 'compare' => '=' ), ), ) ); $router->pre_get_posts( $query ); $where = $router->posts_where( '', $query ); $this->assertStringContainsString( '`_price`', $where ); $this->assertStringContainsString( "'99'", $where ); } public function test_pass_through_when_no_meta_query(): void { $this->set_post_mode( 'aeav_only' ); $router = new WPDO_Post_Query_Router(); $query = $this->make_query( array( 'post_type' => 'product' ) ); $router->pre_get_posts( $query ); $this->assertSame( '', $query->get( 'wpdo_post_clauses' ) ); } }