create(); expect($article)->toBeInstanceOf(CmsArticle::class) ->and($article->slug)->not->toBeEmpty() ->and($article->title)->not->toBeEmpty(); }); test('published scope returns only published articles', function () { CmsArticle::factory()->published()->count(2)->create(); CmsArticle::factory()->unpublished()->create(); expect(CmsArticle::published()->count())->toBe(2); }); test('ordered scope sorts by order then created_at desc', function () { $first = CmsArticle::factory()->create(['order' => 1]); $second = CmsArticle::factory()->create(['order' => 2]); $third = CmsArticle::factory()->create(['order' => 3]); $sorted = CmsArticle::ordered()->pluck('id')->toArray(); expect($sorted)->toBe([$first->id, $second->id, $third->id]); }); test('toFrontendArray returns compatible structure', function () { $article = CmsArticle::factory()->create([ 'slug' => 'test-article', 'title' => 'Test Article', 'subtitle' => 'Test Subtitle', 'image' => 'b2in/magazin-1.jpg', 'category' => 'Dubai Investment', 'date_label' => 'März 10, 2026', 'read_time' => '6 min read', 'author' => ['name' => 'Marcel', 'bio' => 'CEO', 'avatar' => 'avatar.jpg'], 'content' => ['de' => ['intro' => 'Intro text', 'sections' => [['title' => 'S1', 'content' => 'C1']]]], ]); $array = $article->toFrontendArray(); expect($array) ->toHaveKeys(['id', 'slug', 'title', 'subtitle', 'image', 'category', 'date', 'readTime', 'author', 'content']) ->and($array['slug'])->toBe('test-article') ->and($array['date'])->toBe('März 10, 2026') ->and($array['readTime'])->toBe('6 min read') ->and($array['author']['name'])->toBe('Marcel') ->and($array['content']['sections'])->toHaveCount(1); }); test('slug is unique', function () { CmsArticle::factory()->create(['slug' => 'unique-slug']); expect(fn () => CmsArticle::factory()->create(['slug' => 'unique-slug'])) ->toThrow(\Illuminate\Database\QueryException::class); }); test('author cast returns array', function () { $article = CmsArticle::factory()->create([ 'author' => ['name' => 'Test Author', 'bio' => 'Bio text', 'avatar' => 'a.jpg'], ]); $article->refresh(); expect($article->author) ->toBeArray() ->toHaveKey('name', 'Test Author') ->toHaveKey('bio', 'Bio text'); }); test('translatable fields work correctly', function () { $article = CmsArticle::factory()->create([ 'title' => ['de' => 'Deutscher Titel', 'en' => 'English Title'], 'subtitle' => ['de' => 'Deutsch', 'en' => 'English'], ]); expect($article->getTranslation('title', 'de'))->toBe('Deutscher Titel') ->and($article->getTranslation('title', 'en'))->toBe('English Title'); }); test('seeder creates articles from config data', function () { $this->seed(\Database\Seeders\CmsArticleSeeder::class); expect(CmsArticle::count())->toBe(5); $article = CmsArticle::where('slug', 'escrow-system-dubai-investoren')->first(); expect($article)->not->toBeNull() ->and($article->category)->toBe('Dubai Investment') ->and($article->read_time)->toBe('6 min read') ->and($article->author['name'])->toBe('Marcel Scheibe') ->and($article->is_published)->toBeTrue(); $content = $article->getTranslation('content', 'de'); expect($content)->toHaveKey('intro') ->and($content['sections'])->toHaveCount(3); }); test('seeder is idempotent', function () { $this->seed(\Database\Seeders\CmsArticleSeeder::class); $this->seed(\Database\Seeders\CmsArticleSeeder::class); expect(CmsArticle::count())->toBe(5); });