query( "DROP TABLE IF EXISTS `{$wpdb->prefix}hpct_listing_meta`" ); // Simulate HPCT_Core being present — register_hooks() only logs the skip // when HPCT is loaded but its table is missing (genuine inconsistency). if ( ! class_exists( 'HPCT_Core' ) ) { // phpcs:ignore Generic.Commenting.InlineComment.InvalidEndChar -- runtime stub eval( 'class HPCT_Core {}' ); // @phpcs:ignore } // Ensure wpdo_errors exists for the skip log; harmless if pre-created. $wpdb->query( "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}wpdo_errors` ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, module varchar(50) NOT NULL DEFAULT '', zone varchar(10) NOT NULL DEFAULT '', hook varchar(255) NOT NULL DEFAULT '', message longtext NOT NULL, context longtext, created_at datetime NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (id), KEY idx_module (module) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" ); // Snapshot pre-call count of skip messages. $pre = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->prefix}wpdo_errors` WHERE module = %s AND hook = %s", 'listing_meta', 'register_hooks' ) ); $interceptor = new WPDO_Listing_Meta_Interceptor(); $interceptor->register_hooks(); $post = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM `{$wpdb->prefix}wpdo_errors` WHERE module = %s AND hook = %s", 'listing_meta', 'register_hooks' ) ); $this->assertSame( $pre + 1, $post, 'Expected exactly one new skip message after register_hooks()' ); } /** * P-C1: WPDO_DB::upsert() must produce an INSERT ... ON DUPLICATE KEY UPDATE * statement (single round-trip), and writes must succeed via the composite * unique key (listing_id, meta_key). * * @runInSeparateProcess */ public function test_upsert_uses_composite_unique_key(): void { global $wpdb; $table = $wpdb->prefix . 'hpct_listing_meta'; // Clean slate. $wpdb->query( "DROP TABLE IF EXISTS `{$table}`" ); $wpdb->query( "CREATE TABLE `{$table}` ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT, listing_id bigint(20) unsigned NOT NULL DEFAULT 0, meta_key varchar(255) NOT NULL DEFAULT '', meta_value longtext, PRIMARY KEY (id), UNIQUE KEY ui_listing_meta (listing_id, meta_key(191)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" ); // First upsert: INSERT. $result1 = WPDO_DB::upsert( $table, array( 'listing_id' => 4242, 'meta_key' => 'hp_price', 'meta_value' => '100.00', ), array( 'meta_value' ), array( 'listing_id', 'meta_key' ), array( '%d', '%s', '%s' ) ); $this->assertNotFalse( $result1 ); // Second upsert: UPDATE via the composite key. $result2 = WPDO_DB::upsert( $table, array( 'listing_id' => 4242, 'meta_key' => 'hp_price', 'meta_value' => '250.50', ), array( 'meta_value' ), array( 'listing_id', 'meta_key' ), array( '%d', '%s', '%s' ) ); $this->assertNotFalse( $result2 ); // Verify only one row exists for (4242, 'hp_price') with the latest value. $rows = $wpdb->get_results( $wpdb->prepare( "SELECT meta_value FROM `{$table}` WHERE listing_id = %d AND meta_key = %s", 4242, 'hp_price' ), ARRAY_A ); $this->assertCount( 1, $rows, 'Composite UNIQUE must collapse two upserts into a single row' ); $this->assertSame( '250.50', $rows[0]['meta_value'] ); // Cleanup. $wpdb->query( "DROP TABLE IF EXISTS `{$table}`" ); } /** * Verify table_exists() returns false when table missing, true after CREATE. * * @runInSeparateProcess */ public function test_table_exists_detection(): void { global $wpdb; $wpdb->query( "DROP TABLE IF EXISTS `{$wpdb->prefix}hpct_listing_meta`" ); // Use reflection to invoke private static. $ref = new ReflectionClass( WPDO_Listing_Meta_Interceptor::class ); $method = $ref->getMethod( 'table_exists' ); $method->setAccessible( true ); $this->assertFalse( $method->invoke( null ), 'table_exists must return false when table missing' ); } }