Certificate manager built on Laravel 13, Livewire 4, and Flux. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
123 lines
4 KiB
PHP
123 lines
4 KiB
PHP
<?php
|
|
|
|
use App\Models\User;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Livewire\Livewire;
|
|
|
|
beforeEach(function () {
|
|
Storage::fake('local');
|
|
});
|
|
|
|
test('the create page is displayed', function () {
|
|
$this->actingAs(User::factory()->create());
|
|
|
|
$this->get(route('certificates.create'))->assertOk();
|
|
});
|
|
|
|
test('a certificate is stored on the private disk', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
|
|
Livewire::test('pages::certificates.create')
|
|
->set('file', UploadedFile::fake()->create('cert.pdf', 200, 'application/pdf'))
|
|
->set('title', 'My Diploma')
|
|
->set('expires_at', now()->addYear()->toDateString())
|
|
->call('save')
|
|
->assertHasNoErrors()
|
|
->assertRedirect(route('certificates.index'));
|
|
|
|
$certificate = $user->certificates()->firstOrFail();
|
|
|
|
expect($certificate->title)->toBe('My Diploma')
|
|
->and($certificate->file_path)->toStartWith('certificates/'.$user->id.'/');
|
|
|
|
Storage::disk('local')->assertExists($certificate->file_path);
|
|
});
|
|
|
|
test('certificate details are stored', function () {
|
|
$user = User::factory()->create();
|
|
$this->actingAs($user);
|
|
|
|
Livewire::test('pages::certificates.create')
|
|
->set('file', UploadedFile::fake()->create('cert.pdf', 200, 'application/pdf'))
|
|
->set('title', 'First Aid')
|
|
->set('issuer', 'Red Cross')
|
|
->set('certificate_number', 'RC-2026-001')
|
|
->set('issued_at', '2026-01-10')
|
|
->set('expires_at', '2028-01-10')
|
|
->set('notes', 'Renewed on-site.')
|
|
->call('save')
|
|
->assertHasNoErrors();
|
|
|
|
$certificate = $user->certificates()->firstOrFail();
|
|
|
|
expect($certificate->issuer)->toBe('Red Cross')
|
|
->and($certificate->certificate_number)->toBe('RC-2026-001')
|
|
->and($certificate->issued_at->toDateString())->toBe('2026-01-10')
|
|
->and($certificate->notes)->toBe('Renewed on-site.');
|
|
});
|
|
|
|
test('the issue date cannot be after the expiry date', function () {
|
|
$this->actingAs(User::factory()->create());
|
|
|
|
Livewire::test('pages::certificates.create')
|
|
->set('file', UploadedFile::fake()->create('cert.pdf', 200, 'application/pdf'))
|
|
->set('title', 'Bad Dates')
|
|
->set('issued_at', '2028-01-10')
|
|
->set('expires_at', '2026-01-10')
|
|
->call('save')
|
|
->assertHasErrors(['issued_at']);
|
|
});
|
|
|
|
test('an invalid file type is rejected', function () {
|
|
$this->actingAs(User::factory()->create());
|
|
|
|
Livewire::test('pages::certificates.create')
|
|
->set('file', UploadedFile::fake()->create('malware.exe', 100))
|
|
->assertHasErrors(['file']);
|
|
});
|
|
|
|
test('ocr suggestions pre-fill empty fields on upload', function () {
|
|
Http::fake([
|
|
'custom-ocr.klippa.com/*' => Http::response([
|
|
'data' => ['parsed' => [
|
|
'document_subject' => 'Scanned Title',
|
|
'expiry_date' => '2028-01-15',
|
|
]],
|
|
]),
|
|
]);
|
|
|
|
$user = User::factory()->create();
|
|
$user->ocr_provider = 'klippa';
|
|
$user->ocr_api_key = 'key';
|
|
$user->save();
|
|
|
|
$this->actingAs($user);
|
|
|
|
Livewire::test('pages::certificates.create')
|
|
->set('file', UploadedFile::fake()->create('cert.pdf', 200, 'application/pdf'))
|
|
->assertSet('title', 'Scanned Title')
|
|
->assertSet('expires_at', '2028-01-15');
|
|
});
|
|
|
|
test('ocr does not overwrite fields the user already filled', function () {
|
|
Http::fake([
|
|
'custom-ocr.klippa.com/*' => Http::response([
|
|
'data' => ['parsed' => ['document_subject' => 'Scanned Title']],
|
|
]),
|
|
]);
|
|
|
|
$user = User::factory()->create();
|
|
$user->ocr_provider = 'klippa';
|
|
$user->ocr_api_key = 'key';
|
|
$user->save();
|
|
|
|
$this->actingAs($user);
|
|
|
|
Livewire::test('pages::certificates.create')
|
|
->set('title', 'My Own Title')
|
|
->set('file', UploadedFile::fake()->create('cert.pdf', 200, 'application/pdf'))
|
|
->assertSet('title', 'My Own Title');
|
|
});
|