markTestSkipped('WordPress not loaded - skipping integration tests'); return; } $this->wpdb = $wpdb; $this->prefix = $wpdb->prefix; $this->migrator = new DatabaseMigrator($wpdb); // Limpiar tablas anteriores $this->cleanupTables(); // Crear tablas legacy con datos de prueba $this->createLegacyTables(); $this->seedLegacyData(); } /** * Teardown después de cada test */ protected function tearDown(): void { $this->cleanupTables(); } /** * Test: La migración crea tablas v2 correctamente * * @test */ public function it_creates_v2_tables(): void { $result = $this->migrator->migrate(); $this->assertTrue($result['success'], $result['message']); // Verificar que tabla components existe $components_table = $this->prefix . 'roi_theme_components'; $table_exists = $this->wpdb->get_var( "SHOW TABLES LIKE '{$components_table}'" ) === $components_table; $this->assertTrue($table_exists, 'Tabla components no existe después de migración'); // Verificar que tabla defaults existe $defaults_table = $this->prefix . 'roi_theme_components_defaults'; $table_exists = $this->wpdb->get_var( "SHOW TABLES LIKE '{$defaults_table}'" ) === $defaults_table; $this->assertTrue($table_exists, 'Tabla defaults no existe después de migración'); } /** * Test: La migración preserva la cantidad de registros * * @test */ public function it_preserves_record_count(): void { // Contar antes de migración $legacy_count = $this->wpdb->get_var( "SELECT COUNT(*) FROM {$this->prefix}roi_theme_components" ); // Ejecutar migración $result = $this->migrator->migrate(); $this->assertTrue($result['success']); // Contar después de migración $v2_count = $this->wpdb->get_var( "SELECT COUNT(*) FROM {$this->prefix}roi_theme_components" ); $this->assertEquals( $legacy_count, $v2_count, "Cantidad de registros no coincide: legacy={$legacy_count}, v2={$v2_count}" ); } /** * Test: La migración infiere grupos correctamente * * @test */ public function it_infers_config_groups_correctly(): void { $result = $this->migrator->migrate(); $this->assertTrue($result['success']); // Verificar que "enabled" se migró a grupo "visibility" $group = $this->wpdb->get_var( "SELECT config_group FROM {$this->prefix}roi_theme_components WHERE config_key = 'enabled' LIMIT 1" ); $this->assertEquals('visibility', $group); // Verificar que "message_text" se migró a grupo "content" $group = $this->wpdb->get_var( "SELECT config_group FROM {$this->prefix}roi_theme_components WHERE config_key = 'message_text' LIMIT 1" ); $this->assertEquals('content', $group); // Verificar que "background_color" se migró a grupo "styles" $group = $this->wpdb->get_var( "SELECT config_group FROM {$this->prefix}roi_theme_components WHERE config_key = 'background_color' LIMIT 1" ); $this->assertEquals('styles', $group); } /** * Test: La migración crea backup de tablas legacy * * @test */ public function it_creates_backup_tables(): void { $result = $this->migrator->migrate(); $this->assertTrue($result['success']); // Verificar que tabla backup existe $backup_table = $this->prefix . 'roi_theme_components_backup'; $table_exists = $this->wpdb->get_var( "SHOW TABLES LIKE '{$backup_table}'" ) === $backup_table; $this->assertTrue($table_exists, 'Tabla backup no fue creada'); // Verificar que backup tiene datos $backup_count = $this->wpdb->get_var( "SELECT COUNT(*) FROM {$backup_table}" ); $this->assertGreaterThan(0, $backup_count, 'Tabla backup está vacía'); } /** * Test: Rollback elimina tablas v2 en caso de error * * @test */ public function it_rolls_back_on_error(): void { // Crear escenario de error: tabla legacy vacía después de crear v2 $this->wpdb->query("DELETE FROM {$this->prefix}roi_theme_components"); $result = $this->migrator->migrate(); // La migración debe fallar por mismatch de conteo $this->assertFalse($result['success']); // Verificar que tablas v2 fueron eliminadas $v2_table = $this->prefix . 'roi_theme_components_v2'; $table_exists = $this->wpdb->get_var( "SHOW TABLES LIKE '{$v2_table}'" ) === $v2_table; $this->assertFalse($table_exists, 'Tabla v2 no fue eliminada en rollback'); } /** * Test: cleanup_backup elimina tablas de respaldo * * @test */ public function it_removes_backup_tables(): void { // Ejecutar migración $result = $this->migrator->migrate(); $this->assertTrue($result['success']); // Verificar que backup existe $backup_table = $this->prefix . 'roi_theme_components_backup'; $table_exists = $this->wpdb->get_var( "SHOW TABLES LIKE '{$backup_table}'" ) === $backup_table; $this->assertTrue($table_exists); // Ejecutar cleanup $this->migrator->cleanupBackup(); // Verificar que backup fue eliminado $table_exists = $this->wpdb->get_var( "SHOW TABLES LIKE '{$backup_table}'" ) === $backup_table; $this->assertFalse($table_exists, 'Tabla backup no fue eliminada'); } /** * Helper: Crear tablas legacy para testing */ private function createLegacyTables(): void { if (!defined('ABSPATH')) { return; } require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); $charset_collate = $this->wpdb->get_charset_collate(); $components_sql = "CREATE TABLE {$this->prefix}roi_theme_components ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, component_name VARCHAR(50) NOT NULL, config_key VARCHAR(100) NOT NULL, config_value TEXT NOT NULL, data_type VARCHAR(20) NOT NULL DEFAULT 'string', version VARCHAR(10) NOT NULL DEFAULT '1.0.0', created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY component_config (component_name, config_key) ) {$charset_collate};"; $defaults_sql = "CREATE TABLE {$this->prefix}roi_theme_components_defaults ( id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, component_name VARCHAR(50) NOT NULL, config_key VARCHAR(100) NOT NULL, config_value TEXT NOT NULL, data_type VARCHAR(20) NOT NULL DEFAULT 'string', version VARCHAR(10) NOT NULL DEFAULT '1.0.0', created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, PRIMARY KEY (id), UNIQUE KEY component_config (component_name, config_key) ) {$charset_collate};"; dbDelta($components_sql); dbDelta($defaults_sql); } /** * Helper: Insertar datos de prueba en tablas legacy */ private function seedLegacyData(): void { $timestamp = current_time('mysql'); // Components $components_data = [ ['top_bar', 'enabled', '1', 'boolean'], ['top_bar', 'message_text', 'Welcome!', 'string'], ['top_bar', 'background_color', '#000000', 'string'], ['footer', 'enabled', '1', 'boolean'], ['footer', 'cta_url', 'https://example.com', 'string'], ['footer', 'cta_text', 'Click here', 'string'], ]; foreach ($components_data as $data) { $this->wpdb->insert( $this->prefix . 'roi_theme_components', [ 'component_name' => $data[0], 'config_key' => $data[1], 'config_value' => $data[2], 'data_type' => $data[3], 'version' => '1.0.0', 'created_at' => $timestamp, 'updated_at' => $timestamp ], ['%s', '%s', '%s', '%s', '%s', '%s', '%s'] ); } // Defaults (misma estructura) $this->wpdb->insert( $this->prefix . 'roi_theme_components_defaults', [ 'component_name' => 'top_bar', 'config_key' => 'enabled', 'config_value' => '1', 'data_type' => 'boolean', 'version' => '1.0.0', 'created_at' => $timestamp, 'updated_at' => $timestamp ], ['%s', '%s', '%s', '%s', '%s', '%s', '%s'] ); } /** * Helper: Limpiar todas las tablas del test */ private function cleanupTables(): void { $tables = [ 'roi_theme_components', 'roi_theme_components_defaults', 'roi_theme_components_v2', 'roi_theme_components_defaults_v2', 'roi_theme_components_backup', 'roi_theme_components_defaults_backup' ]; foreach ($tables as $table) { $this->wpdb->query("DROP TABLE IF EXISTS {$this->prefix}{$table}"); } // Limpiar opciones delete_option('roi_theme_migration_date'); delete_option('roi_theme_migration_backup_date'); delete_option('roi_theme_migration_stats'); } }