libra/tests/Feature/RtlLtrLayoutTest.php

234 lines
8.8 KiB
PHP

<?php
use App\Models\User;
describe('RTL Layout for Arabic', function () {
test('html element has dir="rtl" when locale is Arabic', function () {
session(['locale' => '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 logical properties for skip link
expect($publicContent)->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')");
});
});