libra/tests/Feature/ResponsiveDesignTest.php

288 lines
11 KiB
PHP

<?php
use App\Models\User;
beforeEach(function () {
$this->admin = User::factory()->admin()->create();
$this->client = User::factory()->individual()->create();
});
describe('Responsive Utility Classes', function () {
test('app.css contains responsive design system section', function () {
$cssPath = resource_path('css/app.css');
$cssContent = file_get_contents($cssPath);
expect($cssContent)->toContain('Responsive Design System (Story 9.9)')
->and($cssContent)->toContain('.dashboard-grid')
->and($cssContent)->toContain('.stats-grid')
->and($cssContent)->toContain('.table-responsive')
->and($cssContent)->toContain('.touch-target')
->and($cssContent)->toContain('.page-header')
->and($cssContent)->toContain('.empty-state');
});
test('app.css contains breakpoint utilities per PRD 7.4', function () {
$cssPath = resource_path('css/app.css');
$cssContent = file_get_contents($cssPath);
// Check for mobile-first responsive breakpoints
expect($cssContent)->toContain('sm:grid-cols-2')
->and($cssContent)->toContain('lg:grid-cols-3')
->and($cssContent)->toContain('xl:grid-cols-4');
});
test('app.css contains touch-friendly minimum size', function () {
$cssPath = resource_path('css/app.css');
$cssContent = file_get_contents($cssPath);
// Check for 44px minimum touch target (Apple HIG recommendation)
expect($cssContent)->toContain('min-h-[44px]')
->and($cssContent)->toContain('min-w-[44px]');
});
test('app.css prevents horizontal page scroll', function () {
$cssPath = resource_path('css/app.css');
$cssContent = file_get_contents($cssPath);
expect($cssContent)->toContain('overflow-x-hidden');
});
test('app.css contains RTL-aware sidebar responsive styles', function () {
$cssPath = resource_path('css/app.css');
$cssContent = file_get_contents($cssPath);
expect($cssContent)->toContain('.sidebar-responsive')
->and($cssContent)->toContain('[dir="rtl"] .sidebar-responsive');
});
});
describe('Admin Dashboard Responsive', function () {
test('admin dashboard uses stats-grid class', function () {
$viewPath = resource_path('views/livewire/admin/dashboard.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('stats-grid');
});
test('admin dashboard uses page-header class', function () {
$viewPath = resource_path('views/livewire/admin/dashboard.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('page-header');
});
test('admin dashboard uses widget-grid class', function () {
$viewPath = resource_path('views/livewire/admin/dashboard.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('widget-grid');
});
});
describe('Client Dashboard Responsive', function () {
test('client dashboard has responsive padding', function () {
$viewPath = resource_path('views/livewire/client/dashboard.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('p-4 sm:p-6');
});
test('client dashboard has responsive grid', function () {
$viewPath = resource_path('views/livewire/client/dashboard.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('grid-cols-1 sm:grid-cols-2');
});
test('client dashboard has responsive text sizing', function () {
$viewPath = resource_path('views/livewire/client/dashboard.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('text-lg sm:text-xl lg:text-2xl');
});
});
describe('Table Responsive', function () {
test('individual clients table uses table-scroll-wrapper', function () {
$viewPath = resource_path('views/livewire/admin/clients/individual/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('table-scroll-wrapper');
});
test('company clients table uses table-scroll-wrapper', function () {
$viewPath = resource_path('views/livewire/admin/clients/company/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('table-scroll-wrapper');
});
test('individual clients uses header-actions class', function () {
$viewPath = resource_path('views/livewire/admin/clients/individual/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('header-actions');
});
});
describe('Calendar Responsive', function () {
test('availability calendar uses calendar-grid class', function () {
$viewPath = resource_path('views/livewire/availability-calendar.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('calendar-grid');
});
test('availability calendar uses calendar-cell class', function () {
$viewPath = resource_path('views/livewire/availability-calendar.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('calendar-cell');
});
test('availability calendar uses time-slots-grid class', function () {
$viewPath = resource_path('views/livewire/availability-calendar.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('time-slots-grid');
});
test('availability calendar time slots are touch-friendly', function () {
$viewPath = resource_path('views/livewire/availability-calendar.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('time-slot-btn');
});
});
describe('Forms Responsive', function () {
test('booking form buttons have touch-friendly sizing', function () {
$viewPath = resource_path('views/livewire/client/consultations/book.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('min-h-[44px]');
});
test('booking form buttons are full-width on mobile', function () {
$viewPath = resource_path('views/livewire/client/consultations/book.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('w-full sm:w-auto');
});
});
describe('Footer Responsive', function () {
test('footer has responsive grid', function () {
$viewPath = resource_path('views/components/footer.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('grid-cols-1 sm:grid-cols-2 lg:grid-cols-3');
});
test('footer has responsive padding', function () {
$viewPath = resource_path('views/components/footer.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('px-4 sm:px-6 lg:px-8');
});
test('footer links are touch-friendly', function () {
$viewPath = resource_path('views/components/footer.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('min-h-[44px]');
});
});
describe('Public Pages Responsive', function () {
test('home page has responsive grid', function () {
$viewPath = resource_path('views/pages/home.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('grid-cols-1 sm:grid-cols-2 lg:grid-cols-3');
});
test('home page has responsive text sizing', function () {
$viewPath = resource_path('views/pages/home.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('text-2xl sm:text-3xl lg:text-4xl');
});
test('public layout has responsive padding', function () {
$viewPath = resource_path('views/components/layouts/public.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('px-4 sm:px-6 lg:px-8');
});
});
describe('Posts Responsive', function () {
test('posts list has responsive styling', function () {
$viewPath = resource_path('views/livewire/pages/posts/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('p-4 sm:p-6');
});
test('posts list uses empty-state class', function () {
$viewPath = resource_path('views/livewire/pages/posts/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('empty-state');
});
test('posts read more link is touch-friendly', function () {
$viewPath = resource_path('views/livewire/pages/posts/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('min-h-[44px]');
});
});
describe('Consultations Page Responsive', function () {
test('consultations index uses page-header class', function () {
$viewPath = resource_path('views/livewire/client/consultations/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('page-header');
});
test('consultations index uses empty-state class', function () {
$viewPath = resource_path('views/livewire/client/consultations/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('empty-state');
});
test('consultations index has responsive card padding', function () {
$viewPath = resource_path('views/livewire/client/consultations/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('p-3 sm:p-4');
});
});
describe('Timelines Responsive', function () {
test('timelines index has responsive layout', function () {
$viewPath = resource_path('views/livewire/client/timelines/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('flex-col sm:flex-row');
});
test('timelines index uses empty-state class', function () {
$viewPath = resource_path('views/livewire/client/timelines/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('empty-state');
});
test('timelines view button is touch-friendly', function () {
$viewPath = resource_path('views/livewire/client/timelines/index.blade.php');
$viewContent = file_get_contents($viewPath);
expect($viewContent)->toContain('min-h-[44px]');
});
});