query( 'CREATE TABLE IF NOT EXISTS `' . self::TERM_MISC . '` ( term_id bigint(20) unsigned NOT NULL, meta_key varchar(191) NOT NULL, meta_value longtext, updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (term_id, meta_key) ) DEFAULT CHARACTER SET utf8mb4' ); } protected function setUp(): void { global $wpdb; $wpdb->prefix = 'wp_itest_'; $wpdb->options = 'wp_itest_options'; $wpdb->query( 'TRUNCATE TABLE `' . self::TERM_MISC . '`' ); delete_option( 'wpdo_bridge_modes' ); delete_option( 'wpdo_features' ); } public function test_clean_site_has_no_blockers(): void { $this->assertSame( array(), TMDO_Installer::uninstall_blockers() ); } public function test_aeav_only_mode_blocks(): void { update_option( 'wpdo_bridge_modes', array( 'post' => 'aeav_only', 'user' => 'dual_write' ) ); $blockers = TMDO_Installer::uninstall_blockers(); $this->assertCount( 1, $blockers ); $this->assertStringContainsString( 'post', $blockers[0] ); } public function test_modes_that_still_write_native_do_not_block(): void { update_option( 'wpdo_bridge_modes', array( 'user' => 'dual_write', 'term' => 'shadow_read', 'comment' => 'disabled' ) ); $this->assertSame( array(), TMDO_Installer::uninstall_blockers() ); } public function test_misc_rows_block(): void { global $wpdb; $wpdb->query( 'INSERT INTO `' . self::TERM_MISC . "` (term_id, meta_key, meta_value) VALUES (1, 'k', 'v')" ); $blockers = TMDO_Installer::uninstall_blockers(); $this->assertCount( 1, $blockers ); $this->assertStringContainsString( 'wpdo_term_misc', $blockers[0] ); } public function test_zone_module_past_cutover_blocks(): void { update_option( 'wpdo_features', array( 'hot_hp_listing' => 'complete', 'cold_hp_vendor' => 'cleanup', 'warm' => 'cutover' ) ); $blockers = TMDO_Installer::uninstall_blockers(); $this->assertCount( 2, $blockers ); $this->assertStringContainsString( 'hot_hp_listing', implode( ' ', $blockers ) ); $this->assertStringContainsString( 'cold_hp_vendor', implode( ' ', $blockers ) ); } public function test_hpct_module_complete_does_not_block(): void { // HPCT modules live in hpct_* tables, which uninstall never drops. update_option( 'wpdo_features', array( 'reviews' => 'complete' ) ); $this->assertSame( array(), TMDO_Installer::uninstall_blockers() ); } public function test_uninstall_script_refuses_and_keeps_data(): void { global $wpdb; update_option( 'wpdo_bridge_modes', array( 'post' => 'aeav_only' ) ); if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) { define( 'WP_UNINSTALL_PLUGIN', '2meet-data-optimizer/2meet-data-optimizer.php' ); } try { require TMDO_PATH . 'uninstall.php'; $this->fail( 'uninstall.php should have stopped with wp_die()' ); } catch ( RuntimeException $e ) { $this->assertStringContainsString( 'aeav_only', $e->getMessage() ); } $this->assertSame( array( 'post' => 'aeav_only' ), get_option( 'wpdo_bridge_modes' ) ); $this->assertSame( self::TERM_MISC, $wpdb->get_var( "SHOW TABLES LIKE '" . self::TERM_MISC . "'" ) ); } public function test_uninstall_script_checks_every_site_on_multisite(): void { update_option( 'wpdo_bridge_modes', array( 'user' => 'aeav_only' ) ); if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) { define( 'WP_UNINSTALL_PLUGIN', '2meet-data-optimizer/2meet-data-optimizer.php' ); } $GLOBALS['_wp_is_multisite'] = true; $GLOBALS['_wp_sites'] = array( 1, 3 ); try { require TMDO_PATH . 'uninstall.php'; $this->fail( 'uninstall.php should have stopped with wp_die()' ); } catch ( RuntimeException $e ) { $this->assertStringContainsString( '站台 #1', $e->getMessage() ); $this->assertStringContainsString( '站台 #3', $e->getMessage() ); } finally { unset( $GLOBALS['_wp_is_multisite'], $GLOBALS['_wp_sites'] ); } } }