322 lines
9.3 KiB
PHP
322 lines
9.3 KiB
PHP
<?php
|
|
|
|
use App\Models\AdminLog;
|
|
use App\Models\Page;
|
|
use App\Models\User;
|
|
use Livewire\Volt\Volt;
|
|
|
|
beforeEach(function () {
|
|
$this->admin = User::factory()->admin()->create();
|
|
// Ensure test pages exist
|
|
Page::factory()->terms()->create();
|
|
Page::factory()->privacy()->create();
|
|
});
|
|
|
|
// ===========================================
|
|
// Admin Index Page Tests
|
|
// ===========================================
|
|
|
|
test('admin can view legal pages list', function () {
|
|
$this->actingAs($this->admin)
|
|
->get(route('admin.pages.index'))
|
|
->assertOk()
|
|
->assertSee('Terms of Service')
|
|
->assertSee('Privacy Policy');
|
|
});
|
|
|
|
test('legal pages list shows both pages', function () {
|
|
$this->actingAs($this->admin);
|
|
|
|
$component = Volt::test('admin.pages.index');
|
|
|
|
expect($component->viewData('pages')->count())->toBe(2);
|
|
});
|
|
|
|
// ===========================================
|
|
// Admin Edit Page Tests
|
|
// ===========================================
|
|
|
|
test('admin can view terms edit page', function () {
|
|
$this->actingAs($this->admin)
|
|
->get(route('admin.pages.edit', 'terms'))
|
|
->assertOk();
|
|
});
|
|
|
|
test('admin can view privacy edit page', function () {
|
|
$this->actingAs($this->admin)
|
|
->get(route('admin.pages.edit', 'privacy'))
|
|
->assertOk();
|
|
});
|
|
|
|
test('admin can edit terms of service in Arabic', function () {
|
|
$page = Page::where('slug', 'terms')->first();
|
|
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'terms'])
|
|
->set('content_ar', '<p>شروط الخدمة الجديدة</p>')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
expect($page->fresh()->content_ar)->toContain('شروط الخدمة الجديدة');
|
|
});
|
|
|
|
test('admin can edit terms of service in English', function () {
|
|
$page = Page::where('slug', 'terms')->first();
|
|
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'terms'])
|
|
->set('content_en', '<p>New terms content</p>')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
expect($page->fresh()->content_en)->toContain('New terms content');
|
|
});
|
|
|
|
test('admin can edit privacy policy in Arabic', function () {
|
|
$page = Page::where('slug', 'privacy')->first();
|
|
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'privacy'])
|
|
->set('content_ar', '<p>سياسة الخصوصية الجديدة</p>')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
expect($page->fresh()->content_ar)->toContain('سياسة الخصوصية الجديدة');
|
|
});
|
|
|
|
test('admin can edit privacy policy in English', function () {
|
|
$page = Page::where('slug', 'privacy')->first();
|
|
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'privacy'])
|
|
->set('content_en', '<p>New privacy policy</p>')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
expect($page->fresh()->content_en)->toContain('New privacy policy');
|
|
});
|
|
|
|
test('admin can preview page content', function () {
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'terms'])
|
|
->assertSet('showPreview', false)
|
|
->call('togglePreview')
|
|
->assertSet('showPreview', true);
|
|
});
|
|
|
|
test('preview modal can be closed', function () {
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'terms'])
|
|
->call('togglePreview')
|
|
->assertSet('showPreview', true)
|
|
->call('closePreview')
|
|
->assertSet('showPreview', false);
|
|
});
|
|
|
|
test('updated_at timestamp changes on save', function () {
|
|
$page = Page::where('slug', 'terms')->first();
|
|
$originalTimestamp = $page->updated_at;
|
|
|
|
$this->travel(1)->minute();
|
|
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'terms'])
|
|
->set('content_en', '<p>Updated content</p>')
|
|
->call('save');
|
|
|
|
expect($page->fresh()->updated_at)->toBeGreaterThan($originalTimestamp);
|
|
});
|
|
|
|
test('html content is sanitized on save', function () {
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'terms'])
|
|
->set('content_en', '<script>alert("xss")</script><p>Safe content</p>')
|
|
->call('save');
|
|
|
|
$page = Page::where('slug', 'terms')->first();
|
|
expect($page->content_en)->not->toContain('<script>');
|
|
expect($page->content_en)->toContain('Safe content');
|
|
});
|
|
|
|
test('admin log created on page update', function () {
|
|
$page = Page::where('slug', 'terms')->first();
|
|
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'terms'])
|
|
->set('content_en', '<p>Updated content</p>')
|
|
->call('save');
|
|
|
|
expect(AdminLog::where('action', 'update')
|
|
->where('target_type', 'page')
|
|
->where('target_id', $page->id)
|
|
->exists())->toBeTrue();
|
|
});
|
|
|
|
test('language tabs switch correctly', function () {
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'terms'])
|
|
->assertSet('activeTab', 'ar')
|
|
->call('setTab', 'en')
|
|
->assertSet('activeTab', 'en')
|
|
->call('setTab', 'ar')
|
|
->assertSet('activeTab', 'ar');
|
|
});
|
|
|
|
test('empty content can be saved', function () {
|
|
$this->actingAs($this->admin);
|
|
|
|
Volt::test('admin.pages.edit', ['slug' => 'terms'])
|
|
->set('content_ar', '')
|
|
->set('content_en', '')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$page = Page::where('slug', 'terms')->first();
|
|
expect($page->content_ar)->toBe('');
|
|
expect($page->content_en)->toBe('');
|
|
});
|
|
|
|
// ===========================================
|
|
// Public Page Tests
|
|
// ===========================================
|
|
|
|
test('public can view terms page', function () {
|
|
Page::where('slug', 'terms')->update(['content_en' => '<p>Our terms</p>']);
|
|
|
|
$this->withSession(['locale' => 'en'])
|
|
->get('/page/terms')
|
|
->assertOk()
|
|
->assertSee('Our terms');
|
|
});
|
|
|
|
test('public can view privacy page', function () {
|
|
Page::where('slug', 'privacy')->update(['content_en' => '<p>Our privacy policy</p>']);
|
|
|
|
$this->withSession(['locale' => 'en'])
|
|
->get('/page/privacy')
|
|
->assertOk()
|
|
->assertSee('Our privacy policy');
|
|
});
|
|
|
|
test('public page shows last updated timestamp', function () {
|
|
$page = Page::where('slug', 'terms')->first();
|
|
|
|
$this->get('/page/terms')
|
|
->assertOk()
|
|
->assertSee($page->updated_at->format('M d, Y'));
|
|
});
|
|
|
|
test('invalid page slug returns 404', function () {
|
|
$this->get('/page/invalid-slug')
|
|
->assertNotFound();
|
|
});
|
|
|
|
test('legacy terms route redirects to new route', function () {
|
|
$this->get('/terms')
|
|
->assertRedirect('/page/terms');
|
|
});
|
|
|
|
test('legacy privacy route redirects to new route', function () {
|
|
$this->get('/privacy')
|
|
->assertRedirect('/page/privacy');
|
|
});
|
|
|
|
test('public page displays content in correct language based on locale', function () {
|
|
Page::where('slug', 'terms')->update([
|
|
'content_ar' => '<p>شروط الخدمة</p>',
|
|
'content_en' => '<p>Terms of Service</p>',
|
|
]);
|
|
|
|
// Test English
|
|
$this->withSession(['locale' => 'en'])
|
|
->get('/page/terms')
|
|
->assertSee('Terms of Service');
|
|
|
|
// Test Arabic
|
|
$this->withSession(['locale' => 'ar'])
|
|
->get('/page/terms')
|
|
->assertSee('شروط الخدمة');
|
|
});
|
|
|
|
// ===========================================
|
|
// Authorization Tests
|
|
// ===========================================
|
|
|
|
test('guest cannot access admin pages editor', function () {
|
|
$this->get(route('admin.pages.index'))
|
|
->assertRedirect(route('login'));
|
|
});
|
|
|
|
test('client cannot access admin pages editor', function () {
|
|
$client = User::factory()->individual()->create();
|
|
|
|
$this->actingAs($client)
|
|
->get(route('admin.pages.index'))
|
|
->assertForbidden();
|
|
});
|
|
|
|
test('guest cannot access admin pages edit', function () {
|
|
$this->get(route('admin.pages.edit', 'terms'))
|
|
->assertRedirect(route('login'));
|
|
});
|
|
|
|
test('client cannot access admin pages edit', function () {
|
|
$client = User::factory()->individual()->create();
|
|
|
|
$this->actingAs($client)
|
|
->get(route('admin.pages.edit', 'terms'))
|
|
->assertForbidden();
|
|
});
|
|
|
|
// ===========================================
|
|
// Page Model Tests
|
|
// ===========================================
|
|
|
|
test('page has localized title accessor', function () {
|
|
$page = Page::where('slug', 'terms')->first();
|
|
|
|
app()->setLocale('ar');
|
|
expect($page->getTitle())->toBe('شروط الخدمة');
|
|
|
|
app()->setLocale('en');
|
|
expect($page->getTitle())->toBe('Terms of Service');
|
|
});
|
|
|
|
test('page has localized content accessor', function () {
|
|
Page::where('slug', 'terms')->update([
|
|
'content_ar' => 'محتوى عربي',
|
|
'content_en' => 'English content',
|
|
]);
|
|
|
|
$page = Page::where('slug', 'terms')->first();
|
|
|
|
app()->setLocale('ar');
|
|
expect($page->getContent())->toBe('محتوى عربي');
|
|
|
|
app()->setLocale('en');
|
|
expect($page->getContent())->toBe('English content');
|
|
});
|
|
|
|
test('page content falls back to arabic when english is empty', function () {
|
|
Page::where('slug', 'terms')->update([
|
|
'content_ar' => 'محتوى عربي',
|
|
'content_en' => null,
|
|
]);
|
|
|
|
$page = Page::where('slug', 'terms')->first();
|
|
|
|
app()->setLocale('en');
|
|
// Falls back to Arabic content when English is null
|
|
expect($page->getContent())->toBe('محتوى عربي');
|
|
});
|