Files
wpdev 59c9b698b7
Tests / PHP Lint (push) Successful in 5s
Tests / Unit Tests (push) Successful in 16s
Tests / Integration Tests (push) Successful in 20s
test: 加入 integration 測試套件(連真實 MariaDB)
從 wp-data-optimizer v3.4.6 移植 5 個 integration 測試檔,並新增
tests/integration/bootstrap.php(複用核心的 integration bootstrap,不重複
 與 WP stub)+ phpunit-integration.xml + CI integration job。
2026-07-31 09:56:48 +08:00

161 lines
4.8 KiB
PHP

<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
/**
* Integration tests for WPDO_Listing_Meta_Interceptor — PR-3 R-2 + P-C1 fixes.
*
* Verifies:
* 1. R-2: Interceptor SKIPS hook registration when hpct_listing_meta is missing
* (prevents the "wp_hpct_listing_meta doesn't exist" cascading errors that
* forced 2meet-infocards to bypass the interceptor in production).
* 2. P-C1: upsert_meta() uses 1 SQL round-trip via WPDO_DB::upsert().
*
* @covers WPDO_Listing_Meta_Interceptor
*/
class ListingMetaInterceptorTest extends TestCase {
/**
* R-2: When hpct_listing_meta table is missing, register_hooks() must skip
* gracefully and write a single explanatory error log entry.
*
* @runInSeparateProcess
*/
public function test_register_hooks_skips_when_table_missing(): void {
global $wpdb;
$wpdb->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' );
}
}