create(); expect($project)->toBeInstanceOf(CmsProject::class) ->and($project->slug)->not->toBeEmpty() ->and($project->title)->not->toBeEmpty(); }); test('published scope returns only published projects', function () { CmsProject::factory()->published()->count(2)->create(); CmsProject::factory()->unpublished()->create(); expect(CmsProject::published()->count())->toBe(2); }); test('ordered scope sorts by order then launch_date desc', function () { $first = CmsProject::factory()->create([ 'order' => 0, 'launch_date' => '2026-06-01', ]); $second = CmsProject::factory()->create([ 'order' => 0, 'launch_date' => '2026-01-01', ]); $third = CmsProject::factory()->create([ 'order' => 1, 'launch_date' => '2026-12-01', ]); $sorted = CmsProject::ordered()->pluck('id')->toArray(); expect($sorted)->toBe([$first->id, $second->id, $third->id]); }); test('getFormattedPrice returns formatted AED with EUR and USD', function () { $project = CmsProject::factory()->create(['price_from_aed' => 1_125_000]); $formatted = $project->getFormattedPrice(); expect($formatted) ->toContain('AED') ->toContain('EUR') ->toContain('USD') ->toContain('1.125.000') ->toContain('whitespace-nowrap'); }); test('getFormattedPrice returns empty string when no price', function () { $project = CmsProject::factory()->create(['price_from_aed' => null]); expect($project->getFormattedPrice())->toBe(''); }); test('toFrontendArray returns compatible structure', function () { $project = CmsProject::factory()->create([ 'slug' => 'test-project', 'title' => 'Test Project', 'location' => 'Dubai', 'status' => 'NEW LAUNCH', 'launch_date' => '2026-03-03', 'price_from_aed' => 1_000_000, 'highlights' => ['Highlight 1', 'Highlight 2'], 'quick_facts' => [['icon' => 'home', 'label' => 'Type', 'value' => '1BR']], 'gallery' => ['img1.jpg', 'img2.jpg'], ]); $array = $project->toFrontendArray(); expect($array) ->toHaveKeys(['slug', 'title', 'location', 'status', 'launch_date', 'price_from', 'image', 'highlights', 'quick_facts', 'investment_case', 'gallery', 'location_info', 'contact', 'investor_trust', 'furniture_benefit']) ->and($array['slug'])->toBe('test-project') ->and($array['launch_date'])->toBe('03.03.2026') ->and($array['highlights'])->toHaveCount(2) ->and($array['gallery'])->toHaveCount(2) ->and($array['price_from'])->toContain('AED'); }); test('slug is unique', function () { CmsProject::factory()->create(['slug' => 'unique-slug']); expect(fn () => CmsProject::factory()->create(['slug' => 'unique-slug'])) ->toThrow(\Illuminate\Database\QueryException::class); }); test('seeder creates project from config data', function () { $this->seed(\Database\Seeders\CmsProjectSeeder::class); $project = CmsProject::where('slug', 'azizi-creek-views-4')->first(); expect($project)->not->toBeNull() ->and($project->title)->toBe('Azizi Developments: Creek Views 4') ->and($project->price_from_aed)->toBe(1_125_000) ->and($project->is_published)->toBeTrue() ->and($project->gallery)->toHaveCount(6) ->and($project->quick_facts)->toHaveCount(4) ->and($project->investor_trust)->toBeArray() ->and($project->investor_trust['columns'] ?? [])->toHaveCount(3) ->and($project->furniture_benefit)->toBeArray() ->and($project->furniture_benefit['button_link'] ?? '')->toBe('/netzwerk'); }); test('seeder is idempotent', function () { $this->seed(\Database\Seeders\CmsProjectSeeder::class); $this->seed(\Database\Seeders\CmsProjectSeeder::class); expect(CmsProject::count())->toBe(1); });