172 lines
5.2 KiB
PHP
172 lines
5.2 KiB
PHP
<?php
|
||
|
||
use App\Enums\LegalDocumentType;
|
||
use App\Enums\UserRole;
|
||
use App\Filament\Resources\LegalDocuments\Pages\EditLegalDocument;
|
||
use App\Filament\Resources\LegalDocuments\Pages\ListLegalDocuments;
|
||
use App\Models\LegalDocument;
|
||
use App\Models\User;
|
||
use Filament\Facades\Filament;
|
||
use Filament\Forms\Components\Repeater;
|
||
use Filament\Forms\Components\TextInput;
|
||
use Filament\Tables\Columns\TextColumn;
|
||
use Filament\Tables\Filters\SelectFilter;
|
||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
use Livewire\Livewire;
|
||
|
||
uses(RefreshDatabase::class);
|
||
|
||
it('returns the active published legal document by slug', function (): void {
|
||
LegalDocument::factory()->create([
|
||
'slug' => 'privacy-policy',
|
||
'version' => 1,
|
||
'is_active' => false,
|
||
]);
|
||
|
||
LegalDocument::factory()->create([
|
||
'slug' => 'privacy-policy',
|
||
'version' => 2,
|
||
'is_active' => true,
|
||
'published_at' => now(),
|
||
'title' => [
|
||
'fr' => 'Confidentialité Bowli',
|
||
],
|
||
]);
|
||
|
||
$this
|
||
->getJson('/api/legal-documents/privacy-policy')
|
||
->assertOk()
|
||
->assertJsonPath('data.slug', 'privacy-policy')
|
||
->assertJsonPath('data.type', LegalDocumentType::PRIVACY_POLICY->value)
|
||
->assertJsonPath('data.version', 2)
|
||
->assertJsonPath('data.title.fr', 'Confidentialité Bowli')
|
||
->assertJsonPath('data.isActive', true);
|
||
});
|
||
|
||
it('does not expose inactive or unpublished legal documents', function (): void {
|
||
LegalDocument::factory()->inactive()->create([
|
||
'slug' => 'privacy-policy',
|
||
]);
|
||
|
||
LegalDocument::factory()->unpublished()->create([
|
||
'slug' => 'terms-of-service',
|
||
]);
|
||
|
||
$this->getJson('/api/legal-documents/privacy-policy')->assertNotFound();
|
||
$this->getJson('/api/legal-documents/terms-of-service')->assertNotFound();
|
||
});
|
||
|
||
it('lists active published legal documents with an optional type filter', function (): void {
|
||
LegalDocument::factory()->create([
|
||
'slug' => 'privacy-policy',
|
||
'type' => LegalDocumentType::PRIVACY_POLICY,
|
||
]);
|
||
|
||
LegalDocument::factory()->terms()->create([
|
||
'slug' => 'terms-of-service',
|
||
'type' => LegalDocumentType::TERMS,
|
||
]);
|
||
|
||
$this
|
||
->getJson('/api/legal-documents?type=terms')
|
||
->assertOk()
|
||
->assertJsonCount(1, 'data')
|
||
->assertJsonPath('data.0.slug', 'terms-of-service')
|
||
->assertJsonPath('data.0.type', LegalDocumentType::TERMS->value);
|
||
});
|
||
|
||
it('keeps only one active version per slug', function (): void {
|
||
$firstVersion = LegalDocument::factory()->create([
|
||
'slug' => 'privacy-policy',
|
||
'version' => 1,
|
||
'is_active' => true,
|
||
]);
|
||
|
||
LegalDocument::factory()->create([
|
||
'slug' => 'privacy-policy',
|
||
'version' => 2,
|
||
'is_active' => true,
|
||
]);
|
||
|
||
expect($firstVersion->fresh()->is_active)->toBeFalse();
|
||
});
|
||
|
||
it('exposes legal documents in filament', function (): void {
|
||
app()->setLocale('fr');
|
||
|
||
Filament::setCurrentPanel(Filament::getPanel('dashboard'));
|
||
|
||
$admin = User::factory()->create([
|
||
'role' => UserRole::ADMIN,
|
||
]);
|
||
|
||
$document = LegalDocument::factory()->create([
|
||
'slug' => 'privacy-policy',
|
||
]);
|
||
|
||
$this->actingAs($admin);
|
||
|
||
Livewire::test(ListLegalDocuments::class)
|
||
->assertTableColumnExists(
|
||
'slug',
|
||
fn (TextColumn $column): bool => $column->getLabel() === 'Slug',
|
||
)
|
||
->assertTableFilterExists(
|
||
'type',
|
||
fn (SelectFilter $filter): bool => $filter->getLabel() === 'Type'
|
||
&& $filter->getOptions() === [
|
||
'privacy_policy' => 'Politique de confidentialité',
|
||
'terms' => 'Conditions d’utilisation',
|
||
],
|
||
)
|
||
->assertSee('privacy-policy');
|
||
|
||
Livewire::test(EditLegalDocument::class, ['record' => $document->getKey()])
|
||
->assertFormFieldExists(
|
||
'title.fr',
|
||
null,
|
||
fn (TextInput $field): bool => $field->getLabel() === 'Titre',
|
||
)
|
||
->assertFormFieldExists(
|
||
'content.fr.intro',
|
||
null,
|
||
fn (Repeater $field): bool => $field->getLabel() === 'Introduction',
|
||
)
|
||
->assertFormFieldExists(
|
||
'content.fr.sections',
|
||
null,
|
||
fn (Repeater $field): bool => $field->getLabel() === 'Sections',
|
||
);
|
||
});
|
||
|
||
it('creates a new inactive unpublished version from filament', function (): void {
|
||
app()->setLocale('fr');
|
||
|
||
Filament::setCurrentPanel(Filament::getPanel('dashboard'));
|
||
|
||
$admin = User::factory()->create([
|
||
'role' => UserRole::ADMIN,
|
||
]);
|
||
$document = LegalDocument::factory()->create([
|
||
'slug' => 'privacy-policy',
|
||
'version' => 3,
|
||
'is_active' => true,
|
||
'published_at' => now(),
|
||
]);
|
||
|
||
$this->actingAs($admin);
|
||
|
||
Livewire::test(ListLegalDocuments::class)
|
||
->callTableAction('createNewVersion', $document);
|
||
|
||
$newVersion = LegalDocument::query()
|
||
->where('slug', 'privacy-policy')
|
||
->where('version', 4)
|
||
->firstOrFail();
|
||
|
||
expect($newVersion->title)->toBe($document->title)
|
||
->and($newVersion->content)->toBe($document->content)
|
||
->and($newVersion->is_active)->toBeFalse()
|
||
->and($newVersion->published_at)->toBeNull();
|
||
});
|