set('filesystems.disks.backup', [ 'driver' => 'local', 'root' => sys_get_temp_dir(), ]); return new StorageServiceConfig( defaultDisk: 'local', eligibleDisks: ['local', 'backup'], laravelExistingDisks: [ (object) ['disk' => 'local', 'driver' => 'local'], (object) ['disk' => 'backup', 'driver' => 'local'], ], allowedExtensions: ['pdf', 'txt', 'png'] ); } describe('StorageServiceImpl file validation', function (): void { it('delegates fileIsValid to FileSanitizer', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $file = UploadedFile::fake()->create('dummy.txt'); $sanitizer->shouldReceive('fileIsValid') ->once() ->with($file) ->andReturn(true); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $result = $service->fileIsValid($file); // THEN expect($result)->toBeTrue(); }); }); describe('StorageServiceImpl file existence', function (): void { it('checks file exists on default disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $filePath = new StorageFilePath('documents/report.pdf'); $gateway->shouldReceive('fileExists') ->once() ->with(\Mockery::on(fn (DiskName $d) => $d->value === 'local'), $filePath) ->andReturn(true); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $exists = $service->fileExists($filePath); // THEN expect($exists)->toBeTrue(); }); it('checks file exists on specified eligible disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $disk = new DiskName('backup', 'local'); $filePath = new StorageFilePath('documents/report.pdf'); $gateway->shouldReceive('fileExists') ->once() ->with($disk, $filePath) ->andReturn(true); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $exists = $service->fileExistsOnDisk($filePath, $disk); // THEN expect($exists)->toBeTrue(); }); it('throws exception if specified disk is not eligible during existence check', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $disk = new DiskName('public', 'local'); $filePath = new StorageFilePath('documents/report.pdf'); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $action = fn () => $service->fileExistsOnDisk($filePath, $disk); // THEN expect($action)->toThrow( UnexpectedStorageException::class, "Disk 'public' is not eligible for storage operations." ); }); }); describe('StorageServiceImpl getFile', function (): void { it('retrieves file stream from default disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $filePath = new StorageFilePath('archive/data.txt'); $expectedStream = FileStream::fromString('file data'); $gateway->shouldReceive('getFile') ->once() ->with(\Mockery::on(fn (DiskName $d) => $d->value === 'local'), $filePath) ->andReturn($expectedStream); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $result = $service->getFile($filePath); // THEN expect($result)->toBe($expectedStream); }); }); describe('StorageServiceImpl storing files', function (): void { it('stores sanitized file onto default disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $sanitizedFile = new SanitizedFile('doc.pdf', 'doc.pdf', FileStream::fromString('bytes')); $expectedPath = new StorageFilePath('2026/11/03/aa/doc-12345678.pdf'); $gateway->shouldReceive('storeFile') ->once() ->with(\Mockery::on(fn (DiskName $d) => $d->value === 'local'), $sanitizedFile) ->andReturn($expectedPath); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $path = $service->storeSanitized($sanitizedFile); // THEN expect($path)->toBe($expectedPath); }); it('stores sanitized file onto specified eligible disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $disk = new DiskName('backup', 'local'); $sanitizedFile = new SanitizedFile('doc.pdf', 'doc.pdf', FileStream::fromString('bytes')); $expectedPath = new StorageFilePath('uuid.pdf'); $gateway->shouldReceive('storeFile') ->once() ->with($disk, $sanitizedFile) ->andReturn($expectedPath); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $path = $service->storeSanitizedOntoDisk($sanitizedFile, $disk); // THEN expect($path)->toBe($expectedPath); }); it('throws exception if storing sanitized file onto non-eligible disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $disk = new DiskName('public', 'local'); $sanitizedFile = new SanitizedFile('doc.pdf', 'doc.pdf', FileStream::fromString('bytes')); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $action = fn () => $service->storeSanitizedOntoDisk($sanitizedFile, $disk); // THEN expect($action)->toThrow(UnexpectedStorageException::class, "Disk 'public' is not eligible for storage operations."); }); it('stores uploaded file onto default disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $uploadedFile = UploadedFile::fake()->create('file.pdf'); $sanitizedFile = new SanitizedFile('file.pdf', 'file.pdf', FileStream::fromString('pdf')); $expectedPath = new StorageFilePath('stored/path.pdf'); $sanitizer->shouldReceive('sanitizeUploaded') ->once() ->with($uploadedFile) ->andReturn($sanitizedFile); $gateway->shouldReceive('storeFile') ->once() ->with(\Mockery::on(fn (DiskName $d) => $d->value === 'local'), $sanitizedFile) ->andReturn($expectedPath); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $path = $service->storeUploaded($uploadedFile); // THEN expect($path)->toBe($expectedPath); }); it('stores uploaded file onto specified eligible disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $disk = new DiskName('backup', 'local'); $uploadedFile = UploadedFile::fake()->create('file.pdf'); $sanitizedFile = new SanitizedFile('file.pdf', 'file.pdf', FileStream::fromString('pdf')); $expectedPath = new StorageFilePath('uuid.pdf'); $sanitizer->shouldReceive('sanitizeUploaded') ->once() ->with($uploadedFile) ->andReturn($sanitizedFile); $gateway->shouldReceive('storeFile') ->once() ->with($disk, $sanitizedFile) ->andReturn($expectedPath); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $path = $service->storeUploadedOntoDisk($uploadedFile, $disk); // THEN expect($path)->toBe($expectedPath); }); it('stores SplFileObject onto default disk', function (): void { // GIVEN $tempFile = tempnam(sys_get_temp_dir(), 'test_spl_svc_') . '.txt'; file_put_contents($tempFile, 'spl content'); $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $splFile = new \SplFileObject($tempFile); $sanitizedFile = new SanitizedFile('file.txt', 'file.txt', FileStream::fromString('txt')); $expectedPath = new StorageFilePath('stored/spl.txt'); $sanitizer->shouldReceive('sanitizeFile') ->once() ->with($splFile) ->andReturn($sanitizedFile); $gateway->shouldReceive('storeFile') ->once() ->with(\Mockery::on(fn (DiskName $d) => $d->value === 'local'), $sanitizedFile) ->andReturn($expectedPath); $service = new StorageServiceImpl($config, $sanitizer, $gateway); try { // WHEN $path = $service->storeFile($splFile); // THEN expect($path)->toBe($expectedPath); } finally { unset($splFile); if (file_exists($tempFile)) { unlink($tempFile); } } }); it('stores SplFileObject onto specified eligible disk', function (): void { // GIVEN $tempFile = tempnam(sys_get_temp_dir(), 'test_spl_disk_') . '.txt'; file_put_contents($tempFile, 'spl disk content'); $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $disk = new DiskName('backup', 'local'); $splFile = new \SplFileObject($tempFile); $sanitizedFile = new SanitizedFile('file.txt', 'file.txt', FileStream::fromString('txt')); $expectedPath = new StorageFilePath('s3/spl.txt'); $sanitizer->shouldReceive('sanitizeFile') ->once() ->with($splFile) ->andReturn($sanitizedFile); $gateway->shouldReceive('storeFile') ->once() ->with($disk, $sanitizedFile) ->andReturn($expectedPath); $service = new StorageServiceImpl($config, $sanitizer, $gateway); try { // WHEN $path = $service->storeFileOntoDisk($splFile, $disk); // THEN expect($path)->toBe($expectedPath); } finally { unset($splFile); if (file_exists($tempFile)) { unlink($tempFile); } } }); }); describe('StorageServiceImpl file removal', function (): void { it('removes file from default disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $filePath = new StorageFilePath('to_delete.txt'); $gateway->shouldReceive('deleteFile') ->once() ->with(\Mockery::on(fn (DiskName $d) => $d->value === 'local'), $filePath) ->andReturn(true); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $result = $service->remove($filePath); // THEN expect($result)->toBeTrue(); }); it('removes file from specified eligible disk', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $disk = new DiskName('backup', 'local'); $filePath = new StorageFilePath('to_delete.txt'); $gateway->shouldReceive('deleteFile') ->once() ->with($disk, $filePath) ->andReturn(true); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $result = $service->removeFromDisk($filePath, $disk); // THEN expect($result)->toBeTrue(); }); it('throws exception if specified disk is not eligible during removal', function (): void { // GIVEN $config = createServiceConfig(); $sanitizer = \Mockery::mock(FileSanitizer::class); $gateway = \Mockery::mock(StorageGateway::class); $disk = new DiskName('public', 'local'); $filePath = new StorageFilePath('to_delete.txt'); $service = new StorageServiceImpl($config, $sanitizer, $gateway); // WHEN $action = fn () => $service->removeFromDisk($filePath, $disk); // THEN expect($action)->toThrow(UnexpectedStorageException::class, "Disk 'public' is not eligible for storage operations."); }); });