query(). */ public static string $last_query = ''; /** Arguments passed to $wpdb->delete(). */ public static array $last_delete = []; /** Return value for get_var mock. */ public static ?string $get_var_return = null; /** Return value for get_row mock. */ public static mixed $get_row_return = null; protected function setUp(): void { self::$last_query = ''; self::$last_delete = []; self::$get_var_return = null; self::$get_row_return = null; $this->setup_wpdb_mock(); } private function setup_wpdb_mock(): void { global $wpdb; $wpdb = new class { public string $prefix = 'wp_'; public function prepare( string $sql, ...$args ): string { $i = 0; return preg_replace_callback( '/%([sd])/', function ( $m ) use ( &$i, $args ) { $val = $args[ $i++ ] ?? ''; return $m[1] === 'd' ? (string) (int) $val : "'" . addslashes( (string) $val ) . "'"; }, $sql ); } public function get_var( string $sql ): ?string { return ZoneHotTest::$get_var_return; } public function get_row( string $sql, $output = OBJECT ) { return ZoneHotTest::$get_row_return; } public function get_results( string $sql, $output = OBJECT ): array { return []; } public function insert( string $table, array $data, $format = null ): int|false { return 1; } public function update( string $table, array $data, array $where, $format = null, $where_format = null ): int|false { return 1; } public function delete( string $table, array $where, $format = null ): int|false { ZoneHotTest::$last_delete = [ 'table' => $table, 'where' => $where ]; return 1; } public function query( string $sql ): int|bool { ZoneHotTest::$last_query = $sql; return 1; } }; } // ── table() ────────────────────────────────────────────────────────────── public function test_table_returns_prefixed_name(): void { $this->assertSame( 'wp_wpdo_hot_hp_listing', WPDO_Zone_Hot::table( 'hp_listing' ) ); } public function test_table_sanitizes_post_type(): void { // The test sanitize_key stub strips non-[a-z0-9_-] chars then lowercases. // 'HP Listing!' → strip uppercase H,P + space + '!' → 'isting' → lower → 'isting'. $sanitized = sanitize_key( 'HP Listing!' ); $this->assertSame( 'wp_wpdo_hot_' . $sanitized, WPDO_Zone_Hot::table( 'HP Listing!' ) ); } // ── get() ───────────────────────────────────────────────────────────────── public function test_get_returns_null_when_row_missing(): void { self::$get_var_return = null; $result = WPDO_Zone_Hot::get( 1, 'hp_listing', 'hp_price' ); $this->assertNull( $result ); } public function test_get_returns_value_from_db(): void { self::$get_var_return = '42'; $result = WPDO_Zone_Hot::get( 1, 'hp_listing', 'hp_price' ); $this->assertSame( '42', $result ); } // ── get_row() ──────────────────────────────────────────────────────────── public function test_get_row_returns_null_when_missing(): void { self::$get_row_return = null; $result = WPDO_Zone_Hot::get_row( 1, 'hp_listing' ); $this->assertNull( $result ); } public function test_get_row_returns_array(): void { $expected = [ 'post_id' => 1, 'hp_price' => '100', 'hp_location' => 'NYC' ]; self::$get_row_return = $expected; $result = WPDO_Zone_Hot::get_row( 1, 'hp_listing' ); $this->assertSame( $expected, $result ); } // ── set() ───────────────────────────────────────────────────────────────── public function test_set_executes_upsert_query(): void { WPDO_Zone_Hot::set( 5, 'hp_listing', 'hp_price', '99' ); $this->assertNotEmpty( self::$last_query, 'Expected $wpdb->query() to be called' ); $this->assertStringContainsString( 'ON DUPLICATE KEY UPDATE', self::$last_query ); } // ── set_many() ─────────────────────────────────────────────────────────── public function test_set_many_includes_all_columns_in_upsert(): void { WPDO_Zone_Hot::set_many( 7, 'hp_listing', [ 'hp_price' => '150', 'hp_location' => 'LA', 'hp_category' => '3', ] ); $this->assertNotEmpty( self::$last_query ); $this->assertStringContainsString( 'hp_price', self::$last_query ); $this->assertStringContainsString( 'hp_location', self::$last_query ); $this->assertStringContainsString( 'hp_category', self::$last_query ); } // ── delete() ───────────────────────────────────────────────────────────── public function test_delete_calls_wpdb_delete(): void { WPDO_Zone_Hot::delete( 42, 'hp_listing' ); $this->assertNotEmpty( self::$last_delete, 'Expected $wpdb->delete() to be called' ); $this->assertSame( 42, self::$last_delete['where']['post_id'] ); } public function test_delete_table_name_contains_post_type(): void { WPDO_Zone_Hot::delete( 5, 'hp_vendor' ); $this->assertStringContainsString( 'hp_vendor', self::$last_delete['table'] ); } // ── Additional edge cases ───────────────────────────────────────────────── public function test_table_for_different_post_type(): void { $this->assertSame( 'wp_wpdo_hot_hp_vendor', WPDO_Zone_Hot::table( 'hp_vendor' ) ); } }