ldc-file-storage-service/tests/Unit/Lib/PathGenerators/UuidPathGeneratorTest.php
Jérémy Munsch dcfec3de04
test(DateHashPathGenerator): add unit tests for path generation
Added comprehensive unit tests for DateHashPathGenerator to validate path generation
with and without directories, ensuring unique paths for identical files and proper
slugging of filenames.
2026-11-03 17:04:29 +01:00

140 lines
5 KiB
PHP

<?php
declare(strict_types=1);
namespace Uwil\Storage\Tests\Unit\Lib\PathGenerators;
use Illuminate\Support\Str;
use Uwil\Storage\Lib\PathGenerators\UuidPathGenerator;
use Uwil\Storage\Lib\ValueObjects\DiskName;
use Uwil\Storage\Lib\ValueObjects\FileStream;
use Uwil\Storage\Lib\ValueObjects\SanitizedFile;
use Uwil\Storage\Lib\ValueObjects\StorageFilePath;
covers(UuidPathGenerator::class);
describe('UuidPathGenerator generation without directory', function (): void {
it('generates a storage file path containing a valid UUID and extension', function (): void {
// GIVEN
$generator = new UuidPathGenerator();
$disk = new DiskName('local', 'local');
$sanitizedFile = new SanitizedFile(
originalName: 'picture.png',
sanitizedName: 'picture.png',
contents: FileStream::fromString('image bytes')
);
// WHEN
$result = $generator->generate($disk, $sanitizedFile);
// THEN
expect($result)->toBeInstanceOf(StorageFilePath::class);
$filename = $result->value;
expect($filename)->toMatch('#^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.png$#');
$uuidOnly = pathinfo($filename, PATHINFO_FILENAME);
expect(Str::isUuid($uuidOnly))->toBeTrue();
});
it('generates a storage file path without extension when file has no extension', function (): void {
// GIVEN
$generator = new UuidPathGenerator();
$disk = new DiskName('local', 'local');
$sanitizedFile = new SanitizedFile(
originalName: 'DOCKERFILE',
sanitizedName: 'DOCKERFILE',
contents: FileStream::fromString('FROM php:8.5')
);
// WHEN
$result = $generator->generate($disk, $sanitizedFile);
// THEN
expect($result)->toBeInstanceOf(StorageFilePath::class)
->and(Str::isUuid($result->value))->toBeTrue();
});
it('generates unique paths on successive calls for the same file', function (): void {
// GIVEN
$generator = new UuidPathGenerator();
$disk = new DiskName('local', 'local');
$sanitizedFile = new SanitizedFile(
originalName: 'data.json',
sanitizedName: 'data.json',
contents: FileStream::fromString('{}')
);
// WHEN
$path1 = $generator->generate($disk, $sanitizedFile);
$path2 = $generator->generate($disk, $sanitizedFile);
// THEN
expect($path1->value)->not->toBe($path2->value);
});
});
describe('UuidPathGenerator generation with directory', function (): void {
it('prepends the given directory to the generated UUID filename', function (): void {
// GIVEN
$generator = new UuidPathGenerator();
$disk = new DiskName('local', 'local');
$sanitizedFile = new SanitizedFile(
originalName: 'invoice.pdf',
sanitizedName: 'invoice.pdf',
contents: FileStream::fromString('PDF DATA')
);
$directory = 'billing/invoices';
// WHEN
$result = $generator->generate($disk, $sanitizedFile, $directory);
// THEN
expect($result)->toBeInstanceOf(StorageFilePath::class)
->and($result->value)->toStartWith('billing/invoices/')
->and($result->value)->toMatch('#^billing/invoices/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.pdf$#');
});
it('trims leading and trailing slashes from the directory', function (string $directory): void {
// GIVEN
$generator = new UuidPathGenerator();
$disk = new DiskName('local', 'local');
$sanitizedFile = new SanitizedFile(
originalName: 'file.txt',
sanitizedName: 'file.txt',
contents: FileStream::fromString('text')
);
// WHEN
$result = $generator->generate($disk, $sanitizedFile, $directory);
// THEN
expect($result->value)->toStartWith('custom/path/');
})->with([
'leading slash' => '/custom/path',
'trailing slash' => 'custom/path/',
'both slashes' => '/custom/path/',
'multiple outer slashes' => '///custom/path///',
]);
it('ignores empty or slash-only directory', function (string $directory): void {
// GIVEN
$generator = new UuidPathGenerator();
$disk = new DiskName('local', 'local');
$sanitizedFile = new SanitizedFile(
originalName: 'file.txt',
sanitizedName: 'file.txt',
contents: FileStream::fromString('text')
);
// WHEN
$result = $generator->generate($disk, $sanitizedFile, $directory);
// THEN
expect($result->value)->toMatch('#^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.txt$#');
})->with([
'empty string' => '',
'single slash' => '/',
'multi slashes' => '///',
]);
});