- Implement tests for DiskName instantiation and validation. - Add tests for FileStream instantiation and methods. - Create tests for SanitizedFile instantiation and validation. - Introduce TestDiskBackedEnum and TestDiskUnitEnum for testing purposes.
162 lines
5.3 KiB
PHP
162 lines
5.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Uwil\Storage\Tests\Unit\Lib\ValueObjects;
|
|
|
|
use Uwil\Storage\Exceptions\UnexpectedStorageException;
|
|
use Uwil\Storage\Lib\ValueObjects\FileStream;
|
|
use Uwil\Storage\Lib\ValueObjects\SanitizedFile;
|
|
|
|
covers(SanitizedFile::class);
|
|
|
|
describe('SanitizedFile instantiation', function (): void {
|
|
it('can instantiate with all valid parameters', function (): void {
|
|
// GIVEN
|
|
$stream = FileStream::fromString('file content');
|
|
$originalName = 'My Document (1).pdf';
|
|
$sanitizedName = 'my-document-1.pdf';
|
|
$mimeType = 'application/pdf';
|
|
$size = 12;
|
|
|
|
// WHEN
|
|
$vo = new SanitizedFile(
|
|
originalName: $originalName,
|
|
sanitizedName: $sanitizedName,
|
|
contents: $stream,
|
|
mimeType: $mimeType,
|
|
size: $size
|
|
);
|
|
|
|
// THEN
|
|
expect($vo)->toBeInstanceOf(SanitizedFile::class)
|
|
->and($vo->originalName)->toBe($originalName)
|
|
->and($vo->sanitizedName)->toBe($sanitizedName)
|
|
->and($vo->contents)->toBe($stream)
|
|
->and($vo->mimeType)->toBe($mimeType)
|
|
->and($vo->size)->toBe($size);
|
|
});
|
|
|
|
it('can instantiate with default optional parameters as null', function (): void {
|
|
// GIVEN
|
|
$stream = FileStream::fromString('another content');
|
|
$originalName = 'photo.png';
|
|
$sanitizedName = 'photo.png';
|
|
|
|
// WHEN
|
|
$vo = new SanitizedFile(
|
|
originalName: $originalName,
|
|
sanitizedName: $sanitizedName,
|
|
contents: $stream
|
|
);
|
|
|
|
// THEN
|
|
expect($vo)->toBeInstanceOf(SanitizedFile::class)
|
|
->and($vo->originalName)->toBe($originalName)
|
|
->and($vo->sanitizedName)->toBe($sanitizedName)
|
|
->and($vo->contents)->toBe($stream)
|
|
->and($vo->mimeType)->toBeNull()
|
|
->and($vo->size)->toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('SanitizedFile originalName validation', function (): void {
|
|
it('throws exception if originalName is empty or only whitespace', function (string $invalidName): void {
|
|
// GIVEN
|
|
$stream = FileStream::fromString('dummy');
|
|
$sanitizedName = 'valid-name.txt';
|
|
|
|
// WHEN
|
|
$action = fn () => new SanitizedFile(
|
|
originalName: $invalidName,
|
|
sanitizedName: $sanitizedName,
|
|
contents: $stream
|
|
);
|
|
|
|
// THEN
|
|
expect($action)->toThrow(
|
|
UnexpectedStorageException::class,
|
|
'Original name cannot be empty.'
|
|
);
|
|
})->with([
|
|
'empty string' => '',
|
|
'spaces only' => ' ',
|
|
'tabs and newlines' => "\t \n \r",
|
|
]);
|
|
});
|
|
|
|
describe('SanitizedFile sanitizedName validation', function (): void {
|
|
it('throws exception if sanitizedName is empty or only whitespace', function (string $invalidName): void {
|
|
// GIVEN
|
|
$stream = FileStream::fromString('dummy');
|
|
$originalName = 'valid_original.txt';
|
|
|
|
// WHEN
|
|
$action = fn () => new SanitizedFile(
|
|
originalName: $originalName,
|
|
sanitizedName: $invalidName,
|
|
contents: $stream
|
|
);
|
|
|
|
// THEN
|
|
expect($action)->toThrow(
|
|
UnexpectedStorageException::class,
|
|
'Sanitized name cannot be empty.'
|
|
);
|
|
})->with([
|
|
'empty string' => '',
|
|
'spaces only' => ' ',
|
|
'tabs and newlines' => "\t \n",
|
|
]);
|
|
|
|
it('throws exception if sanitizedName contains invalid characters', function (string $invalidName): void {
|
|
// GIVEN
|
|
$stream = FileStream::fromString('dummy');
|
|
$originalName = 'original.txt';
|
|
|
|
// WHEN
|
|
$action = fn () => new SanitizedFile(
|
|
originalName: $originalName,
|
|
sanitizedName: $invalidName,
|
|
contents: $stream
|
|
);
|
|
|
|
// THEN
|
|
expect($action)->toThrow(
|
|
UnexpectedStorageException::class,
|
|
'Sanitized name contains invalid characters.'
|
|
);
|
|
})->with([
|
|
'contains space' => 'file name.txt',
|
|
'contains slash' => 'dir/file.txt',
|
|
'contains backslash' => 'dir\\file.txt',
|
|
'contains question' => 'file?.txt',
|
|
'contains hash' => 'file#name.txt',
|
|
'contains at symbol' => 'file@name.txt',
|
|
'contains accented é' => 'été.pdf',
|
|
'contains parenthesis' => 'file(1).pdf',
|
|
'contains emoji' => 'file🔥.txt',
|
|
]);
|
|
|
|
it('accepts valid sanitizedName containing allowed characters', function (string $validName): void {
|
|
// GIVEN
|
|
$stream = FileStream::fromString('dummy');
|
|
$originalName = 'original.txt';
|
|
|
|
// WHEN
|
|
$vo = new SanitizedFile(
|
|
originalName: $originalName,
|
|
sanitizedName: $validName,
|
|
contents: $stream
|
|
);
|
|
|
|
// THEN
|
|
expect($vo)->toBeInstanceOf(SanitizedFile::class)
|
|
->and($vo->sanitizedName)->toBe($validName);
|
|
})->with([
|
|
'lowercase alphanumeric' => 'abc123.txt',
|
|
'uppercase letters' => 'FILE_NAME.PDF',
|
|
'hyphens and dots' => 'my-custom-file.tar.gz',
|
|
'underscores' => 'report_final_2026.csv',
|
|
]);
|
|
});
|