Files
2meet-data-optimizer-hivepr…/tests/integration/TermCommentBackfillTest.php
T
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

248 lines
11 KiB
PHP

<?php
declare(strict_types=1);
use PHPUnit\Framework\TestCase;
/**
* Integration test: WPDO_Term_Comment_Backfill (v2.12.6 Phase 6).
*
* Verifies pivot-style backfill from wp_*meta to flat tables:
* - dry_run reports candidate count without writing
* - confirm path performs INSERT ... ON DUPLICATE KEY UPDATE
* - multi-key pivot collapses N rows per term into 1 flat row
* - idempotent re-run does not duplicate
* - empty DB returns zero counts
* - error returns for invalid group / missing registry
*/
class TermCommentBackfillTest extends TestCase {
private const TERMS = 'wp_itest_terms';
private const TERMMETA = 'wp_itest_termmeta';
private const COMMENTS = 'wp_itest_comments';
private const COMMENTMETA = 'wp_itest_commentmeta';
private const TERM_FLAT = 'wp_itest_wpdo_term_hp_taxonomy';
private const COMMENT_FLAT = 'wp_itest_wpdo_comment_hp_review';
public static function setUpBeforeClass(): void {
global $wpdb;
$wpdb->terms = self::TERMS;
$wpdb->termmeta = self::TERMMETA;
$wpdb->comments = self::COMMENTS;
$wpdb->commentmeta = self::COMMENTMETA;
WPDO_Entity_Registry::register_adapter( 'term', new WPDO_Adapter_Term() );
WPDO_Entity_Registry::register_adapter( 'comment', new WPDO_Adapter_Comment() );
WPDO_Hivepress_Term_Comment_Fields::register_entity_fields();
// Test tables.
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::TERMS . '`' );
$wpdb->query(
'CREATE TABLE `' . self::TERMS . '` (
term_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
name varchar(200) NOT NULL DEFAULT "",
PRIMARY KEY (term_id)
) DEFAULT CHARACTER SET utf8mb4'
);
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::COMMENTS . '`' );
$wpdb->query(
'CREATE TABLE `' . self::COMMENTS . '` (
comment_ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
comment_post_ID bigint(20) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (comment_ID)
) DEFAULT CHARACTER SET utf8mb4'
);
$wpdb->query( 'CREATE TABLE IF NOT EXISTS `' . self::TERMMETA . '` (
meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
term_id bigint(20) unsigned NOT NULL DEFAULT 0,
meta_key varchar(255) DEFAULT NULL,
meta_value longtext,
PRIMARY KEY (meta_id),
KEY term_id (term_id),
KEY meta_key (meta_key(191))
) DEFAULT CHARACTER SET utf8mb4' );
$wpdb->query( 'CREATE TABLE IF NOT EXISTS `' . self::COMMENTMETA . '` (
meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
comment_id bigint(20) unsigned NOT NULL DEFAULT 0,
meta_key varchar(255) DEFAULT NULL,
meta_value longtext,
PRIMARY KEY (meta_id),
KEY comment_id (comment_id),
KEY meta_key (meta_key(191))
) DEFAULT CHARACTER SET utf8mb4' );
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::TERM_FLAT . '`' );
$wpdb->query(
'CREATE TABLE `' . self::TERM_FLAT . '` (
term_id bigint(20) unsigned NOT NULL,
hp_sort_order int(11) DEFAULT NULL,
hp_default tinyint(1) DEFAULT NULL,
hp_icon varchar(64) DEFAULT NULL,
PRIMARY KEY (term_id)
) DEFAULT CHARACTER SET utf8mb4'
);
$wpdb->query( 'DROP TABLE IF EXISTS `' . self::COMMENT_FLAT . '`' );
$wpdb->query(
'CREATE TABLE `' . self::COMMENT_FLAT . '` (
comment_id bigint(20) unsigned NOT NULL,
hp_rating tinyint(1) DEFAULT NULL,
PRIMARY KEY (comment_id)
) DEFAULT CHARACTER SET utf8mb4'
);
}
public static function tearDownAfterClass(): void {
global $wpdb;
foreach ( array( self::TERMS, self::COMMENTS, self::TERM_FLAT, self::COMMENT_FLAT ) as $tbl ) {
$wpdb->query( 'DROP TABLE IF EXISTS `' . $tbl . '`' );
}
}
protected function setUp(): void {
global $wpdb;
$wpdb->query( 'TRUNCATE TABLE `' . self::TERMS . '`' );
$wpdb->query( 'TRUNCATE TABLE `' . self::COMMENTS . '`' );
$wpdb->query( 'TRUNCATE TABLE `' . self::TERMMETA . '`' );
$wpdb->query( 'TRUNCATE TABLE `' . self::COMMENTMETA . '`' );
$wpdb->query( 'TRUNCATE TABLE `' . self::TERM_FLAT . '`' );
$wpdb->query( 'TRUNCATE TABLE `' . self::COMMENT_FLAT . '`' );
}
// ── backfill_group ──────────────────────────────────────────────────────
public function test_backfill_returns_zero_counts_for_empty_db(): void {
$result = WPDO_Term_Comment_Backfill::backfill_group( 'term', 'hp_taxonomy', false );
$this->assertSame( 0, $result['candidates'] );
$this->assertSame( 0, $result['written'] );
}
public function test_dry_run_does_not_write(): void {
global $wpdb;
$wpdb->insert( self::TERMS, array( 'term_id' => 1, 'name' => 'a' ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'hp_sort_order', 'meta_value' => '5' ) );
$result = WPDO_Term_Comment_Backfill::backfill_group( 'term', 'hp_taxonomy', true );
$this->assertSame( 1, $result['candidates'] );
$this->assertSame( 0, $result['written'] );
$this->assertTrue( $result['dry_run'] );
$flat_count = (int) $wpdb->get_var( 'SELECT COUNT(*) FROM `' . self::TERM_FLAT . '`' );
$this->assertSame( 0, $flat_count, 'dry_run must not INSERT' );
}
public function test_backfill_pivots_multi_key_into_single_row(): void {
global $wpdb;
$wpdb->insert( self::TERMS, array( 'term_id' => 1, 'name' => 'a' ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'hp_sort_order', 'meta_value' => '5' ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'hp_default', 'meta_value' => '1' ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'hp_icon', 'meta_value' => 'fa-star' ) );
$result = WPDO_Term_Comment_Backfill::backfill_group( 'term', 'hp_taxonomy', false );
$this->assertSame( 1, $result['candidates'] );
$row = $wpdb->get_row( 'SELECT * FROM `' . self::TERM_FLAT . '` WHERE term_id = 1', ARRAY_A );
$this->assertNotNull( $row );
$this->assertSame( '5', (string) $row['hp_sort_order'] );
$this->assertSame( '1', (string) $row['hp_default'] );
$this->assertSame( 'fa-star', $row['hp_icon'] );
}
public function test_backfill_handles_multiple_terms(): void {
global $wpdb;
for ( $i = 1; $i <= 5; $i++ ) {
$wpdb->insert( self::TERMS, array( 'term_id' => $i, 'name' => 'term_' . $i ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => $i, 'meta_key' => 'hp_sort_order', 'meta_value' => $i * 10 ) );
}
$result = WPDO_Term_Comment_Backfill::backfill_group( 'term', 'hp_taxonomy', false );
$this->assertSame( 5, $result['candidates'] );
$count = (int) $wpdb->get_var( 'SELECT COUNT(*) FROM `' . self::TERM_FLAT . '`' );
$this->assertSame( 5, $count );
}
public function test_backfill_idempotent_on_re_run(): void {
global $wpdb;
$wpdb->insert( self::TERMS, array( 'term_id' => 1, 'name' => 'a' ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'hp_sort_order', 'meta_value' => '5' ) );
WPDO_Term_Comment_Backfill::backfill_group( 'term', 'hp_taxonomy', false );
WPDO_Term_Comment_Backfill::backfill_group( 'term', 'hp_taxonomy', false );
$count = (int) $wpdb->get_var( 'SELECT COUNT(*) FROM `' . self::TERM_FLAT . '`' );
$this->assertSame( 1, $count, 'Re-running must not duplicate (PRIMARY KEY enforces)' );
}
public function test_backfill_updates_existing_row_via_on_duplicate_key(): void {
global $wpdb;
$wpdb->insert( self::TERMS, array( 'term_id' => 1, 'name' => 'a' ) );
$wpdb->insert( self::TERM_FLAT, array( 'term_id' => 1, 'hp_sort_order' => 99 ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'hp_sort_order', 'meta_value' => '5' ) );
WPDO_Term_Comment_Backfill::backfill_group( 'term', 'hp_taxonomy', false );
$value = $wpdb->get_var( 'SELECT hp_sort_order FROM `' . self::TERM_FLAT . '` WHERE term_id = 1' );
$this->assertSame( '5', (string) $value, 'wp_termmeta value should overwrite stale flat value' );
}
public function test_backfill_handles_comment_entity(): void {
global $wpdb;
$wpdb->insert( self::COMMENTS, array( 'comment_ID' => 1, 'comment_post_ID' => 100 ) );
$wpdb->insert( self::COMMENTMETA, array( 'comment_id' => 1, 'meta_key' => 'hp_rating', 'meta_value' => '5' ) );
$result = WPDO_Term_Comment_Backfill::backfill_group( 'comment', 'hp_review', false );
$this->assertSame( 1, $result['candidates'] );
$value = $wpdb->get_var( 'SELECT hp_rating FROM `' . self::COMMENT_FLAT . '` WHERE comment_id = 1' );
$this->assertSame( '5', (string) $value );
}
public function test_backfill_only_picks_registered_keys(): void {
global $wpdb;
$wpdb->insert( self::TERMS, array( 'term_id' => 1, 'name' => 'a' ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'hp_sort_order', 'meta_value' => '5' ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'unknown_key', 'meta_value' => 'x' ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'note_group', 'meta_value' => 'foo' ) );
WPDO_Term_Comment_Backfill::backfill_group( 'term', 'hp_taxonomy', false );
// hp_icon and hp_default should be NULL (not in wp_termmeta).
$row = $wpdb->get_row( 'SELECT * FROM `' . self::TERM_FLAT . '` WHERE term_id = 1', ARRAY_A );
$this->assertSame( '5', (string) $row['hp_sort_order'] );
$this->assertNull( $row['hp_default'] );
$this->assertNull( $row['hp_icon'] );
}
public function test_backfill_unknown_group_returns_error(): void {
$result = WPDO_Term_Comment_Backfill::backfill_group( 'term', 'bogus_group', false );
$this->assertArrayHasKey( 'error', $result );
$this->assertSame( 0, $result['candidates'] );
}
public function test_backfill_unsupported_entity_returns_error(): void {
$result = WPDO_Term_Comment_Backfill::backfill_group( 'user', 'hp_taxonomy', false );
$this->assertArrayHasKey( 'error', $result );
}
// ── backfill_all ────────────────────────────────────────────────────────
public function test_backfill_all_runs_every_group(): void {
global $wpdb;
$wpdb->insert( self::TERMS, array( 'term_id' => 1, 'name' => 'a' ) );
$wpdb->insert( self::TERMMETA, array( 'term_id' => 1, 'meta_key' => 'hp_sort_order', 'meta_value' => '5' ) );
$wpdb->insert( self::COMMENTS, array( 'comment_ID' => 1, 'comment_post_ID' => 100 ) );
$wpdb->insert( self::COMMENTMETA, array( 'comment_id' => 1, 'meta_key' => 'hp_rating', 'meta_value' => '5' ) );
$results = WPDO_Term_Comment_Backfill::backfill_all( false );
$this->assertCount( 2, $results );
$this->assertArrayHasKey( 'hp_taxonomy', $results );
$this->assertArrayHasKey( 'hp_review', $results );
$this->assertSame( 1, $results['hp_taxonomy']['candidates'] );
$this->assertSame( 1, $results['hp_review']['candidates'] );
}
}