'ar']); $response = $this->get(route('home')); $response->assertOk(); $response->assertSee('dir="rtl"', escape: false); $response->assertSee('lang="ar"', escape: false); }); test('authenticated Arabic user gets RTL layout', function () { $user = User::factory()->create(['preferred_language' => 'ar']); $response = $this->actingAs($user)->get(route('client.dashboard')); $response->assertOk(); $response->assertSee('dir="rtl"', escape: false); $response->assertSee('lang="ar"', escape: false); }); test('admin dashboard has RTL layout for Arabic locale', function () { $admin = User::factory()->admin()->create(['preferred_language' => 'ar']); $response = $this->actingAs($admin)->get(route('admin.dashboard')); $response->assertOk(); $response->assertSee('dir="rtl"', escape: false); }); test('auth pages have RTL layout for Arabic locale', function () { session(['locale' => 'ar']); $response = $this->get(route('login')); $response->assertOk(); $response->assertSee('dir="rtl"', escape: false); $response->assertSee('lang="ar"', escape: false); }); }); describe('LTR Layout for English', function () { test('html element has dir="ltr" when locale is English', function () { session(['locale' => 'en']); $response = $this->get(route('home')); $response->assertOk(); $response->assertSee('dir="ltr"', escape: false); $response->assertSee('lang="en"', escape: false); }); test('authenticated English user gets LTR layout', function () { $user = User::factory()->create(['preferred_language' => 'en']); $response = $this->actingAs($user)->get(route('client.dashboard')); $response->assertOk(); $response->assertSee('dir="ltr"', escape: false); $response->assertSee('lang="en"', escape: false); }); test('admin dashboard has LTR layout for English locale', function () { $admin = User::factory()->admin()->create(['preferred_language' => 'en']); $response = $this->actingAs($admin)->get(route('admin.dashboard')); $response->assertOk(); $response->assertSee('dir="ltr"', escape: false); }); test('auth pages have LTR layout for English locale', function () { session(['locale' => 'en']); $response = $this->get(route('login')); $response->assertOk(); $response->assertSee('dir="ltr"', escape: false); $response->assertSee('lang="en"', escape: false); }); }); describe('Language Switch Transitions', function () { test('language switch updates direction attribute seamlessly', function () { // Start with Arabic session(['locale' => 'ar']); $response = $this->get(route('home')); $response->assertSee('dir="rtl"', escape: false); // Switch to English $this->get(route('language.switch', 'en')); $response = $this->get(route('home')); $response->assertSee('dir="ltr"', escape: false); }); test('authenticated user language switch persists direction', function () { $user = User::factory()->create(['preferred_language' => 'ar']); // Verify Arabic RTL $response = $this->actingAs($user)->get(route('client.dashboard')); $response->assertSee('dir="rtl"', escape: false); // Switch to English $this->actingAs($user)->get(route('language.switch', 'en')); // Verify English LTR $response = $this->actingAs($user)->get(route('client.dashboard')); $response->assertSee('dir="ltr"', escape: false); // Verify user preference was updated expect($user->fresh()->preferred_language)->toBe('en'); }); test('direction matches locale after multiple switches', function () { // Start with Arabic session(['locale' => 'ar']); $response = $this->get(route('home')); $response->assertSee('dir="rtl"', escape: false); // Switch to English $this->get(route('language.switch', 'en')); $response = $this->get(route('home')); $response->assertSee('dir="ltr"', escape: false); // Switch back to Arabic $this->get(route('language.switch', 'ar')); $response = $this->get(route('home')); $response->assertSee('dir="rtl"', escape: false); }); }); describe('RTL CSS Utilities', function () { test('flip-rtl utility class is available in CSS', function () { $cssContent = file_get_contents(resource_path('css/app.css')); expect($cssContent)->toContain('[dir="rtl"] .flip-rtl'); expect($cssContent)->toContain('transform: scaleX(-1)'); }); test('ltr-content utility class is available in CSS', function () { $cssContent = file_get_contents(resource_path('css/app.css')); expect($cssContent)->toContain('.ltr-content'); expect($cssContent)->toContain('direction: ltr'); expect($cssContent)->toContain('unicode-bidi: embed'); }); test('RTL form styling is available in CSS', function () { $cssContent = file_get_contents(resource_path('css/app.css')); expect($cssContent)->toContain('[dir="rtl"] [data-flux-label]'); expect($cssContent)->toContain('[dir="rtl"] [data-flux-error]'); }); }); describe('Component Direction Support', function () { test('sidebar layout uses logical properties', function () { $sidebarContent = file_get_contents(resource_path('views/components/layouts/app/sidebar.blade.php')); // Verify logical properties are used expect($sidebarContent)->toContain('border-e'); expect($sidebarContent)->toContain('me-5'); expect($sidebarContent)->toContain('rtl:space-x-reverse'); expect($sidebarContent)->toContain('text-start'); // Verify dir attribute is set expect($sidebarContent)->toContain("dir=\"{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}\""); }); test('public layout uses logical properties', function () { $publicContent = file_get_contents(resource_path('views/components/layouts/public.blade.php')); // Verify dir attribute is set expect($publicContent)->toContain("dir=\"{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}\""); // Verify skip link uses skip-link class (which contains RTL-compatible focus:start-4) expect($publicContent)->toContain('class="skip-link"'); // Verify CSS class contains logical properties $cssContent = file_get_contents(resource_path('css/app.css')); expect($cssContent)->toContain('.skip-link'); expect($cssContent)->toContain('focus:start-4'); }); test('auth layouts use logical properties', function () { $simpleContent = file_get_contents(resource_path('views/components/layouts/auth/simple.blade.php')); $cardContent = file_get_contents(resource_path('views/components/layouts/auth/card.blade.php')); $splitContent = file_get_contents(resource_path('views/components/layouts/auth/split.blade.php')); // Verify dir attribute is set in all auth layouts expect($simpleContent)->toContain("dir=\"{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}\""); expect($cardContent)->toContain("dir=\"{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}\""); expect($splitContent)->toContain("dir=\"{{ app()->getLocale() === 'ar' ? 'rtl' : 'ltr' }}\""); // Verify logical end positioning for language toggle expect($simpleContent)->toContain('end-4'); expect($cardContent)->toContain('end-4'); expect($splitContent)->toContain('end-4'); }); }); describe('Default Language Direction', function () { test('default locale is Arabic with RTL direction', function () { // Clear any session locale session()->forget('locale'); $response = $this->get(route('home')); $response->assertOk(); $response->assertSee('dir="rtl"', escape: false); $response->assertSee('lang="ar"', escape: false); }); test('user preferred language determines direction', function () { // Arabic user gets RTL $arabicUser = User::factory()->create(['preferred_language' => 'ar']); $response = $this->actingAs($arabicUser)->get(route('client.dashboard')); $response->assertSee('dir="rtl"', escape: false); // English user gets LTR $englishUser = User::factory()->create(['preferred_language' => 'en']); $response = $this->actingAs($englishUser)->get(route('client.dashboard')); $response->assertSee('dir="ltr"', escape: false); }); test('migration defines Arabic as default preferred language', function () { // Verify the migration file has Arabic as default $migrationFiles = glob(database_path('migrations/*create_users_table.php')); $migrationContent = file_get_contents($migrationFiles[0]); expect($migrationContent)->toContain("->default('ar')"); }); });