published()->create(['title' => ['en' => 'Published Post', 'ar' => 'مقال منشور']]); Post::factory()->draft()->create(['title' => ['en' => 'Draft Post', 'ar' => 'مقال مسودة']]); $this->withSession(['locale' => 'en']) ->get(route('posts.index')) ->assertOk() ->assertSee('Published Post') ->assertDontSee('Draft Post'); }); test('posts listing page displays in reverse chronological order', function () { Post::factory()->published()->create([ 'title' => ['en' => 'Older Post', 'ar' => 'مقال قديم'], 'created_at' => now()->subDays(5), 'published_at' => now()->subDays(5), ]); Post::factory()->published()->create([ 'title' => ['en' => 'Newer Post', 'ar' => 'مقال جديد'], 'created_at' => now(), 'published_at' => now(), ]); $this->withSession(['locale' => 'en']) ->get(route('posts.index')) ->assertOk() ->assertSeeInOrder(['Newer Post', 'Older Post']); }); test('posts listing page paginates results', function () { Post::factory()->count(15)->published()->create(); // First page should show navigation to next page $this->withSession(['locale' => 'en']) ->get(route('posts.index')) ->assertOk() ->assertSee('Next'); // Second page should also work $this->withSession(['locale' => 'en']) ->get(route('posts.index').'?page=2') ->assertOk(); }); test('posts listing page shows no posts message when empty', function () { $this->withSession(['locale' => 'en']) ->get(route('posts.index')) ->assertOk() ->assertSee('No posts found.'); }); test('posts listing page shows post excerpt', function () { Post::factory()->published()->create([ 'title' => ['en' => 'Test Post', 'ar' => 'مقال اختباري'], 'body' => ['en' => 'This is a test body content that should be displayed as an excerpt.', 'ar' => 'محتوى اختباري'], ]); $this->withSession(['locale' => 'en']) ->get(route('posts.index')) ->assertOk() ->assertSee('Test Post') ->assertSee('This is a test body content'); }); test('posts listing page is accessible without authentication', function () { Post::factory()->published()->create(); $this->get(route('posts.index')) ->assertOk(); }); test('individual post page shows full content', function () { $post = Post::factory()->published()->create([ 'title' => ['en' => 'Full Post Title', 'ar' => 'عنوان المقال الكامل'], 'body' => ['en' => '
Full post body content here.
', 'ar' => 'محتوى المقال الكامل هنا.
'], ]); $this->withSession(['locale' => 'en']) ->get(route('posts.show', $post)) ->assertOk() ->assertSee('Full Post Title') ->assertSee('Full post body content here.'); }); test('individual post page returns 404 for unpublished posts', function () { $post = Post::factory()->draft()->create(); $this->get(route('posts.show', $post)) ->assertNotFound(); }); test('individual post page returns 404 for non-existent posts', function () { $this->get(route('posts.show', 999)) ->assertNotFound(); }); test('individual post page shows back to posts link', function () { $post = Post::factory()->published()->create(); $this->withSession(['locale' => 'en']) ->get(route('posts.show', $post)) ->assertOk() ->assertSee('Back to Posts'); }); test('individual post page is accessible without authentication', function () { $post = Post::factory()->published()->create(); $this->get(route('posts.show', $post)) ->assertOk(); }); test('posts listing page displays content in current locale', function () { Post::factory()->published()->create([ 'title' => ['en' => 'English Title', 'ar' => 'عنوان عربي'], 'body' => ['en' => 'English content', 'ar' => 'محتوى عربي'], ]); // Test English $this->withSession(['locale' => 'en']) ->get(route('posts.index')) ->assertOk() ->assertSee('English Title'); // Test Arabic $this->withSession(['locale' => 'ar']) ->get(route('posts.index')) ->assertOk() ->assertSee('عنوان عربي'); }); test('individual post page displays content in current locale', function () { $post = Post::factory()->published()->create([ 'title' => ['en' => 'English Title', 'ar' => 'عنوان عربي'], 'body' => ['en' => 'English content', 'ar' => 'محتوى عربي'], ]); // Test English $this->withSession(['locale' => 'en']) ->get(route('posts.show', $post)) ->assertOk() ->assertSee('English Title') ->assertSee('English content'); // Test Arabic $this->withSession(['locale' => 'ar']) ->get(route('posts.show', $post)) ->assertOk() ->assertSee('عنوان عربي') ->assertSee('محتوى عربي'); }); // Search functionality tests test('search input is displayed on posts listing page', function () { $this->withSession(['locale' => 'en']) ->get(route('posts.index')) ->assertOk() ->assertSee('Search posts...'); }); test('search filters posts by English title', function () { Post::factory()->published()->create([ 'title' => ['en' => 'Legal Rights Guide', 'ar' => 'دليل الحقوق القانونية'], ]); Post::factory()->published()->create([ 'title' => ['en' => 'Tax Information', 'ar' => 'معلومات ضريبية'], ]); app()->setLocale('en'); // Title is highlighted, so we check for parts that won't be in the mark tag // "Legal" will be in , "Rights Guide" will be after Livewire\Volt\Volt::test('pages.posts.index') ->set('search', 'Legal') ->assertSee('Rights Guide') // Part after the highlighted word ->assertSee('Legal') // The highlighted word (inside ) ->assertDontSee('Tax Information'); }); test('search filters posts by Arabic title', function () { Post::factory()->published()->create([ 'title' => ['en' => 'Legal Rights Guide', 'ar' => 'دليل الحقوق القانونية'], ]); Post::factory()->published()->create([ 'title' => ['en' => 'Tax Information', 'ar' => 'معلومات ضريبية'], ]); app()->setLocale('ar'); // Search for "الحقوق" (rights) - should find first post only $component = Livewire\Volt\Volt::test('pages.posts.index') ->set('search', 'الحقوق'); // Check we have results (not "no results") $html = $component->html(); expect(str_contains($html, 'تم العثور'))->toBeTrue('Should show found results message'); // Check the highlighted word appears $component->assertSee('الحقوق') // The highlighted word ->assertDontSee('ضريبية'); // Part of second post }); test('search filters posts by body content', function () { Post::factory()->published()->create([ 'title' => ['en' => 'First Article', 'ar' => 'المقال الأول'], 'body' => ['en' => 'This discusses property law topics.', 'ar' => 'هذا يناقش مواضيع قانون الملكية.'], ]); Post::factory()->published()->create([ 'title' => ['en' => 'Second Article', 'ar' => 'المقال الثاني'], 'body' => ['en' => 'This is about family matters.', 'ar' => 'هذا يتعلق بشؤون الأسرة.'], ]); app()->setLocale('en'); // Searching body content - title doesn't contain 'property' so won't be highlighted Livewire\Volt\Volt::test('pages.posts.index') ->set('search', 'property') ->assertSee('First Article') // This title has no highlight since match is in body ->assertDontSee('Second Article'); }); test('search shows no results message when no matches found', function () { Post::factory()->published()->create([ 'title' => ['en' => 'Test Post', 'ar' => 'مقال اختبار'], ]); app()->setLocale('en'); Livewire\Volt\Volt::test('pages.posts.index') ->set('search', 'nonexistent') ->assertSee('No results found'); }); test('search only searches published posts', function () { Post::factory()->draft()->create([ 'title' => ['en' => 'Draft Article', 'ar' => 'مقال مسودة'], ]); Post::factory()->published()->create([ 'title' => ['en' => 'Published Article', 'ar' => 'مقال منشور'], ]); app()->setLocale('en'); // Search for "Article" - both have it in title, but only published should appear // "Article" will be highlighted in "Published Article" Livewire\Volt\Volt::test('pages.posts.index') ->set('search', 'Article') ->assertSee('Published') // Part of the title without highlight ->assertSee('Article') // The highlighted word ->assertDontSee('Draft'); }); test('clear search button resets search and shows all posts', function () { Post::factory()->published()->create([ 'title' => ['en' => 'Alpha Article', 'ar' => 'المقال الأول'], ]); Post::factory()->published()->create([ 'title' => ['en' => 'Beta Article', 'ar' => 'المقال الثاني'], ]); app()->setLocale('en'); Livewire\Volt\Volt::test('pages.posts.index') ->set('search', 'Alpha') ->assertSee('Alpha') // Highlighted in "Alpha Article" ->assertDontSee('Beta') ->call('clearSearch') ->assertSet('search', '') ->assertSee('Alpha Article') // No highlighting after clear ->assertSee('Beta Article'); }); test('search is case insensitive', function () { Post::factory()->published()->create([ 'title' => ['en' => 'UPPERCASE TITLE', 'ar' => 'عنوان كبير'], ]); app()->setLocale('en'); // Search lowercase "uppercase" should find "UPPERCASE TITLE" // Note: "uppercase" will be highlighted (case preserved in original) Livewire\Volt\Volt::test('pages.posts.index') ->set('search', 'uppercase') ->assertSee('UPPERCASE') // The highlighted word ->assertSee('TITLE'); // Rest of title }); test('search resets pagination', function () { Post::factory()->count(15)->published()->create(); Post::factory()->published()->create([ 'title' => ['en' => 'Special Searchable Post', 'ar' => 'مقال قابل للبحث خاص'], ]); $component = Livewire\Volt\Volt::test('pages.posts.index'); // Navigate to page 2 $component->call('gotoPage', 2); // Set search - should reset to page 1 $component->set('search', 'Special') ->assertSet('paginators.page', 1); });