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>
229 lines
8 KiB
PHP
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();
|
|
}
|