239 lines
9.1 KiB
PHP
239 lines
9.1 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 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')");
|
|
});
|
|
});
|