357 lines
12 KiB
PHP
357 lines
12 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace Uwil\Storage\Tests\Unit\Config;
|
||
|
|
|
||
|
|
use Uwil\Storage\Config\StorageServiceConfig;
|
||
|
|
use Uwil\Storage\Exceptions\UnexpectedStorageException;
|
||
|
|
use Uwil\Storage\Lib\ValueObjects\DiskName;
|
||
|
|
|
||
|
|
covers(StorageServiceConfig::class);
|
||
|
|
|
||
|
|
describe('StorageServiceConfig instantiation', function (): void {
|
||
|
|
it('can instantiate with valid configuration', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = ['local'];
|
||
|
|
$laravelExistingDisks = [(object) ['disk' => 'local', 'driver' => 'local']];
|
||
|
|
$allowedExtensions = ['jpg', 'png', 'pdf'];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$config = new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($config)->toBeInstanceOf(StorageServiceConfig::class)
|
||
|
|
->and($config->getDefaultDisk())->toBeInstanceOf(DiskName::class)
|
||
|
|
->and($config->getDefaultDisk()->value)->toBe('local')
|
||
|
|
->and($config->getEligibleDisks())->toHaveCount(1)
|
||
|
|
->and($config->getEligibleDisks()[0]->value)->toBe('local')
|
||
|
|
->and($config->getAllowedExtensions())->toBe(['jpg', 'png', 'pdf']);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('StorageServiceConfig disk validation', function (): void {
|
||
|
|
it('throws exception if default disk does not exist', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'non_existent_disk';
|
||
|
|
$eligibleDisks = ['local'];
|
||
|
|
$laravelExistingDisks = [(object) ['disk' => 'local', 'driver' => 'local']];
|
||
|
|
$allowedExtensions = ['pdf'];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
'Default disk does not exist'
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws exception if an eligible disk does not exist', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = ['local', 'unknown_disk'];
|
||
|
|
$laravelExistingDisks = [(object) ['disk' => 'local', 'driver' => 'local']];
|
||
|
|
$allowedExtensions = ['pdf'];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
'Eligible disk unknown_disk does not exist'
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws exception if a Laravel existing disk does not exist', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = ['local'];
|
||
|
|
$laravelExistingDisks = [
|
||
|
|
(object) ['disk' => 'local', 'driver' => 'local'],
|
||
|
|
(object) ['disk' => 'phantom_disk', 'driver' => 'local'],
|
||
|
|
];
|
||
|
|
$allowedExtensions = ['pdf'];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
'Laravel existing disk phantom_disk does not exist'
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws exception if laravelExistingDisks is empty', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = ['local'];
|
||
|
|
$laravelExistingDisks = [];
|
||
|
|
$allowedExtensions = ['pdf'];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
'Laravel existing disks cannot be empty'
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws exception if eligibleDisks is empty', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = [];
|
||
|
|
$laravelExistingDisks = [(object) ['disk' => 'local', 'driver' => 'local']];
|
||
|
|
$allowedExtensions = ['pdf'];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
'Eligible disks cannot be empty'
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws exception if no eligible disks exist in Laravel existing disks', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = ['public'];
|
||
|
|
$laravelExistingDisks = [(object) ['disk' => 'local', 'driver' => 'local']];
|
||
|
|
$allowedExtensions = ['pdf'];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
'No eligible disks exist in Laravel existing disks'
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws exception if default disk does not exist in Laravel existing disks', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = ['public'];
|
||
|
|
$laravelExistingDisks = [(object) ['disk' => 'public', 'driver' => 'local']];
|
||
|
|
$allowedExtensions = ['pdf'];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
'Default disk does not exist in Laravel existing disks'
|
||
|
|
);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('StorageServiceConfig allowed extensions validation', function (): void {
|
||
|
|
it('throws exception if allowedExtensions is empty', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = ['local'];
|
||
|
|
$laravelExistingDisks = [(object) ['disk' => 'local', 'driver' => 'local']];
|
||
|
|
$allowedExtensions = [];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
'Allowed extensions cannot be empty'
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('throws exception if an allowed extension is empty or invalid', function (string $invalidExtension): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = ['local'];
|
||
|
|
$laravelExistingDisks = [(object) ['disk' => 'local', 'driver' => 'local']];
|
||
|
|
$allowedExtensions = ['jpg', $invalidExtension];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
"Allowed extension {$invalidExtension} is not valid"
|
||
|
|
);
|
||
|
|
})->with([
|
||
|
|
'empty string' => '',
|
||
|
|
'whitespace' => ' ',
|
||
|
|
]);
|
||
|
|
|
||
|
|
it('throws exception if an allowed extension is forbidden (svg or xml)', function (string $forbidden): void {
|
||
|
|
// GIVEN
|
||
|
|
$defaultDisk = 'local';
|
||
|
|
$eligibleDisks = ['local'];
|
||
|
|
$laravelExistingDisks = [(object) ['disk' => 'local', 'driver' => 'local']];
|
||
|
|
$allowedExtensions = ['jpg', $forbidden];
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$action = fn () => new StorageServiceConfig(
|
||
|
|
defaultDisk: $defaultDisk,
|
||
|
|
eligibleDisks: $eligibleDisks,
|
||
|
|
laravelExistingDisks: $laravelExistingDisks,
|
||
|
|
allowedExtensions: $allowedExtensions
|
||
|
|
);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($action)->toThrow(
|
||
|
|
UnexpectedStorageException::class,
|
||
|
|
"Extension '{$forbidden}' is forbidden: XML/SVG sanitization is currently not supported."
|
||
|
|
);
|
||
|
|
})->with([
|
||
|
|
'svg' => 'svg',
|
||
|
|
'svg with .' => '.svg',
|
||
|
|
'SVG upper' => 'SVG',
|
||
|
|
'xml' => 'xml',
|
||
|
|
'xml with .' => '.xml',
|
||
|
|
'XML upper' => 'XML',
|
||
|
|
]);
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('StorageServiceConfig isDiskEligible', function (): void {
|
||
|
|
it('returns true when checking eligible disk with string or DiskName', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$config = new StorageServiceConfig(
|
||
|
|
defaultDisk: 'local',
|
||
|
|
eligibleDisks: ['local'],
|
||
|
|
laravelExistingDisks: [(object) ['disk' => 'local', 'driver' => 'local']],
|
||
|
|
allowedExtensions: ['pdf']
|
||
|
|
);
|
||
|
|
$diskNameVo = new DiskName('local', 'local');
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$eligibleFromString = $config->isDiskEligible('local');
|
||
|
|
$eligibleFromVo = $config->isDiskEligible($diskNameVo);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($eligibleFromString)->toBeTrue()
|
||
|
|
->and($eligibleFromVo)->toBeTrue();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('returns false when checking non-eligible disk', function (): void {
|
||
|
|
// GIVEN
|
||
|
|
$config = new StorageServiceConfig(
|
||
|
|
defaultDisk: 'local',
|
||
|
|
eligibleDisks: ['local'],
|
||
|
|
laravelExistingDisks: [(object) ['disk' => 'local', 'driver' => 'local']],
|
||
|
|
allowedExtensions: ['pdf']
|
||
|
|
);
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$isEligible = $config->isDiskEligible('public');
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($isEligible)->toBeFalse();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('StorageServiceConfig isExtensionAllowed', function (): void {
|
||
|
|
it('returns true for allowed extensions regardless of case or leading dot', function (string $extension): void {
|
||
|
|
// GIVEN
|
||
|
|
$config = new StorageServiceConfig(
|
||
|
|
defaultDisk: 'local',
|
||
|
|
eligibleDisks: ['local'],
|
||
|
|
laravelExistingDisks: [(object) ['disk' => 'local', 'driver' => 'local']],
|
||
|
|
allowedExtensions: ['jpg', 'png', 'pdf']
|
||
|
|
);
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$isAllowed = $config->isExtensionAllowed($extension);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($isAllowed)->toBeTrue();
|
||
|
|
})->with([
|
||
|
|
'exact' => 'jpg',
|
||
|
|
'with dot' => '.jpg',
|
||
|
|
'uppercase' => 'PNG',
|
||
|
|
'upper dot' => '.PDF',
|
||
|
|
]);
|
||
|
|
|
||
|
|
it('returns false for non-allowed extensions', function (string $extension): void {
|
||
|
|
// GIVEN
|
||
|
|
$config = new StorageServiceConfig(
|
||
|
|
defaultDisk: 'local',
|
||
|
|
eligibleDisks: ['local'],
|
||
|
|
laravelExistingDisks: [(object) ['disk' => 'local', 'driver' => 'local']],
|
||
|
|
allowedExtensions: ['jpg', 'png', 'pdf']
|
||
|
|
);
|
||
|
|
|
||
|
|
// WHEN
|
||
|
|
$isAllowed = $config->isExtensionAllowed($extension);
|
||
|
|
|
||
|
|
// THEN
|
||
|
|
expect($isAllowed)->toBeFalse();
|
||
|
|
})->with([
|
||
|
|
'exe' => 'exe',
|
||
|
|
'zip' => 'zip',
|
||
|
|
'svg' => 'svg',
|
||
|
|
'xml' => 'xml',
|
||
|
|
'.svg' => '.svg',
|
||
|
|
]);
|
||
|
|
});
|