fc0f018a94
- install() no longer switches the Hook Bus on or puts user/term/comment into dual_write; the now-unused maybe_autoactivate_entity_bridge() is gone - Hook Bus and Mode_Manager defaults are off/disabled; sites with stored modes (incl. aeav_only) keep them since only unset keys use defaults - Guard run_dbdelta()'s upgrade.php require like install_v2_tables() so install() can run under the integration test stub Verify: InstallerV2Test::test_install_does_not_enable_entity_bridge, ModeManagerDefaultsTest; unit 602 OK, integration 421 OK PR: PR-007
132 lines
4.6 KiB
PHP
132 lines
4.6 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
/**
|
|
* Integration test for WPDO_Installer::install_v2_tables() — PR-2 v2.0.0 schema.
|
|
*
|
|
* Verifies idempotent table creation for:
|
|
* - wp_*_wpdo_audit
|
|
* - wp_*_wpdo_shadow_diffs
|
|
* - wp_*_wpdo_site_metrics
|
|
* - wp_*_wpdo_uni_options
|
|
*
|
|
* @covers WPDO_Installer::install_v2_tables
|
|
* @covers WPDO_Installer::v2_tables_status
|
|
*/
|
|
class InstallerV2Test extends TestCase {
|
|
|
|
public static function setUpBeforeClass(): void {
|
|
// Drop v2 tables for a clean slate.
|
|
global $wpdb;
|
|
$p = $wpdb->prefix;
|
|
$wpdb->query( "DROP TABLE IF EXISTS `{$p}wpdo_audit`" );
|
|
$wpdb->query( "DROP TABLE IF EXISTS `{$p}wpdo_shadow_diffs`" );
|
|
$wpdb->query( "DROP TABLE IF EXISTS `{$p}wpdo_site_metrics`" );
|
|
$wpdb->query( "DROP TABLE IF EXISTS `{$p}wpdo_uni_options`" );
|
|
}
|
|
|
|
public function test_v2_tables_initially_absent(): void {
|
|
$status = WPDO_Installer::v2_tables_status();
|
|
foreach ( $status as $table => $exists ) {
|
|
$this->assertFalse( $exists, "Expected {$table} to NOT exist initially" );
|
|
}
|
|
}
|
|
|
|
public function test_install_v2_tables_creates_all_four(): void {
|
|
WPDO_Installer::install_v2_tables();
|
|
|
|
$status = WPDO_Installer::v2_tables_status();
|
|
foreach ( $status as $table => $exists ) {
|
|
$this->assertTrue( $exists, "Expected {$table} to exist after install_v2_tables()" );
|
|
}
|
|
}
|
|
|
|
public function test_install_v2_tables_is_idempotent(): void {
|
|
WPDO_Installer::install_v2_tables();
|
|
WPDO_Installer::install_v2_tables(); // Second call must not error.
|
|
WPDO_Installer::install_v2_tables(); // Third for good measure.
|
|
|
|
$status = WPDO_Installer::v2_tables_status();
|
|
$this->assertCount( 4, $status );
|
|
$this->assertTrue( array_reduce( $status, static fn( $carry, $v ) => $carry && $v, true ) );
|
|
}
|
|
|
|
public function test_audit_table_has_required_columns(): void {
|
|
global $wpdb;
|
|
$p = $wpdb->prefix;
|
|
$cols = $wpdb->get_col( "SHOW COLUMNS FROM `{$p}wpdo_audit`" );
|
|
|
|
// PR-2 spec: op, value_before, value_after, source, trace_id are required.
|
|
foreach ( array( 'op', 'value_before', 'value_after', 'source', 'trace_id' ) as $required ) {
|
|
$this->assertContains( $required, $cols, "wpdo_audit missing column {$required}" );
|
|
}
|
|
}
|
|
|
|
public function test_shadow_diffs_table_has_required_columns(): void {
|
|
global $wpdb;
|
|
$p = $wpdb->prefix;
|
|
$cols = $wpdb->get_col( "SHOW COLUMNS FROM `{$p}wpdo_shadow_diffs`" );
|
|
|
|
foreach ( array( 'entity_type', 'entity_id', 'meta_key', 'postmeta_value', 'zone_value', 'diff_hash' ) as $required ) {
|
|
$this->assertContains( $required, $cols, "wpdo_shadow_diffs missing column {$required}" );
|
|
}
|
|
}
|
|
|
|
public function test_uni_options_has_unique_index_on_option_name(): void {
|
|
global $wpdb;
|
|
$p = $wpdb->prefix;
|
|
$indexes = $wpdb->get_results(
|
|
$wpdb->prepare(
|
|
'SELECT INDEX_NAME, COLUMN_NAME, NON_UNIQUE FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s',
|
|
$p . 'wpdo_uni_options'
|
|
),
|
|
ARRAY_A
|
|
);
|
|
|
|
$found_unique = false;
|
|
foreach ( $indexes as $idx ) {
|
|
if ( 'option_name' === $idx['COLUMN_NAME'] && '0' === (string) $idx['NON_UNIQUE'] ) {
|
|
$found_unique = true;
|
|
break;
|
|
}
|
|
}
|
|
$this->assertTrue( $found_unique, 'Expected UNIQUE index on wpdo_uni_options.option_name' );
|
|
}
|
|
|
|
public function test_audit_table_indexes_for_query_performance(): void {
|
|
global $wpdb;
|
|
$p = $wpdb->prefix;
|
|
$indexes = $wpdb->get_col(
|
|
$wpdb->prepare(
|
|
'SELECT DISTINCT INDEX_NAME FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s',
|
|
$p . 'wpdo_audit'
|
|
)
|
|
);
|
|
|
|
// Performance-critical indexes per Part F.3 schema spec.
|
|
foreach ( array( 'idx_entity', 'idx_meta_key', 'idx_ts', 'idx_trace' ) as $required ) {
|
|
$this->assertContains( $required, $indexes, "wpdo_audit missing index {$required}" );
|
|
}
|
|
}
|
|
|
|
public function test_install_does_not_enable_entity_bridge(): void {
|
|
delete_option( 'wpdo_hook_bus_enabled' );
|
|
delete_option( 'wpdo_bridge_modes' );
|
|
delete_option( 'wpdo_entity_bridge_autoactivated_v2' );
|
|
// Skip the crypto step: it queries $wpdb->options, which InstallerCleanupTest leaves pointing at its own prefix.
|
|
update_option( 'wpdo_crypto_migrated_v2', '1' );
|
|
|
|
TMDO_Installer::install();
|
|
|
|
$this->assertFalse( get_option( 'wpdo_hook_bus_enabled' ), 'install() must not switch the Hook Bus on' );
|
|
$this->assertFalse( get_option( 'wpdo_bridge_modes' ), 'install() must not write bridge modes' );
|
|
}
|
|
|
|
public static function tearDownAfterClass(): void {
|
|
// Leave v2 tables in place for subsequent tests / dev convenience.
|
|
// Cleanup happens via wp wpdo cleanup-uae-tables --confirm in real upgrades.
|
|
}
|
|
}
|