Files
compras/tests/Feature/CandidateDocumentFormatsTest.php
2026-10-30 20:52:10 +02:00

36 lines
2.4 KiB
PHP

<?php
use App\Services\CandidateDocuments;
use Illuminate\Http\UploadedFile;
use Illuminate\Validation\ValidationException;
function candidateWordFixture(bool $unsafe = false): UploadedFile
{
$path = tempnam(sys_get_temp_dir(), 'sgc-word-');
$zip = new ZipArchive;
$zip->open($path, ZipArchive::OVERWRITE);
$zip->addFromString('[Content_Types].xml', '<?xml version="1.0"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/></Types>');
$zip->addFromString('word/document.xml', '<?xml version="1.0"?>'.($unsafe ? '<!DOCTYPE document [<!ENTITY x SYSTEM "file:///nonexistent">]>' : '').'<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w:body><w:p><w:r><w:t>'.str_repeat('Ficticio ', 300).'</w:t></w:r></w:p></w:body></w:document>');
$zip->setCompressionName('word/document.xml', ZipArchive::CM_STORE);
$zip->close();
try {
return UploadedFile::fake()->createWithContent('curriculo.docx', file_get_contents($path));
} finally {
unlink($path);
}
}
test('word documents must contain valid bounded document XML without external entity declarations', function () {
$definition = ['documents' => [['key' => 'cv', 'required' => true, 'formats' => ['docx'], 'max_kb' => 1024]]];
app(CandidateDocuments::class)->validate($definition, ['cv' => candidateWordFixture()]);
expect(fn () => app(CandidateDocuments::class)->validate($definition, ['cv' => candidateWordFixture(true)]))->toThrow(ValidationException::class);
});
test('an image must match its allowed format and content while an optional absent file remains optional', function () {
$definition = ['documents' => [['key' => 'photo', 'required' => false, 'formats' => ['png'], 'max_kb' => 1024]]];
app(CandidateDocuments::class)->validate($definition, []);
$png = base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jRZkAAAAASUVORK5CYII=');
app(CandidateDocuments::class)->validate($definition, ['photo' => UploadedFile::fake()->createWithContent('photo.png', $png)]);
expect(fn () => app(CandidateDocuments::class)->validate($definition, ['photo' => UploadedFile::fake()->createWithContent('photo.png', str_repeat('invalid', 200))]))->toThrow(ValidationException::class);
});