4a8622c385
- Wrap the data copy in DB::transaction (FULLTEXT ALTER stays outside) - Switch to chunkById(500) so the migration scales - Document down() as irreversible for non-default-locale translations - Add test_existing_documents_data_is_copied_to_translations to cover the data copy itself (the only previously-untested behavior) - Drop unused Migrator import in DocumentMigrationTest - Also restore title index in down() so up() can be re-run cleanly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
115 lines
4.3 KiB
PHP
115 lines
4.3 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Tests\TestCase;
|
|
|
|
class DocumentMigrationTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
public function test_documents_table_has_default_locale_after_migration(): void
|
|
{
|
|
$this->assertTrue(Schema::hasColumn('documents', 'default_locale'));
|
|
}
|
|
|
|
public function test_documents_table_no_longer_has_translatable_columns(): void
|
|
{
|
|
$this->assertFalse(Schema::hasColumn('documents', 'title'));
|
|
$this->assertFalse(Schema::hasColumn('documents', 'content'));
|
|
$this->assertFalse(Schema::hasColumn('documents', 'rendered_html'));
|
|
}
|
|
|
|
public function test_document_translations_table_exists_with_required_columns(): void
|
|
{
|
|
$this->assertTrue(Schema::hasTable('document_translations'));
|
|
|
|
foreach (['document_id', 'locale', 'title', 'content', 'rendered_html', 'created_by', 'updated_by', 'created_at', 'updated_at'] as $col) {
|
|
$this->assertTrue(
|
|
Schema::hasColumn('document_translations', $col),
|
|
"document_translations missing column: $col"
|
|
);
|
|
}
|
|
}
|
|
|
|
public function test_document_translations_unique_document_locale(): void
|
|
{
|
|
DB::table('documents')->insert([
|
|
'path' => 'A.md',
|
|
'slug' => 'a',
|
|
'default_locale' => 'en',
|
|
'file_size' => 0,
|
|
'file_hash' => str_repeat('0', 64),
|
|
'file_modified_at' => now(),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
$docId = DB::table('documents')->where('slug', 'a')->value('id');
|
|
|
|
DB::table('document_translations')->insert([
|
|
'document_id' => $docId,
|
|
'locale' => 'en',
|
|
'title' => 'A',
|
|
'content' => '...',
|
|
'rendered_html' => '<p>...</p>',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
$this->expectException(\Illuminate\Database\QueryException::class);
|
|
|
|
DB::table('document_translations')->insert([
|
|
'document_id' => $docId,
|
|
'locale' => 'en',
|
|
'title' => 'duplicate',
|
|
'content' => '...',
|
|
'rendered_html' => '<p>...</p>',
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
}
|
|
|
|
public function test_existing_documents_data_is_copied_to_translations(): void
|
|
{
|
|
// Roll the new migration back so the legacy columns exist again
|
|
\Illuminate\Support\Facades\Artisan::call('migrate:rollback', ['--step' => 1]);
|
|
$this->assertTrue(\Illuminate\Support\Facades\Schema::hasColumn('documents', 'title'));
|
|
|
|
// Seed a legacy document row directly
|
|
\Illuminate\Support\Facades\DB::table('documents')->insert([
|
|
'path' => 'Legacy.md',
|
|
'title' => 'Legacy Title',
|
|
'slug' => 'legacy-title',
|
|
'content' => '# Legacy body',
|
|
'rendered_html' => '<h1>Legacy body</h1>',
|
|
'file_size' => 0,
|
|
'file_hash' => str_repeat('0', 64),
|
|
'file_modified_at' => now(),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
$docId = \Illuminate\Support\Facades\DB::table('documents')->where('slug', 'legacy-title')->value('id');
|
|
|
|
// Re-run the migration
|
|
\Illuminate\Support\Facades\Artisan::call('migrate');
|
|
|
|
// Verify the data was copied to document_translations
|
|
$translation = \Illuminate\Support\Facades\DB::table('document_translations')
|
|
->where('document_id', $docId)
|
|
->first();
|
|
|
|
$this->assertNotNull($translation, 'Translation row should have been created from legacy data');
|
|
$this->assertSame('Legacy Title', $translation->title);
|
|
$this->assertSame('# Legacy body', $translation->content);
|
|
$this->assertSame('<h1>Legacy body</h1>', $translation->rendered_html);
|
|
$this->assertSame(config('app.locale', 'en'), $translation->locale);
|
|
|
|
// Verify documents.default_locale was set
|
|
$defaultLocale = \Illuminate\Support\Facades\DB::table('documents')->where('id', $docId)->value('default_locale');
|
|
$this->assertSame(config('app.locale', 'en'), $defaultLocale);
|
|
}
|
|
}
|