PHPUnit config (phpunit.dist.xml, bin/phpunit, bootstrap.php), PHP CS Fixer config, .editorconfig. Separate .env.dev/.env.test templates. Ollama tunnel setup script. Architecture and plan docs. Updated application-layer unit tests to match current service signatures. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
88 lines
3.1 KiB
PHP
88 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Unit\Application\Storage;
|
|
|
|
use App\Domain\Storage\Repository\StoragePathRepositoryInterface;
|
|
use App\Domain\Storage\StoragePath;
|
|
use App\Infrastructure\Storage\LocalStorageManager;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class LocalStorageManagerTest extends TestCase
|
|
{
|
|
private StoragePathRepositoryInterface&MockObject $repo;
|
|
private LocalStorageManager $manager;
|
|
private string $tmpFile;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->repo = $this->createMock(StoragePathRepositoryInterface::class);
|
|
$this->manager = new LocalStorageManager($this->repo);
|
|
$this->tmpFile = sys_get_temp_dir().'/test-upload-'.uniqid().'.jpg';
|
|
file_put_contents($this->tmpFile, str_repeat('x', 100));
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
if (file_exists($this->tmpFile)) {
|
|
unlink($this->tmpFile);
|
|
}
|
|
}
|
|
|
|
public function testStorePicksActivePathWithQuota(): void
|
|
{
|
|
$path = new StoragePath('Main', sys_get_temp_dir().'/storage-test-'.uniqid(), 1_000_000, 10);
|
|
mkdir($path->getBasePath(), recursive: true);
|
|
|
|
$this->repo->expects($this->once())
|
|
->method('findActiveSortedByPriority')
|
|
->willReturn([$path]);
|
|
|
|
$stored = $this->manager->store($this->tmpFile, 'photo.jpg');
|
|
|
|
$this->assertSame($path->getId()->toRfc4122(), $stored->storagePath->getId()->toRfc4122());
|
|
$this->assertStringEndsWith('.jpg', $stored->filename);
|
|
$this->assertFileExists($path->getBasePath().'/'.$stored->filename);
|
|
|
|
// cleanup
|
|
unlink($path->getBasePath().'/'.$stored->filename);
|
|
rmdir($path->getBasePath());
|
|
}
|
|
|
|
public function testThrowsWhenNoActivePath(): void
|
|
{
|
|
$this->repo->method('findActiveSortedByPriority')->willReturn([]);
|
|
|
|
$this->expectException(\RuntimeException::class);
|
|
$this->expectExceptionMessage('No active storage path');
|
|
|
|
$this->manager->store($this->tmpFile, 'photo.jpg');
|
|
}
|
|
|
|
public function testSkipsFullPathAndUsesNext(): void
|
|
{
|
|
$fullPath = new StoragePath('Full', sys_get_temp_dir().'/full-'.uniqid(), 50, 20);
|
|
$okPath = new StoragePath('OK', sys_get_temp_dir().'/ok-'.uniqid(), 1_000_000, 10);
|
|
mkdir($fullPath->getBasePath(), recursive: true);
|
|
mkdir($okPath->getBasePath(), recursive: true);
|
|
|
|
// fullPath quota (50 bytes) is less than file size (100 bytes) — skip it
|
|
$this->repo->method('findActiveSortedByPriority')->willReturn([$fullPath, $okPath]);
|
|
|
|
$stored = $this->manager->store($this->tmpFile, 'photo.jpg');
|
|
|
|
$this->assertSame($okPath->getId()->toRfc4122(), $stored->storagePath->getId()->toRfc4122());
|
|
|
|
unlink($okPath->getBasePath().'/'.$stored->filename);
|
|
rmdir($fullPath->getBasePath());
|
|
rmdir($okPath->getBasePath());
|
|
}
|
|
|
|
public function testGetFullPath(): void
|
|
{
|
|
$path = new StoragePath('Main', '/srv/storage', 1_000_000, 10);
|
|
$this->assertSame('/srv/storage/photo.jpg', $this->manager->getFullPath($path, 'photo.jpg'));
|
|
}
|
|
}
|