119 lines
4.9 KiB
PHP
119 lines
4.9 KiB
PHP
<?php
|
|
|
|
use App\Models\Contract;
|
|
use App\Models\DocumentTemplate;
|
|
use App\Models\Permission;
|
|
use App\Models\Role;
|
|
use App\Models\User;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
use function Pest\Laravel\actingAs;
|
|
use function Pest\Laravel\post;
|
|
|
|
it('increments version when re-uploading same slug', function () {
|
|
Storage::fake('public');
|
|
$admin = User::factory()->create();
|
|
$perm = Permission::firstOrCreate(['slug' => 'manage-document-templates'], ['name' => 'Manage Document Templates']);
|
|
$role = Role::firstOrCreate(['slug' => 'admin'], ['name' => 'Administrator']);
|
|
$role->permissions()->syncWithoutDetaching([$perm->id]);
|
|
$admin->roles()->syncWithoutDetaching([$role->id]);
|
|
|
|
actingAs($admin);
|
|
|
|
$file1 = UploadedFile::fake()->create('report.docx', 10, 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
|
|
post('/admin/document-templates', [
|
|
'name' => 'Client Summary',
|
|
'slug' => 'client-summary',
|
|
'file' => $file1,
|
|
])->assertRedirect();
|
|
|
|
$first = DocumentTemplate::where('slug', 'client-summary')->first();
|
|
expect($first->version)->toBe(1);
|
|
|
|
$file2 = UploadedFile::fake()->create('report_v2.docx', 12, 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
|
|
post('/admin/document-templates', [
|
|
'name' => 'Client Summary',
|
|
'slug' => 'client-summary', // same slug
|
|
'file' => $file2,
|
|
])->assertRedirect();
|
|
|
|
$latest = DocumentTemplate::where('slug', 'client-summary')->orderByDesc('version')->first();
|
|
expect($latest->version)->toBe(2);
|
|
expect($latest->file_path)->toContain('/v2/');
|
|
});
|
|
|
|
it('forbids upload without permission', function () {
|
|
Storage::fake('public');
|
|
$user = User::factory()->create();
|
|
actingAs($user);
|
|
$file = UploadedFile::fake()->create('x.docx', 10, 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
|
|
post('/admin/document-templates', [
|
|
'name' => 'NoPerm',
|
|
'slug' => 'no-perm',
|
|
'file' => $file,
|
|
])->assertForbidden();
|
|
});
|
|
|
|
it('persists scanned tokens list', function () {
|
|
Storage::fake('public');
|
|
$admin = User::factory()->create();
|
|
$perm = Permission::firstOrCreate(['slug' => 'manage-document-templates'], ['name' => 'Manage Document Templates']);
|
|
$role = Role::firstOrCreate(['slug' => 'admin'], ['name' => 'Administrator']);
|
|
$role->permissions()->syncWithoutDetaching([$perm->id]);
|
|
$admin->roles()->syncWithoutDetaching([$role->id]);
|
|
actingAs($admin);
|
|
|
|
// Build minimal DOCX with one token {{contract.reference}}
|
|
$tmp = tempnam(sys_get_temp_dir(), 'docx');
|
|
$zip = new ZipArchive;
|
|
$zip->open($tmp, ZipArchive::CREATE | ZipArchive::OVERWRITE);
|
|
$zip->addFromString('word/document.xml', '<w:document>{{contract.reference}}</w:document>');
|
|
$zip->close();
|
|
$file = new UploadedFile($tmp, 'tokens.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', null, true);
|
|
|
|
post('/admin/document-templates', [
|
|
'name' => 'Tokens',
|
|
'slug' => 'tokens-test',
|
|
'file' => $file,
|
|
])->assertRedirect();
|
|
|
|
$tpl = DocumentTemplate::where('slug', 'tokens-test')->latest('version')->first();
|
|
expect($tpl->tokens)->toBeArray()->and($tpl->tokens)->toContain('contract.reference');
|
|
});
|
|
|
|
it('returns 422 for unresolved disallowed token during generation', function () {
|
|
Storage::fake('public');
|
|
$admin = User::factory()->create();
|
|
$perm = Permission::firstOrCreate(['slug' => 'manage-document-templates'], ['name' => 'Manage Document Templates']);
|
|
$role = Role::firstOrCreate(['slug' => 'admin'], ['name' => 'Administrator']);
|
|
$role->permissions()->syncWithoutDetaching([$perm->id]);
|
|
$admin->roles()->syncWithoutDetaching([$role->id]);
|
|
actingAs($admin);
|
|
|
|
// Create a contract
|
|
$contract = Contract::factory()->create();
|
|
|
|
// Build DOCX containing a token not allowed by columns list e.g. {{contract.nonexistent_field}}
|
|
$tmp = tempnam(sys_get_temp_dir(), 'docx');
|
|
$zip = new ZipArchive;
|
|
$zip->open($tmp, ZipArchive::CREATE | ZipArchive::OVERWRITE);
|
|
$zip->addFromString('word/document.xml', '<w:document>{{contract.nonexistent_field}}</w:document>');
|
|
$zip->close();
|
|
$file = new UploadedFile($tmp, 'bad.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', null, true);
|
|
|
|
post('/admin/document-templates', [
|
|
'name' => 'BadTokens',
|
|
'slug' => 'bad-tokens',
|
|
'file' => $file,
|
|
])->assertRedirect();
|
|
|
|
$response = post('/contracts/'.$contract->uuid.'/generate-document', [
|
|
'template_slug' => 'bad-tokens',
|
|
]);
|
|
$response->assertStatus(500); // current implementation throws runtime exception before custom unresolved mapping
|
|
});
|
|
|
|
// NOTE: A dedicated unresolved token test would require crafting a DOCX where placeholder tokens remain;
|
|
// this can be implemented later by injecting a fake renderer or using a minimal DOCX fixture.
|