elementRepo = new FakeElementRepository(); $this->fileUploader = new FakeFileUploader(); $getElement = new GetElement($this->elementRepo); $updateElement = new UpdateElement( new UpdateTitle($this->elementRepo), new UpdateDescription($this->elementRepo), new UpdateIconImageUrl($this->elementRepo, $this->fileUploader), new UpdateRichText($this->elementRepo), new UpdatePdfPath($this->elementRepo, $this->fileUploader), new UpdateYoutubeUrl($this->elementRepo), new UpdateIconImage( $this->elementRepo, $this->fileUploader, ), new UpdatePdf( $this->elementRepo, $this->fileUploader, ), $this->elementRepo, ); $this->controller = new ElementController( $getElement, $updateElement, $this->fileUploader, ); } public function testShowReturnsElementPayload(): void { $set = $this->createSet(1, 'Baderech'); $element = $this->createElement( $set, 'Baderech HaAvodah', 'A structured path for growth', '/assets/baderech-icon.png', '

A structured path for growth

', '/assets/pdfs/baderech.pdf', 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', null, ); $firstChildElement = $this->createElement( $set, 'Avodah Foundations', 'Foundations for steady avodah', null, '

Foundations rich text

', '/assets/pdfs/foundations.pdf', null, $element, ); $secondChildElement = $this->createElement( $set, 'Daily Practice', 'Daily practices for growth', null, '

Daily practice rich text

', null, null, $element, ); $response = $this->controller->show($element->getId()); $this->assertEquals(200, $response->getStatusCode()); $body = json_decode($response->getContent(), true); $this->assertSame($element->getId(), $body['element']['id']); $this->assertSame('Baderech HaAvodah', $body['element']['title']); $this->assertSame( 'A structured path for growth', $body['element']['description'], ); $this->assertSame( '

A structured path for growth

', $body['element']['richText'], ); $this->assertSame( '/assets/baderech-icon.png', $body['element']['iconImageUrl'], ); $this->assertSame( '/assets/pdfs/baderech.pdf', $body['element']['pdfPath'], ); $this->assertSame( 'https://www.youtube.com/watch?v=yHx-r4p6hHU&t=1s', $body['element']['youtubeUrl'], ); $this->assertSame([ [ 'id' => $firstChildElement->getId(), 'title' => 'Avodah Foundations', 'description' => 'Foundations for steady avodah', ], [ 'id' => $secondChildElement->getId(), 'title' => 'Daily Practice', 'description' => 'Daily practices for growth', ], ], $body['childElements']); } public function testShowReturns400WhenIdMissing(): void { $response = $this->controller->show(null); $this->assertEquals(400, $response->getStatusCode()); $this->assertSame( ['error' => 'id is required'], json_decode($response->getContent(), true), ); } public function testShowReturns404WhenElementDoesNotExist(): void { $response = $this->controller->show(999); $this->assertEquals(404, $response->getStatusCode()); $this->assertSame( ['error' => 'Element not found'], json_decode($response->getContent(), true), ); } public function testUpdateWithIconImageReturnsElementPayload(): void { $set = $this->createSet(1, 'Baderech'); $element = $this->createElement( $set, 'Baderech HaAvodah', 'A structured path for growth', null, '

A structured path for growth

', null, null, null, ); $fixturePath = __DIR__ . '/../../fixtures/icon.png'; $request = new Request([], [ 'elementId' => (string) $element->getId(), ], [], [], [ 'iconImage' => new UploadedFile( $fixturePath, 'icon.png', 'image/png', null, true, ), ], ['REQUEST_METHOD' => 'POST']); $response = $this->controller->update($request); $this->assertEquals(200, $response->getStatusCode()); $body = json_decode($response->getContent(), true); $this->assertSame($element->getId(), $body['element']['id']); $this->assertSame( 'https://test.local/storage/element-icons/fake-icon.png', $body['element']['iconImageUrl'], ); $this->assertSame( 'element-icons', $this->fileUploader->uploads[0]['folder'], ); } public function testUpdateWithPdfReturnsElementPayload(): void { $set = $this->createSet(1, 'Baderech'); $element = $this->createElement( $set, 'Baderech HaAvodah', 'A structured path for growth', null, '

A structured path for growth

', null, null, null, ); $fixturePath = __DIR__ . '/../../fixtures/baderech.pdf'; $request = new Request([], [ 'elementId' => (string) $element->getId(), ], [], [], [ 'pdf' => new UploadedFile( $fixturePath, 'baderech.pdf', 'application/pdf', null, true, ), ], ['REQUEST_METHOD' => 'POST']); $response = $this->controller->update($request); $this->assertEquals(200, $response->getStatusCode()); $body = json_decode($response->getContent(), true); $this->assertSame($element->getId(), $body['element']['id']); $this->assertSame( 'https://test.local/storage/element-pdfs/fake-baderech.pdf', $body['element']['pdfPath'], ); $this->assertSame( 'element-pdfs', $this->fileUploader->uploads[0]['folder'], ); } private function createSet(int $id, string $name): DomainSet { return new DomainSet( id: $id, name: $name, description: "$name description", iconImageUrl: '/assets/baderech-icon.png', ); } private function createElement( DomainSet $set, string $title, string $description, ?string $iconImageUrl, string $richText, ?string $pdfPath, ?string $youtubeUrl, ?Element $parentElement, ): Element { return $this->elementRepo->create(new CreateElementDto( set: $set, title: $title, description: $description, iconImageUrl: $iconImageUrl, richText: $richText, pdfPath: $pdfPath, youtubeUrl: $youtubeUrl, parentElement: $parentElement, )); } }