From 2f615a49366f8be7a1e76e2d361ec7be65797109 Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Mon, 10 Feb 2025 19:40:47 +0100 Subject: [PATCH] feat: GetManga endpoint + tests --- .../Manga/Application/Query/GetManga.php | 10 +++ .../QueryHandler/GetMangaHandler.php | 38 ++++++++++ .../Application/Response/MangaResponse.php | 20 +++++ .../Domain/Exception/MangaDomainException.php | 4 +- .../Exception/MangaNotFoundException.php | 11 +++ .../ApiPlatform/Dto/MangaDetail.php | 23 ++++++ .../ApiPlatform/Resource/MangaResource.php | 22 ++++++ .../State/Provider/GetMangaStateProvider.php | 36 +++++++++ .../QueryHandler/GetMangaHandlerTest.php | 75 +++++++++++++++++++ tests/Feature/Manga/GetMangaTest.php | 63 ++++++++++++++++ 10 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 src/Domain/Manga/Application/Query/GetManga.php create mode 100644 src/Domain/Manga/Application/QueryHandler/GetMangaHandler.php create mode 100644 src/Domain/Manga/Application/Response/MangaResponse.php create mode 100644 src/Domain/Manga/Domain/Exception/MangaNotFoundException.php create mode 100644 src/Domain/Manga/Infrastructure/ApiPlatform/Dto/MangaDetail.php create mode 100644 src/Domain/Manga/Infrastructure/ApiPlatform/Resource/MangaResource.php create mode 100644 src/Domain/Manga/Infrastructure/ApiPlatform/State/Provider/GetMangaStateProvider.php create mode 100644 tests/Domain/Manga/Application/QueryHandler/GetMangaHandlerTest.php create mode 100644 tests/Feature/Manga/GetMangaTest.php diff --git a/src/Domain/Manga/Application/Query/GetManga.php b/src/Domain/Manga/Application/Query/GetManga.php new file mode 100644 index 0000000..130dbb7 --- /dev/null +++ b/src/Domain/Manga/Application/Query/GetManga.php @@ -0,0 +1,10 @@ +mangaRepository->findById($query->id); + + if (!$manga) { + throw new MangaNotFoundException(); + } + + return new MangaResponse( + id: $manga->getId()->getValue(), + title: $manga->getTitle()->getValue(), + slug: $manga->getSlug()->getValue(), + description: $manga->getDescription(), + author: $manga->getAuthor(), + publicationYear: $manga->getPublicationYear(), + genres: $manga->getGenres(), + status: $manga->getStatus(), + externalId: $manga->getExternalId()?->getValue(), + imageUrl: $manga->getImageUrl(), + rating: $manga->getRating() + ); + } +} \ No newline at end of file diff --git a/src/Domain/Manga/Application/Response/MangaResponse.php b/src/Domain/Manga/Application/Response/MangaResponse.php new file mode 100644 index 0000000..9faa9f4 --- /dev/null +++ b/src/Domain/Manga/Application/Response/MangaResponse.php @@ -0,0 +1,20 @@ +handler->handle($query); + + return new MangaDetail( + id: $response->id, + title: $response->title, + slug: $response->slug, + description: $response->description, + author: $response->author, + publicationYear: $response->publicationYear, + genres: $response->genres, + status: $response->status, + externalId: $response->externalId, + imageUrl: $response->imageUrl, + rating: $response->rating + ); + } +} \ No newline at end of file diff --git a/tests/Domain/Manga/Application/QueryHandler/GetMangaHandlerTest.php b/tests/Domain/Manga/Application/QueryHandler/GetMangaHandlerTest.php new file mode 100644 index 0000000..f384687 --- /dev/null +++ b/tests/Domain/Manga/Application/QueryHandler/GetMangaHandlerTest.php @@ -0,0 +1,75 @@ +repository = new InMemoryMangaRepository(); + $this->handler = new GetMangaHandler($this->repository); + } + + public function testHandleThrowsExceptionWhenMangaNotFound(): void + { + $this->expectException(MangaNotFoundException::class); + + $query = new GetManga('non-existent-id'); + $this->handler->handle($query); + } + + public function testHandleReturnsMangaResponse(): void + { + // Arrange + $manga = new Manga( + new MangaId('123'), + new MangaTitle('One Piece'), + new MangaSlug('one-piece'), + 'Description test', + 'Eiichiro Oda', + 1997, + ['action', 'adventure'], + 'ongoing', + new ExternalId('external-123'), + 'http://example.com/image.jpg', + 4.5 + ); + $this->repository->save($manga); + + // Act + $query = new GetManga('123'); + $response = $this->handler->handle($query); + + // Assert + $this->assertEquals('123', $response->id); + $this->assertEquals('One Piece', $response->title); + $this->assertEquals('one-piece', $response->slug); + $this->assertEquals('Description test', $response->description); + $this->assertEquals('Eiichiro Oda', $response->author); + $this->assertEquals(1997, $response->publicationYear); + $this->assertEquals(['action', 'adventure'], $response->genres); + $this->assertEquals('ongoing', $response->status); + $this->assertEquals('external-123', $response->externalId); + $this->assertEquals('http://example.com/image.jpg', $response->imageUrl); + $this->assertEquals(4.5, $response->rating); + } + + protected function tearDown(): void + { + $this->repository->clear(); + } +} \ No newline at end of file diff --git a/tests/Feature/Manga/GetMangaTest.php b/tests/Feature/Manga/GetMangaTest.php new file mode 100644 index 0000000..0e8a4b8 --- /dev/null +++ b/tests/Feature/Manga/GetMangaTest.php @@ -0,0 +1,63 @@ +request('GET', '/api/mangas/999'); + + // Then + $this->assertResponseStatusCodeSame(404); + } + + public function testGetExistingManga(): void + { + // Given + $manga = new Manga(); + $manga->setTitle('One Piece') + ->setSlug('one-piece') + ->setDescription('Test description') + ->setAuthor('Eiichiro Oda') + ->setPublicationYear(1997) + ->setGenres(['action', 'adventure']) + ->setStatus('ongoing') + ->setExternalId('external-123') + ->setImageUrl('http://example.com/image.jpg') + ->setRating(4.5) + ->setMonitored(true); + + $entityManager = static::getContainer()->get('doctrine')->getManager(); + $entityManager->persist($manga); + $entityManager->flush(); + + // When + $client = static::createClient(); + $response = $client->request('GET', '/api/mangas/' . $manga->getId()); + + // Then + $this->assertResponseIsSuccessful(); + $this->assertJsonContains([ + 'id' => (string) $manga->getId(), + 'title' => 'One Piece', + 'slug' => 'one-piece', + 'description' => 'Test description', + 'author' => 'Eiichiro Oda', + 'publicationYear' => 1997, + 'genres' => ['action', 'adventure'], + 'status' => 'ongoing', + 'externalId' => 'external-123', + 'imageUrl' => 'http://example.com/image.jpg', + 'rating' => 4.5 + ]); + } +} \ No newline at end of file