complet story 6.9 with qa tests
This commit is contained in:
@@ -0,0 +1,321 @@
|
||||
<?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('محتوى عربي');
|
||||
});
|
||||
Reference in New Issue
Block a user