59c9b698b7
從 wp-data-optimizer v3.4.6 移植 5 個 integration 測試檔,並新增 tests/integration/bootstrap.php(複用核心的 integration bootstrap,不重複 與 WP stub)+ phpunit-integration.xml + CI integration job。
248 lines
11 KiB
PHP
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'] );
|
|
}
|
|
}
|