feat: ajout de la gestion des URL d'image et de miniature dans les réponses des mangas, avec mise à jour des classes et des tests associés

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-03-28 15:05:13 +01:00
parent 6ea24deacf
commit 7051bf5274
9 changed files with 50 additions and 29 deletions

View File

@@ -44,6 +44,7 @@ readonly class FetchMangaChaptersHandler
$chapterData['attributes']['title'], $chapterData['attributes']['title'],
isset($chapterData['attributes']['volume']) ? (int) $chapterData['attributes']['volume'] : null, isset($chapterData['attributes']['volume']) ? (int) $chapterData['attributes']['volume'] : null,
true, true,
false,
new \DateTimeImmutable() new \DateTimeImmutable()
); );

View File

@@ -33,6 +33,7 @@ readonly class GetMangaBySlugHandler
status: $manga->getStatus(), status: $manga->getStatus(),
externalId: $manga->getExternalId()?->getValue(), externalId: $manga->getExternalId()?->getValue(),
imageUrl: $manga->getImageUrl(), imageUrl: $manga->getImageUrl(),
thumbnailUrl: $manga->getImageUrls()?->getThumbnail(),
rating: $manga->getRating() rating: $manga->getRating()
); );
} }

View File

@@ -6,6 +6,7 @@ use App\Domain\Manga\Application\Query\SearchManga;
use App\Domain\Manga\Application\Response\MangaSearchItem; use App\Domain\Manga\Application\Response\MangaSearchItem;
use App\Domain\Manga\Application\Response\MangaSearchResponse; use App\Domain\Manga\Application\Response\MangaSearchResponse;
use App\Domain\Manga\Domain\Contract\Provider\MangaProviderInterface; use App\Domain\Manga\Domain\Contract\Provider\MangaProviderInterface;
use App\Domain\Manga\Domain\Model\Manga;
readonly class SearchMangaHandler readonly class SearchMangaHandler
{ {
@@ -19,7 +20,8 @@ readonly class SearchMangaHandler
return new MangaSearchResponse( return new MangaSearchResponse(
array_map( array_map(
fn ($manga) => new MangaSearchItem( fn (Manga$manga) => new MangaSearchItem(
id: $manga->getId()->getValue(),
externalId: $manga->getExternalId()->getValue(), externalId: $manga->getExternalId()->getValue(),
title: $manga->getTitle()->getValue(), title: $manga->getTitle()->getValue(),
slug: $manga->getSlug()->getValue(), slug: $manga->getSlug()->getValue(),
@@ -29,6 +31,7 @@ readonly class SearchMangaHandler
genres: $manga->getGenres(), genres: $manga->getGenres(),
status: $manga->getStatus(), status: $manga->getStatus(),
imageUrl: $manga->getImageUrl(), imageUrl: $manga->getImageUrl(),
thumbnailUrl: $manga->getImageUrls()?->getThumbnail(),
rating: $manga->getRating() rating: $manga->getRating()
), ),
$mangaCollection->getItems() $mangaCollection->getItems()

View File

@@ -7,6 +7,7 @@ use App\Domain\Manga\Application\QueryHandler\GetMangaByIdHandler;
use App\Domain\Manga\Domain\Exception\MangaNotFoundException; use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
use App\Domain\Manga\Domain\Model\Manga; use App\Domain\Manga\Domain\Model\Manga;
use App\Domain\Manga\Domain\Model\ValueObject\ExternalId; use App\Domain\Manga\Domain\Model\ValueObject\ExternalId;
use App\Domain\Manga\Domain\Model\ValueObject\ImageUrls;
use App\Domain\Manga\Domain\Model\ValueObject\MangaId; use App\Domain\Manga\Domain\Model\ValueObject\MangaId;
use App\Domain\Manga\Domain\Model\ValueObject\MangaSlug; use App\Domain\Manga\Domain\Model\ValueObject\MangaSlug;
use App\Domain\Manga\Domain\Model\ValueObject\MangaTitle; use App\Domain\Manga\Domain\Model\ValueObject\MangaTitle;
@@ -36,17 +37,19 @@ class GetMangaByIdHandlerTest extends TestCase
{ {
// Arrange // Arrange
$manga = new Manga( $manga = new Manga(
new MangaId('123'), id: new MangaId('123'),
new MangaTitle('One Piece'), title: new MangaTitle('One Piece'),
new MangaSlug('one-piece'), slug: new MangaSlug('one-piece'),
'Description test', description: 'Description test',
'Eiichiro Oda', author: 'Eiichiro Oda',
1997, publicationYear: 1997,
['action', 'adventure'], genres: ['action', 'adventure'],
'ongoing', status: 'ongoing',
new ExternalId('external-123'), externalId: new ExternalId('external-123'),
'http://example.com/image.jpg', imageUrl: 'http://example.com/image.jpg',
4.5 rating: 4.5,
imageUrls: new ImageUrls('http://example.com/image.jpg', 'http://example.com/thumbnail.jpg'),
createdAt: new \DateTimeImmutable()
); );
$this->repository->save($manga); $this->repository->save($manga);

View File

@@ -6,6 +6,7 @@ use App\Domain\Manga\Application\Query\GetMangaBySlug;
use App\Domain\Manga\Application\QueryHandler\GetMangaBySlugHandler; use App\Domain\Manga\Application\QueryHandler\GetMangaBySlugHandler;
use App\Domain\Manga\Domain\Exception\MangaNotFoundException; use App\Domain\Manga\Domain\Exception\MangaNotFoundException;
use App\Domain\Manga\Domain\Model\Manga; use App\Domain\Manga\Domain\Model\Manga;
use App\Domain\Manga\Domain\Model\ValueObject\ImageUrls;
use App\Domain\Manga\Domain\Model\ValueObject\MangaId; use App\Domain\Manga\Domain\Model\ValueObject\MangaId;
use App\Domain\Manga\Domain\Model\ValueObject\MangaSlug; use App\Domain\Manga\Domain\Model\ValueObject\MangaSlug;
use App\Domain\Manga\Domain\Model\ValueObject\MangaTitle; use App\Domain\Manga\Domain\Model\ValueObject\MangaTitle;
@@ -37,6 +38,8 @@ class GetMangaBySlugHandlerTest extends TestCase
status: 'ongoing', status: 'ongoing',
externalId: null, externalId: null,
imageUrl: 'https://example.com/image.jpg', imageUrl: 'https://example.com/image.jpg',
imageUrls: new ImageUrls('https://example.com/image.jpg', 'https://example.com/thumbnail.jpg'),
rating: 4.5 rating: 4.5
); );
$this->repository->save($manga); $this->repository->save($manga);

View File

@@ -25,6 +25,7 @@ class GetMangaBySlugTest extends AbstractApiTestCase
'genres' => ['Action', 'Adventure'], 'genres' => ['Action', 'Adventure'],
'status' => 'ongoing', 'status' => 'ongoing',
'imageUrl' => 'https://example.com/image.jpg', 'imageUrl' => 'https://example.com/image.jpg',
'thumbnailUrl' => 'https://example.com/thumbnail.jpg',
'rating' => 4.5, 'rating' => 4.5,
'monitored' => true 'monitored' => true
]); ]);
@@ -44,7 +45,8 @@ class GetMangaBySlugTest extends AbstractApiTestCase
'genres' => ['Action', 'Adventure'], 'genres' => ['Action', 'Adventure'],
'status' => 'ongoing', 'status' => 'ongoing',
'imageUrl' => 'https://example.com/image.jpg', 'imageUrl' => 'https://example.com/image.jpg',
'rating' => 4.5 'rating' => 4.5,
'imageUrl' => 'https://example.com/image.jpg',
]); ]);
} }
@@ -52,8 +54,8 @@ class GetMangaBySlugTest extends AbstractApiTestCase
{ {
// Act // Act
static::createClient()->request('GET', '/api/mangas/by-slug/non-existent-manga'); static::createClient()->request('GET', '/api/mangas/by-slug/non-existent-manga');
// Assert // Assert
$this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND); $this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND);
} }
} }

View File

@@ -45,7 +45,7 @@ class GetMangaListTest extends AbstractApiTestCase
// Then // Then
$this->assertResponseIsSuccessful(); $this->assertResponseIsSuccessful();
$data = $response->toArray(); $data = $response->toArray();
$this->assertCount(10, $data['items']); $this->assertCount(10, $data['items']);
$this->assertEquals(25, $data['total']); $this->assertEquals(25, $data['total']);
$this->assertEquals(2, $data['page']); $this->assertEquals(2, $data['page']);
@@ -73,7 +73,7 @@ class GetMangaListTest extends AbstractApiTestCase
// Then // Then
$this->assertResponseIsSuccessful(); $this->assertResponseIsSuccessful();
$data = $response->toArray(); $data = $response->toArray();
$this->assertCount(3, $data['items']); $this->assertCount(3, $data['items']);
$this->assertEquals('Manga A', $data['items'][0]['title']); $this->assertEquals('Manga A', $data['items'][0]['title']);
$this->assertEquals('Manga B', $data['items'][1]['title']); $this->assertEquals('Manga B', $data['items'][1]['title']);
@@ -99,7 +99,9 @@ class GetMangaListTest extends AbstractApiTestCase
->setStatus('ongoing') ->setStatus('ongoing')
->setRating(4.5) ->setRating(4.5)
->setMonitored(false) ->setMonitored(false)
; ->setImageUrl('https://via.placeholder.com/150')
->setThumbnailUrl('https://via.placeholder.com/150')
->setCreatedAt(new \DateTimeImmutable('2020-01-01'));
$this->entityManager->persist($manga); $this->entityManager->persist($manga);
$this->entityManager->flush(); $this->entityManager->flush();

View File

@@ -33,6 +33,7 @@ class GetMangaTest extends AbstractApiTestCase
->setStatus('ongoing') ->setStatus('ongoing')
->setExternalId('external-123') ->setExternalId('external-123')
->setImageUrl('http://example.com/image.jpg') ->setImageUrl('http://example.com/image.jpg')
->setThumbnailUrl('http://example.com/thumbnail.jpg')
->setRating(4.5) ->setRating(4.5)
->setMonitored(true); ->setMonitored(true);
@@ -60,4 +61,4 @@ class GetMangaTest extends AbstractApiTestCase
'rating' => 4.5 'rating' => 4.5
]); ]);
} }
} }

View File

@@ -63,10 +63,12 @@ class SearchMangaTest extends AbstractApiTestCase
// Then // Then
$this->assertResponseIsSuccessful(); $this->assertResponseIsSuccessful();
$data = $response->toArray(); $data = $response->toArray();
$this->assertCount(2, $data['items']);
$titles = array_map(fn($item) => $item['title'], $data['items']); $this->assertCount(2, $data['items']['hydra:member']);
$titles = array_map(fn($item) => $item['title'], $data['items']['hydra:member']);
$this->assertContains('One Piece', $titles); $this->assertContains('One Piece', $titles);
$this->assertContains('One Punch Man', $titles); $this->assertContains('One Punch Man', $titles);
} }
@@ -88,10 +90,10 @@ class SearchMangaTest extends AbstractApiTestCase
// Then // Then
$this->assertResponseIsSuccessful(); $this->assertResponseIsSuccessful();
$data = $response->toArray(); $data = $response->toArray();
$this->assertCount(1, $data['items']); $this->assertCount(1, $data['items']['hydra:member']);
$this->assertEquals('Dragon Ball', $data['items'][0]['title']); $this->assertEquals('Dragon Ball', $data['items']['hydra:member'][0]['title']);
$this->assertEquals('dragon-ball', $data['items'][0]['slug']); $this->assertEquals('dragon-ball', $data['items']['hydra:member'][0]['slug']);
} }
// public function testSearchMangaWithPagination(): void // public function testSearchMangaWithPagination(): void
@@ -114,7 +116,7 @@ class SearchMangaTest extends AbstractApiTestCase
// // Then // // Then
// $this->assertResponseIsSuccessful(); // $this->assertResponseIsSuccessful();
// $data = $response->toArray(); // $data = $response->toArray();
// $this->assertCount(1, $data['items']); // $this->assertCount(1, $data['items']);
// $this->assertTrue($data['hasNextPage']); // $this->assertTrue($data['hasNextPage']);
// $this->assertTrue($data['hasPreviousPage']); // $this->assertTrue($data['hasPreviousPage']);
@@ -131,9 +133,12 @@ class SearchMangaTest extends AbstractApiTestCase
->setGenres(['action']) ->setGenres(['action'])
->setStatus('ongoing') ->setStatus('ongoing')
->setRating(4.5) ->setRating(4.5)
->setMonitored(false); ->setMonitored(false)
->setImageUrl('https://via.placeholder.com/150')
->setThumbnailUrl('https://via.placeholder.com/150')
->setCreatedAt(new \DateTimeImmutable('2020-01-01'));
$this->entityManager->persist($manga); $this->entityManager->persist($manga);
$this->entityManager->flush(); $this->entityManager->flush();
} }
} }