elementRepository = new FakeElementRepository(); $this->fileUploader = new FakeFileUploader(); $this->useCase = new UpdateElementPdf( $this->elementRepository, $this->fileUploader, ); } /** * @return array{ * pdfContents: string, * pdfOriginalName: string, * pdfMimeType: string, * pdfSizeBytes: int * } */ private function pdfArgs(): array { return [ 'pdfContents' => 'binary-pdf-bytes', 'pdfOriginalName' => 'baderech.pdf', 'pdfMimeType' => 'application/pdf', 'pdfSizeBytes' => 1024, ]; } public function testUploadsPdfAndStoresPath(): void { $element = $this->createElement(); $updatedElement = $this->useCase->execute( new UpdateElementPdfRequest( ...$this->pdfArgs(), id: $element->getId(), ) ); $this->assertSame( 'element-pdfs/fake-baderech.pdf', $updatedElement->getPdfPath(), ); $storedElement = $this->elementRepository->find($element->getId()); $this->assertNotNull($storedElement); $this->assertSame( 'element-pdfs/fake-baderech.pdf', $storedElement->getPdfPath(), ); $this->assertSame( 'element-pdfs', $this->fileUploader->uploads[0]['folder'], ); } public function testNullIdThrowsBadRequest(): void { $this->expectException(BadRequestException::class); $this->expectExceptionMessage('id is required'); $this->useCase->execute( new UpdateElementPdfRequest( ...$this->pdfArgs(), id: null, ) ); } public function testNullPdfThrowsBadRequest(): void { $this->expectException(BadRequestException::class); $this->expectExceptionMessage('pdf is required'); $this->useCase->execute( new UpdateElementPdfRequest( id: 1, pdfContents: null, pdfOriginalName: null, pdfMimeType: null, pdfSizeBytes: null, ) ); } public function testDisallowedMimeThrowsBadRequest(): void { $this->expectException(BadRequestException::class); $this->expectExceptionMessage('pdf must be a pdf file'); $this->useCase->execute( new UpdateElementPdfRequest( id: 1, pdfContents: 'not-a-pdf', pdfOriginalName: 'icon.png', pdfMimeType: 'image/png', pdfSizeBytes: 1024, ) ); } public function testOversizedPdfThrowsBadRequest(): void { $this->expectException(BadRequestException::class); $this->expectExceptionMessage('pdf must be 10MB or smaller'); $this->useCase->execute( new UpdateElementPdfRequest( id: 1, pdfContents: 'big', pdfOriginalName: 'baderech.pdf', pdfMimeType: 'application/pdf', pdfSizeBytes: 11 * 1024 * 1024, ) ); } public function testMissingElementThrowsNotFound(): void { $this->expectException(NotFoundException::class); $this->expectExceptionMessage('Element not found'); $this->useCase->execute( new UpdateElementPdfRequest( ...$this->pdfArgs(), id: 999, ) ); } private function createElement(): Element { $set = new DomainSet( id: 1, name: 'Baderech', description: 'Baderech description', iconImageUrl: '/assets/baderech-icon.png', ); return $this->elementRepository->create(new CreateElementDto( set: $set, title: 'Original title', description: 'Original description', iconImageUrl: null, richText: '', pdfPath: null, youtubeUrl: null, parentElement: null, )); } }