presseportale/tests/Feature/MigrateLegacyMediaCommandTest.php
Kevin Adametz 0a3e52d603 19-05-2026 Rebrand Pressekonto, Hub-Flux UI und Legacy-Media-Migration
Umbenennung presseportale → pressekonto in Domains, Themes und Dokumentation.
Design-Tokens, Portal-Shell, Customer-Dashboard, Auth- und Admin-PM-Views.
Artisan-Befehl migrate:legacy-media mit Tests und Hub-Flux-Entwicklungsdocs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 16:36:13 +00:00

229 lines
8 KiB
PHP

<?php
use App\Enums\Portal;
use App\Models\Company;
use App\Models\PressRelease;
use App\Models\PressReleaseImage;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Tests\TestCase;
test('legacy media migration copies company logos from migration folder using legacy database rows', function () {
/** @var TestCase $this */
Storage::fake('public');
configureLegacyMediaConnection();
$basePath = prepareLegacyMediaFolder();
File::ensureDirectoryExists("{$basePath}/presseecho/uploads/company");
File::put("{$basePath}/presseecho/uploads/company/logo-a.jpg", migrateLegacyMediaFakeImageBytes());
DB::connection('mysql_presseecho')->table('company')->insert([
'id' => 123,
'logo' => 'logo-a.jpg',
]);
$company = Company::factory()->create([
'portal' => Portal::Presseecho->value,
'legacy_portal' => Portal::Presseecho->value,
'legacy_id' => 123,
'logo_path' => null,
'logo_variants' => null,
]);
$this->artisan('legacy:migrate-media', [
'--portal' => Portal::Presseecho->value,
'--type' => 'company-logos',
'--base-path' => $basePath,
])
->assertSuccessful()
->expectsOutputToContain('presseecho/company-logos: Legacy 1, migriert 1, Thumbnail-Fallback 0, DB-Updates 1');
$company->refresh();
expect($company->logo_path)->toBe("company-logos/presseecho/{$company->id}/logo-a.jpg")
->and($company->logo_variants)->toHaveKeys(['sq', 'wide']);
Storage::disk('public')->assertExists($company->logo_path);
foreach ($company->logo_variants as $variantPath) {
Storage::disk('public')->assertExists($variantPath);
}
});
test('legacy media migration creates press release image records from legacy database rows', function () {
/** @var TestCase $this */
Storage::fake('public');
configureLegacyMediaConnection();
$basePath = prepareLegacyMediaFolder();
File::ensureDirectoryExists("{$basePath}/presseecho/uploads/pressreleaseimage");
File::put("{$basePath}/presseecho/uploads/pressreleaseimage/photo-a.jpg", migrateLegacyMediaFakeImageBytes(1600, 1200));
DB::connection('mysql_presseecho')->table('press_release_image')->insert([
'id' => 987,
'title' => 'Pressefoto',
'description' => 'Beschreibung',
'image' => 'photo-a.jpg',
'copyright' => 'Copyright',
'press_release_id' => 456,
'is_preview_image' => true,
]);
$pressRelease = PressRelease::factory()->create([
'portal' => Portal::Presseecho->value,
'legacy_portal' => Portal::Presseecho->value,
'legacy_id' => 456,
]);
$this->artisan('legacy:migrate-media', [
'--portal' => Portal::Presseecho->value,
'--type' => 'press-release-images',
'--base-path' => $basePath,
])
->assertSuccessful()
->expectsOutputToContain('presseecho/press-release-images: Legacy 1, migriert 1, Thumbnail-Fallback 0, DB-Updates 1');
$image = PressReleaseImage::query()
->where('legacy_portal', Portal::Presseecho->value)
->where('legacy_id', 987)
->firstOrFail();
expect($image->press_release_id)->toBe($pressRelease->id)
->and($image->path)->toBe("press-releases/{$pressRelease->id}/images/photo-a.jpg")
->and($image->title)->toBe('Pressefoto')
->and($image->is_preview)->toBeTrue()
->and($image->variants)->toHaveKeys(['thumb', 'medium', 'large'])
->and($image->width)->toBe(1600)
->and($image->height)->toBe(1200);
Storage::disk('public')->assertExists($image->path);
foreach ($image->variants as $variantPath) {
Storage::disk('public')->assertExists($variantPath);
}
});
test('legacy media migration reports missing source files without changing the target record', function () {
/** @var TestCase $this */
Storage::fake('public');
configureLegacyMediaConnection();
$basePath = prepareLegacyMediaFolder();
DB::connection('mysql_presseecho')->table('company')->insert([
'id' => 321,
'logo' => 'missing.png',
]);
$company = Company::factory()->create([
'portal' => Portal::Presseecho->value,
'legacy_portal' => Portal::Presseecho->value,
'legacy_id' => 321,
'logo_path' => null,
]);
$this->artisan('legacy:migrate-media', [
'--portal' => Portal::Presseecho->value,
'--type' => 'company-logos',
'--base-path' => $basePath,
])
->assertFailed()
->expectsOutputToContain('Datei fehlt: presseecho/company/missing.png');
expect($company->fresh()->logo_path)->toBeNull();
});
test('legacy media migration falls back to legacy thumbnails by image id', function () {
/** @var TestCase $this */
Storage::fake('public');
configureLegacyMediaConnection();
$basePath = prepareLegacyMediaFolder();
File::ensureDirectoryExists("{$basePath}/presseecho/thumbnails/pressreleaseimage/press_image_preview/42/01/00");
File::put("{$basePath}/presseecho/thumbnails/pressreleaseimage/press_image_preview/42/01/00/pool-10042.png", migrateLegacyMediaFakeImageBytes(filename: 'legacy.png'));
DB::connection('mysql_presseecho')->table('press_release_image')->insert([
'id' => 10042,
'title' => 'Pool',
'description' => null,
'image' => 'missing-original.jpg',
'copyright' => null,
'press_release_id' => 654,
'is_preview_image' => false,
]);
$pressRelease = PressRelease::factory()->create([
'portal' => Portal::Presseecho->value,
'legacy_portal' => Portal::Presseecho->value,
'legacy_id' => 654,
]);
$this->artisan('legacy:migrate-media', [
'--portal' => Portal::Presseecho->value,
'--type' => 'press-release-images',
'--base-path' => $basePath,
])
->assertSuccessful()
->expectsOutputToContain('Thumbnail-Fallback 1');
$image = PressReleaseImage::query()
->where('legacy_portal', Portal::Presseecho->value)
->where('legacy_id', 10042)
->firstOrFail();
expect($image->path)->toBe("press-releases/{$pressRelease->id}/images/pool-10042.png")
->and($image->variants)->toHaveKeys(['thumb', 'medium', 'large']);
Storage::disk('public')->assertExists($image->path);
});
function configureLegacyMediaConnection(): void
{
Config::set('database.connections.mysql_presseecho', [
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => '',
'foreign_key_constraints' => false,
]);
DB::purge('mysql_presseecho');
Schema::connection('mysql_presseecho')->dropIfExists('company');
Schema::connection('mysql_presseecho')->dropIfExists('press_release_image');
Schema::connection('mysql_presseecho')->create('company', function (Blueprint $table): void {
$table->integer('id')->primary();
$table->string('logo')->nullable();
});
Schema::connection('mysql_presseecho')->create('press_release_image', function (Blueprint $table): void {
$table->integer('id')->primary();
$table->string('title')->nullable();
$table->text('description')->nullable();
$table->string('image')->nullable();
$table->string('copyright')->nullable();
$table->integer('press_release_id');
$table->boolean('is_preview_image')->default(false);
});
}
function prepareLegacyMediaFolder(): string
{
$basePath = storage_path('framework/testing/legacy-media-'.Str::random(8));
File::deleteDirectory($basePath);
File::ensureDirectoryExists($basePath);
return $basePath;
}
function migrateLegacyMediaFakeImageBytes(int $width = 800, int $height = 600, string $filename = 'legacy.jpg'): string
{
return UploadedFile::fake()->image($filename, $width, $height)->get();
}