forceRootUrl('https://'.$portalDomain); }); // ======================================== // Authentication // ======================================== test('cms dashboard requires authentication', function () { $this->get(route('cms.dashboard'))->assertRedirect('/login'); }); test('cms content index requires authentication', function () { $this->get(route('cms.content.index'))->assertRedirect('/login'); }); test('cms projects index requires authentication', function () { $this->get(route('cms.projects.index'))->assertRedirect('/login'); }); test('cms media index requires authentication', function () { $this->get(route('cms.media.index'))->assertRedirect('/login'); }); // ======================================== // Dashboard // ======================================== test('cms dashboard renders for authenticated users', function () { $user = User::factory()->create(); $this->actingAs($user) ->get(route('cms.dashboard')) ->assertSuccessful() ->assertSee('So funktioniert das CMS') ->assertSee('Medienbibliothek'); }); test('cms dashboard shows correct stats', function () { $user = User::factory()->create(); CmsProject::factory()->published()->count(2)->create(); CmsProject::factory()->unpublished()->create(); Volt::actingAs($user) ->test('admin.cms.dashboard') ->assertSee('3') ->assertSee('2 veröffentlicht'); }); // ======================================== // Content Index // ======================================== test('cms content index renders for authenticated users', function () { $user = User::factory()->create(); $this->actingAs($user) ->get(route('cms.content.index')) ->assertSuccessful(); }); test('cms content index shows groups', function () { $user = User::factory()->create(); CmsContent::create([ 'group' => 'home', 'key' => 'hero', 'type' => 'json', 'value' => ['de' => ['title' => 'Test']], ]); CmsContent::create([ 'group' => 'home', 'key' => 'about', 'type' => 'text', 'value' => ['de' => 'About text'], ]); Volt::actingAs($user) ->test('admin.cms.content-index') ->assertSee('home') ->assertSee('2'); }); test('cms content index can select group and show flattened fields', function () { $user = User::factory()->create(); CmsContent::create([ 'group' => 'home', 'key' => 'hero', 'type' => 'json', 'value' => ['de' => ['title' => 'Hero Title', 'subtitle' => 'Hero Sub']], ]); Volt::actingAs($user) ->test('admin.cms.content-index') ->call('selectGroup', 'home') ->assertSee('hero') ->assertSee('title') ->assertSee('subtitle') ->assertSee('Hero Title') ->assertSee('Hero Sub'); }); test('cms content index can edit a flattened field', function () { $user = User::factory()->create(); $content = CmsContent::create([ 'group' => 'home', 'key' => 'hero', 'type' => 'json', 'value' => ['de' => ['title' => 'Old Title', 'subtitle' => 'Sub']], ]); Volt::actingAs($user) ->test('admin.cms.content-index') ->call('selectGroup', 'home') ->call('startFieldEdit', $content->id, 'title') ->assertSet('editingId', $content->id) ->assertSet('editingField', 'title') ->assertSet('editValue', 'Old Title') ->set('editValue', 'New Title') ->call('saveEdit') ->assertSet('editingId', null); $content->refresh(); $value = $content->getTranslation('value', 'de'); expect($value['title'])->toBe('New Title') ->and($value['subtitle'])->toBe('Sub'); }); test('cms content index opens json modal for array subfields', function () { $user = User::factory()->create(); $content = CmsContent::create([ 'group' => 'home', 'key' => 'hero', 'type' => 'json', 'value' => ['de' => ['title' => 'Title', 'stats' => [['label' => 'Projects', 'value' => '50+']]]], ]); Volt::actingAs($user) ->test('admin.cms.content-index') ->call('selectGroup', 'home') ->call('startFieldEdit', $content->id, 'stats') ->assertSet('showJsonModal', true) ->assertSet('jsonEditingKey', 'hero.stats'); }); // ======================================== // Projects Index // ======================================== test('cms projects index renders for authenticated users', function () { $user = User::factory()->create(); $this->actingAs($user) ->get(route('cms.projects.index')) ->assertSuccessful(); }); test('cms projects index lists projects', function () { $user = User::factory()->create(); CmsProject::factory()->published()->create(['slug' => 'test-project', 'title' => ['de' => 'Test Projekt']]); Volt::actingAs($user) ->test('admin.cms.projects-index') ->assertSee('Test Projekt'); }); test('cms projects can open create form', function () { $user = User::factory()->create(); Volt::actingAs($user) ->test('admin.cms.projects-index') ->call('openCreate') ->assertSet('showForm', true) ->assertSet('editingId', null); }); test('cms projects can save a new project', function () { $user = User::factory()->create(); Volt::actingAs($user) ->test('admin.cms.projects-index') ->call('openCreate') ->set('slug', 'new-project') ->set('projectTitle', 'New Project') ->set('is_published', true) ->set('order', 1) ->call('save') ->assertSet('showForm', false) ->assertHasNoErrors(); expect(CmsProject::where('slug', 'new-project')->exists())->toBeTrue(); }); test('cms projects can save with all detail fields', function () { $user = User::factory()->create(); Volt::actingAs($user) ->test('admin.cms.projects-index') ->call('openCreate') ->set('slug', 'full-project') ->set('projectTitle', 'Full Project') ->set('location', 'Dubai') ->set('status', 'NEW LAUNCH') ->set('price_from_aed', 1125000) ->set('highlights', ['Highlight A', 'Highlight B']) ->set('quick_facts', [['icon' => 'home-modern', 'label' => 'Typen', 'value' => '1BR']]) ->set('investTitle', 'Starkes Investment') ->set('investText', 'Beschreibung') ->set('investViews', ['Road View']) ->set('galleryItems', ['img1.jpg', 'img2.jpg']) ->set('locTitle', 'Location: Al Jaddaf') ->set('locMapUrl', 'https://maps.google.com') ->set('locPoints', ['Punkt 1', 'Punkt 2']) ->set('contactTitle', 'Kontakt Titel') ->set('contactSubtitle', 'Ihr Ansprechpartner') ->set('contactOptions', [['key' => '', 'value' => 'Bitte wählen'], ['key' => '1br', 'value' => '1BR Apt']]) ->call('save') ->assertSet('showForm', false); $project = CmsProject::where('slug', 'full-project')->first(); expect($project)->not->toBeNull() ->and($project->getTranslation('highlights', 'de'))->toHaveCount(2) ->and($project->quick_facts)->toHaveCount(1) ->and($project->gallery)->toHaveCount(2) ->and($project->getTranslation('investment_case', 'de')['title'])->toBe('Starkes Investment') ->and($project->getTranslation('location_info', 'de')['points'])->toHaveCount(2) ->and($project->getTranslation('contact', 'de')['options'])->toHaveKey('1br'); }); test('cms projects can edit existing project', function () { $user = User::factory()->create(); $project = CmsProject::factory()->published()->create(['slug' => 'edit-me', 'title' => ['de' => 'Edit Me']]); Volt::actingAs($user) ->test('admin.cms.projects-index') ->call('openEdit', $project->id) ->assertSet('showForm', true) ->assertSet('editingId', $project->id) ->assertSet('slug', 'edit-me'); }); test('cms projects can duplicate a project', function () { $user = User::factory()->create(); $project = CmsProject::factory()->published()->create([ 'slug' => 'original-project', 'title' => ['de' => 'Original Projekt'], ]); Volt::actingAs($user) ->test('admin.cms.projects-index') ->call('duplicateProject', $project->id) ->assertSet('showForm', true) ->assertSet('editingId', null) ->assertSet('projectTitle', 'Original Projekt'); expect($this->slug ?? '')->not->toBe('original-project'); }); test('cms projects can delete a project', function () { $user = User::factory()->create(); $project = CmsProject::factory()->create(['slug' => 'delete-me']); Volt::actingAs($user) ->test('admin.cms.projects-index') ->call('deleteProject', $project->id); expect(CmsProject::where('slug', 'delete-me')->exists())->toBeFalse(); }); // ======================================== // Media Index // ======================================== test('cms media index renders for authenticated users', function () { $user = User::factory()->create(); $this->actingAs($user) ->get(route('cms.media.index')) ->assertSuccessful(); }); // ======================================== // Articles (Magazin) // ======================================== test('cms articles index requires authentication', function () { $this->get(route('cms.articles.index'))->assertRedirect('/login'); }); test('cms articles index renders for authenticated users', function () { $user = User::factory()->create(); $this->actingAs($user) ->get(route('cms.articles.index')) ->assertSuccessful() ->assertSee('Magazin Beiträge'); }); test('cms articles index shows existing articles', function () { $user = User::factory()->create(); CmsArticle::factory()->create([ 'slug' => 'test-magazin-artikel', 'title' => ['de' => 'Ein Test Artikel'], 'category' => 'Dubai Investment', 'author' => ['name' => 'Marcel Scheibe', 'bio' => 'CEO', 'avatar' => 'a.jpg'], ]); $this->actingAs($user) ->get(route('cms.articles.index')) ->assertSee('Ein Test Artikel') ->assertSee('Dubai Investment') ->assertSee('Marcel Scheibe'); }); test('cms articles index can create new article', function () { $user = User::factory()->create(); $this->actingAs($user); Volt::test('admin.cms.articles-index') ->call('openCreate') ->assertSet('showForm', true) ->assertSet('editingId', null); }); test('cms articles index can save a new article', function () { $user = User::factory()->create(); $this->actingAs($user); Volt::test('admin.cms.articles-index') ->call('openCreate') ->set('slug', 'neuer-test-artikel') ->set('articleTitle', 'Neuer Testartikel') ->set('subtitle', 'Ein Untertitel') ->set('category', 'Test Kategorie') ->set('date_label', 'März 23, 2026') ->set('read_time', '5 min read') ->set('authorName', 'Test Autor') ->set('intro', 'Einleitungstext hier.') ->set('sections', [['title' => 'Abschnitt 1', 'content' => 'Inhalt 1']]) ->call('save') ->assertSet('showForm', false); $article = CmsArticle::where('slug', 'neuer-test-artikel')->first(); expect($article)->not->toBeNull() ->and($article->category)->toBe('Test Kategorie') ->and($article->getTranslation('title', 'de'))->toBe('Neuer Testartikel'); $content = $article->getTranslation('content', 'de'); expect($content['intro'])->toBe('Einleitungstext hier.') ->and($content['sections'])->toHaveCount(1); }); test('cms articles index can edit existing article', function () { $user = User::factory()->create(); $this->actingAs($user); $article = CmsArticle::factory()->create([ 'slug' => 'edit-test', 'title' => ['de' => 'Original Titel'], ]); Volt::test('admin.cms.articles-index') ->call('openEdit', $article->id) ->assertSet('editingId', $article->id) ->assertSet('slug', 'edit-test') ->assertSet('showForm', true); }); test('cms articles index can delete article', function () { $user = User::factory()->create(); $this->actingAs($user); $article = CmsArticle::factory()->create(); Volt::test('admin.cms.articles-index') ->call('deleteArticle', $article->id); expect(CmsArticle::find($article->id))->toBeNull(); }); test('cms articles index can toggle published status', function () { $user = User::factory()->create(); $this->actingAs($user); $article = CmsArticle::factory()->published()->create(); Volt::test('admin.cms.articles-index') ->call('togglePublished', $article->id); expect($article->refresh()->is_published)->toBeFalse(); });