test filesystem abstraction

This commit is contained in:
Yisroel Baum 2026-06-26 08:23:17 +03:00
parent bc7937d2b3
commit be2c51bfb7
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
10 changed files with 66 additions and 78 deletions

View file

@ -3,9 +3,9 @@
namespace Tests\Fakes; namespace Tests\Fakes;
use App\Shared\Files\FileToUpload; use App\Shared\Files\FileToUpload;
use App\Shared\Files\FileUploader; use App\Shared\Files\Filesystem;
class FakeFileUploader implements FileUploader class FakeFilesystem implements Filesystem
{ {
/** /**
* @var array<int, array{file: FileToUpload, folder: string}> * @var array<int, array{file: FileToUpload, folder: string}>
@ -17,6 +17,16 @@ class FakeFileUploader implements FileUploader
*/ */
public array $deletedPaths = []; public array $deletedPaths = [];
/**
* @var string[]
*/
public array $readPaths = [];
/**
* @var array<string, string>
*/
private array $filesByPath = [];
public function upload(FileToUpload $file, string $folder): string public function upload(FileToUpload $file, string $folder): string
{ {
$this->uploads[] = ['file' => $file, 'folder' => $folder]; $this->uploads[] = ['file' => $file, 'folder' => $folder];
@ -33,4 +43,16 @@ class FakeFileUploader implements FileUploader
{ {
$this->deletedPaths[] = $path; $this->deletedPaths[] = $path;
} }
public function put(string $path, string $contents): void
{
$this->filesByPath[$path] = $contents;
}
public function read(string $path): ?string
{
$this->readPaths[] = $path;
return $this->filesByPath[$path] ?? null;
}
} }

View file

@ -1,30 +0,0 @@
<?php
namespace Tests\Fakes;
use App\Shared\Files\StoredFileReader;
class FakeStoredFileReader implements StoredFileReader
{
/**
* @var array<string, string>
*/
private array $filesByPath = [];
/**
* @var string[]
*/
public array $readPaths = [];
public function put(string $path, string $contents): void
{
$this->filesByPath[$path] = $contents;
}
public function read(string $path): ?string
{
$this->readPaths[] = $path;
return $this->filesByPath[$path] ?? null;
}
}

View file

@ -25,8 +25,7 @@ use App\Set\Set as DomainSet;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile; use Illuminate\Http\UploadedFile;
use Tests\Fakes\FakeElementRepository; use Tests\Fakes\FakeElementRepository;
use Tests\Fakes\FakeFileUploader; use Tests\Fakes\FakeFilesystem;
use Tests\Fakes\FakeStoredFileReader;
use Tests\TestCase; use Tests\TestCase;
class ElementControllerTest extends TestCase class ElementControllerTest extends TestCase
@ -35,46 +34,43 @@ class ElementControllerTest extends TestCase
private FakeElementRepository $elementRepo; private FakeElementRepository $elementRepo;
private FakeFileUploader $fileUploader; private FakeFilesystem $filesystem;
private FakeStoredFileReader $storedFileReader;
protected function setUp(): void protected function setUp(): void
{ {
$this->elementRepo = new FakeElementRepository(); $this->elementRepo = new FakeElementRepository();
$this->fileUploader = new FakeFileUploader(); $this->filesystem = new FakeFilesystem();
$this->storedFileReader = new FakeStoredFileReader();
$getElement = new GetElement($this->elementRepo); $getElement = new GetElement($this->elementRepo);
$updateElement = new UpdateElement( $updateElement = new UpdateElement(
new UpdateTitle($this->elementRepo), new UpdateTitle($this->elementRepo),
new UpdateDescription($this->elementRepo), new UpdateDescription($this->elementRepo),
new UpdateIconImageUrl($this->elementRepo, $this->fileUploader), new UpdateIconImageUrl($this->elementRepo, $this->filesystem),
new UpdateRichText($this->elementRepo), new UpdateRichText($this->elementRepo),
new UpdateShortPdfPath($this->elementRepo, $this->fileUploader), new UpdateShortPdfPath($this->elementRepo, $this->filesystem),
new UpdateLongPdfPath($this->elementRepo, $this->fileUploader), new UpdateLongPdfPath($this->elementRepo, $this->filesystem),
new UpdateYoutubeUrl($this->elementRepo), new UpdateYoutubeUrl($this->elementRepo),
new UpdateIconImage( new UpdateIconImage(
$this->elementRepo, $this->elementRepo,
$this->fileUploader, $this->filesystem,
), ),
new UpdateShortPdf( new UpdateShortPdf(
$this->elementRepo, $this->elementRepo,
$this->fileUploader, $this->filesystem,
), ),
new UpdateLongPdf( new UpdateLongPdf(
$this->elementRepo, $this->elementRepo,
$this->fileUploader, $this->filesystem,
), ),
$this->elementRepo, $this->elementRepo,
); );
$this->controller = new ElementController( $this->controller = new ElementController(
$getElement, $getElement,
new CreateChildElement($this->elementRepo), new CreateChildElement($this->elementRepo),
new DeleteChildElement($this->elementRepo, $this->fileUploader), new DeleteChildElement($this->elementRepo, $this->filesystem),
new ReorderChildElements($this->elementRepo), new ReorderChildElements($this->elementRepo),
$updateElement, $updateElement,
new GetElementPdf($this->storedFileReader), new GetElementPdf($this->filesystem),
$this->fileUploader, $this->filesystem,
); );
} }
@ -252,7 +248,7 @@ class ElementControllerTest extends TestCase
public function testShowPdfReturnsPdfResponse(): void public function testShowPdfReturnsPdfResponse(): void
{ {
$this->storedFileReader->put( $this->filesystem->put(
'element-pdfs/short/baderech.pdf', 'element-pdfs/short/baderech.pdf',
'pdf-bytes', 'pdf-bytes',
); );
@ -311,7 +307,7 @@ class ElementControllerTest extends TestCase
); );
$this->assertSame( $this->assertSame(
'element-icons', 'element-icons',
$this->fileUploader->uploads[0]['folder'], $this->filesystem->uploads[0]['folder'],
); );
} }
@ -345,7 +341,7 @@ class ElementControllerTest extends TestCase
$this->assertArrayNotHasKey('pdfPath', $body['element']); $this->assertArrayNotHasKey('pdfPath', $body['element']);
$this->assertSame( $this->assertSame(
'element-pdfs/short', 'element-pdfs/short',
$this->fileUploader->uploads[0]['folder'], $this->filesystem->uploads[0]['folder'],
); );
} }
@ -378,7 +374,7 @@ class ElementControllerTest extends TestCase
); );
$this->assertSame( $this->assertSame(
'element-pdfs/long', 'element-pdfs/long',
$this->fileUploader->uploads[0]['folder'], $this->filesystem->uploads[0]['folder'],
); );
} }

View file

@ -10,21 +10,21 @@ use App\Exceptions\BadRequestException;
use App\Exceptions\NotFoundException; use App\Exceptions\NotFoundException;
use App\Set\Set as DomainSet; use App\Set\Set as DomainSet;
use Tests\Fakes\FakeElementRepository; use Tests\Fakes\FakeElementRepository;
use Tests\Fakes\FakeFileUploader; use Tests\Fakes\FakeFilesystem;
use Tests\TestCase; use Tests\TestCase;
class DeleteChildElementTest extends TestCase class DeleteChildElementTest extends TestCase
{ {
private FakeElementRepository $elementRepository; private FakeElementRepository $elementRepository;
private FakeFileUploader $fileUploader; private FakeFilesystem $fileUploader;
private DeleteChildElement $deleteChildElement; private DeleteChildElement $deleteChildElement;
protected function setUp(): void protected function setUp(): void
{ {
$this->elementRepository = new FakeElementRepository(); $this->elementRepository = new FakeElementRepository();
$this->fileUploader = new FakeFileUploader(); $this->fileUploader = new FakeFilesystem();
$this->deleteChildElement = new DeleteChildElement( $this->deleteChildElement = new DeleteChildElement(
$this->elementRepository, $this->elementRepository,
$this->fileUploader, $this->fileUploader,

View file

@ -5,24 +5,24 @@ namespace Tests\Unit\Element\UseCases;
use App\Element\UseCases\GetElementPdf\GetElementPdf; use App\Element\UseCases\GetElementPdf\GetElementPdf;
use App\Element\UseCases\GetElementPdf\GetElementPdfRequest; use App\Element\UseCases\GetElementPdf\GetElementPdfRequest;
use App\Exceptions\NotFoundException; use App\Exceptions\NotFoundException;
use Tests\Fakes\FakeStoredFileReader; use Tests\Fakes\FakeFilesystem;
use Tests\TestCase; use Tests\TestCase;
class GetElementPdfTest extends TestCase class GetElementPdfTest extends TestCase
{ {
private FakeStoredFileReader $storedFileReader; private FakeFilesystem $filesystem;
private GetElementPdf $useCase; private GetElementPdf $useCase;
protected function setUp(): void protected function setUp(): void
{ {
$this->storedFileReader = new FakeStoredFileReader(); $this->filesystem = new FakeFilesystem();
$this->useCase = new GetElementPdf($this->storedFileReader); $this->useCase = new GetElementPdf($this->filesystem);
} }
public function testReturnsShortPdfFile(): void public function testReturnsShortPdfFile(): void
{ {
$this->storedFileReader->put( $this->filesystem->put(
'element-pdfs/short/baderech.pdf', 'element-pdfs/short/baderech.pdf',
'short-pdf-bytes', 'short-pdf-bytes',
); );
@ -37,13 +37,13 @@ class GetElementPdfTest extends TestCase
$this->assertSame('application/pdf', $result->getMimeType()); $this->assertSame('application/pdf', $result->getMimeType());
$this->assertSame( $this->assertSame(
['element-pdfs/short/baderech.pdf'], ['element-pdfs/short/baderech.pdf'],
$this->storedFileReader->readPaths, $this->filesystem->readPaths,
); );
} }
public function testReturnsLongPdfFile(): void public function testReturnsLongPdfFile(): void
{ {
$this->storedFileReader->put( $this->filesystem->put(
'element-pdfs/long/baderech-long.pdf', 'element-pdfs/long/baderech-long.pdf',
'long-pdf-bytes', 'long-pdf-bytes',
); );
@ -58,7 +58,7 @@ class GetElementPdfTest extends TestCase
$this->assertSame('application/pdf', $result->getMimeType()); $this->assertSame('application/pdf', $result->getMimeType());
$this->assertSame( $this->assertSame(
['element-pdfs/long/baderech-long.pdf'], ['element-pdfs/long/baderech-long.pdf'],
$this->storedFileReader->readPaths, $this->filesystem->readPaths,
); );
} }

View file

@ -21,19 +21,19 @@ use App\Element\UseCases\UpdateElement\UpdateYoutubeUrlRequest;
use App\Exceptions\BadRequestException; use App\Exceptions\BadRequestException;
use App\Set\Set as DomainSet; use App\Set\Set as DomainSet;
use Tests\Fakes\FakeElementRepository; use Tests\Fakes\FakeElementRepository;
use Tests\Fakes\FakeFileUploader; use Tests\Fakes\FakeFilesystem;
use Tests\TestCase; use Tests\TestCase;
class UpdateElementFieldsTest extends TestCase class UpdateElementFieldsTest extends TestCase
{ {
private FakeElementRepository $elementRepo; private FakeElementRepository $elementRepo;
private FakeFileUploader $fileUploader; private FakeFilesystem $fileUploader;
protected function setUp(): void protected function setUp(): void
{ {
$this->elementRepo = new FakeElementRepository(); $this->elementRepo = new FakeElementRepository();
$this->fileUploader = new FakeFileUploader(); $this->fileUploader = new FakeFilesystem();
} }
public function testUpdateTitleUpdatesOnlyTitle(): void public function testUpdateTitleUpdatesOnlyTitle(): void

View file

@ -20,21 +20,21 @@ use App\Exceptions\BadRequestException;
use App\Exceptions\NotFoundException; use App\Exceptions\NotFoundException;
use App\Set\Set as DomainSet; use App\Set\Set as DomainSet;
use Tests\Fakes\FakeElementRepository; use Tests\Fakes\FakeElementRepository;
use Tests\Fakes\FakeFileUploader; use Tests\Fakes\FakeFilesystem;
use Tests\TestCase; use Tests\TestCase;
class UpdateElementTest extends TestCase class UpdateElementTest extends TestCase
{ {
private FakeElementRepository $elementRepo; private FakeElementRepository $elementRepo;
private FakeFileUploader $fileUploader; private FakeFilesystem $fileUploader;
private UpdateElement $updateElement; private UpdateElement $updateElement;
protected function setUp(): void protected function setUp(): void
{ {
$this->elementRepo = new FakeElementRepository(); $this->elementRepo = new FakeElementRepository();
$this->fileUploader = new FakeFileUploader(); $this->fileUploader = new FakeFilesystem();
$this->updateElement = new UpdateElement( $this->updateElement = new UpdateElement(
new UpdateTitle($this->elementRepo), new UpdateTitle($this->elementRepo),
new UpdateDescription($this->elementRepo), new UpdateDescription($this->elementRepo),

View file

@ -10,21 +10,21 @@ use App\Exceptions\BadRequestException;
use App\Exceptions\NotFoundException; use App\Exceptions\NotFoundException;
use App\Set\Set as DomainSet; use App\Set\Set as DomainSet;
use Tests\Fakes\FakeElementRepository; use Tests\Fakes\FakeElementRepository;
use Tests\Fakes\FakeFileUploader; use Tests\Fakes\FakeFilesystem;
use Tests\TestCase; use Tests\TestCase;
class UpdateIconImageTest extends TestCase class UpdateIconImageTest extends TestCase
{ {
private FakeElementRepository $elementRepository; private FakeElementRepository $elementRepository;
private FakeFileUploader $fileUploader; private FakeFilesystem $fileUploader;
private UpdateIconImage $useCase; private UpdateIconImage $useCase;
protected function setUp(): void protected function setUp(): void
{ {
$this->elementRepository = new FakeElementRepository(); $this->elementRepository = new FakeElementRepository();
$this->fileUploader = new FakeFileUploader(); $this->fileUploader = new FakeFilesystem();
$this->useCase = new UpdateIconImage( $this->useCase = new UpdateIconImage(
$this->elementRepository, $this->elementRepository,
$this->fileUploader, $this->fileUploader,

View file

@ -9,21 +9,21 @@ use App\Element\UseCases\UpdateElement\UpdateLongPdfRequest;
use App\Exceptions\BadRequestException; use App\Exceptions\BadRequestException;
use App\Set\Set as DomainSet; use App\Set\Set as DomainSet;
use Tests\Fakes\FakeElementRepository; use Tests\Fakes\FakeElementRepository;
use Tests\Fakes\FakeFileUploader; use Tests\Fakes\FakeFilesystem;
use Tests\TestCase; use Tests\TestCase;
class UpdateLongPdfTest extends TestCase class UpdateLongPdfTest extends TestCase
{ {
private FakeElementRepository $elementRepository; private FakeElementRepository $elementRepository;
private FakeFileUploader $fileUploader; private FakeFilesystem $fileUploader;
private UpdateLongPdf $useCase; private UpdateLongPdf $useCase;
protected function setUp(): void protected function setUp(): void
{ {
$this->elementRepository = new FakeElementRepository(); $this->elementRepository = new FakeElementRepository();
$this->fileUploader = new FakeFileUploader(); $this->fileUploader = new FakeFilesystem();
$this->useCase = new UpdateLongPdf( $this->useCase = new UpdateLongPdf(
$this->elementRepository, $this->elementRepository,
$this->fileUploader, $this->fileUploader,

View file

@ -10,21 +10,21 @@ use App\Exceptions\BadRequestException;
use App\Exceptions\NotFoundException; use App\Exceptions\NotFoundException;
use App\Set\Set as DomainSet; use App\Set\Set as DomainSet;
use Tests\Fakes\FakeElementRepository; use Tests\Fakes\FakeElementRepository;
use Tests\Fakes\FakeFileUploader; use Tests\Fakes\FakeFilesystem;
use Tests\TestCase; use Tests\TestCase;
class UpdateShortPdfTest extends TestCase class UpdateShortPdfTest extends TestCase
{ {
private FakeElementRepository $elementRepository; private FakeElementRepository $elementRepository;
private FakeFileUploader $fileUploader; private FakeFilesystem $fileUploader;
private UpdateShortPdf $useCase; private UpdateShortPdf $useCase;
protected function setUp(): void protected function setUp(): void
{ {
$this->elementRepository = new FakeElementRepository(); $this->elementRepository = new FakeElementRepository();
$this->fileUploader = new FakeFileUploader(); $this->fileUploader = new FakeFilesystem();
$this->useCase = new UpdateShortPdf( $this->useCase = new UpdateShortPdf(
$this->elementRepository, $this->elementRepository,
$this->fileUploader, $this->fileUploader,