createManga('One Piece', 'one-piece'); // When $client = static::createClient(); $response = $client->request('GET', '/api/manga-matches', [ 'query' => [ 'filename' => 'one-piece_vol108_ch1094.cbz' ] ]); // Then $this->assertResponseIsSuccessful(); $data = $response->toArray(); $this->assertArrayHasKey('matches', $data); $this->assertCount(1, $data['matches']); $this->assertEquals('One Piece', $data['matches'][0]['title']); $this->assertEquals('one-piece', $data['matches'][0]['slug']); $this->assertEquals(1094.0, $data['matches'][0]['chapterNumber']); $this->assertEquals(108, $data['matches'][0]['volumeNumber']); $this->assertGreaterThan(0, $data['matches'][0]['matchScore']); } public function test_it_returns_empty_matches_when_no_manga_found(): void { // Given - no manga in database // When $client = static::createClient(); $response = $client->request('GET', '/api/manga-matches', [ 'query' => [ 'filename' => 'unknown-manga_vol1_ch1.cbz' ] ]); // Then $this->assertResponseIsSuccessful(); $data = $response->toArray(); $this->assertArrayHasKey('matches', $data); $this->assertCount(0, $data['matches']); } public function test_it_returns_bad_request_when_filename_is_missing(): void { // When $client = static::createClient(); $client->request('GET', '/api/manga-matches'); // Then $this->assertResponseStatusCodeSame(400); } public function test_it_extracts_chapter_and_volume_correctly(): void { // Given $this->createManga('Attack on Titan', 'attack-on-titan'); // When $client = static::createClient(); $response = $client->request('GET', '/api/manga-matches', [ 'query' => [ 'filename' => 'attack-on-titan_vol32_ch130.cbz' ] ]); // Then $this->assertResponseIsSuccessful(); $data = $response->toArray(); $this->assertNotEmpty($data['matches']); } public function test_it_handles_filename_with_only_volume(): void { // Given $this->createManga('Naruto', 'naruto'); // When $client = static::createClient(); $response = $client->request('GET', '/api/manga-matches', [ 'query' => [ 'filename' => 'naruto_vol50.cbz' ] ]); // Then $this->assertResponseIsSuccessful(); $data = $response->toArray(); $this->assertNotEmpty($data['matches']); $this->assertEquals('Naruto', $data['matches'][0]['title']); } public function test_it_handles_filename_with_only_chapter(): void { // Given $this->createManga('Bleach', 'bleach'); // When $client = static::createClient(); $response = $client->request('GET', '/api/manga-matches', [ 'query' => [ 'filename' => 'bleach_ch200.cbz' ] ]); // Then $this->assertResponseIsSuccessful(); $data = $response->toArray(); $this->assertNotEmpty($data['matches']); $this->assertEquals('Bleach', $data['matches'][0]['title']); } public function test_it_sorts_matches_by_score(): void { // Given $this->createManga('One Piece', 'one-piece'); $this->createManga('One Piece Z', 'one-piece-z'); $this->createManga('The One Piece', 'the-one-piece'); // When $client = static::createClient(); $response = $client->request('GET', '/api/manga-matches', [ 'query' => [ 'filename' => 'one-piece_vol108_ch1094.cbz' ] ]); // Then $this->assertResponseIsSuccessful(); $data = $response->toArray(); $this->assertArrayHasKey('matches', $data); $this->assertGreaterThanOrEqual(1, count($data['matches'])); // Le premier résultat devrait être "One Piece" (meilleure correspondance) $this->assertEquals('One Piece', $data['matches'][0]['title']); // Vérifier que les scores sont triés par ordre décroissant $scores = array_map(fn($match) => $match['matchScore'], $data['matches']); $sortedScores = $scores; rsort($sortedScores); $this->assertEquals($sortedScores, $scores); } public function test_it_handles_alternative_slugs(): void { // Given $manga = $this->createManga('Shingeki no Kyojin', 'shingeki-no-kyojin'); $manga->setAlternativeSlugs(['attack-on-titan', 'aot']); $this->entityManager->flush(); // When $client = static::createClient(); $response = $client->request('GET', '/api/manga-matches', [ 'query' => [ 'filename' => 'attack-on-titan_vol1_ch1.cbz' ] ]); // Then $this->assertResponseIsSuccessful(); $data = $response->toArray(); $this->assertArrayHasKey('matches', $data); $this->assertNotEmpty($data['matches']); $this->assertEquals('Shingeki no Kyojin', $data['matches'][0]['title']); $this->assertContains('attack-on-titan', $data['matches'][0]['alternativeSlugs']); } public function test_it_provides_possible_titles_variants(): void { // Given $this->createManga('Dragon Ball', 'dragon-ball'); // When $client = static::createClient(); $response = $client->request('GET', '/api/manga-matches', [ 'query' => [ 'filename' => 'dragon-ball_vol1_ch5.cbz' ] ]); // Then $this->assertResponseIsSuccessful(); $data = $response->toArray(); $this->assertNotEmpty($data['matches']); // Vérifier que le match a bien le slug 'dragon-ball' $this->assertEquals('dragon-ball', $data['matches'][0]['slug']); } private function createManga(string $title, string $slug): Manga { $manga = new Manga(); $manga->setTitle($title) ->setSlug($slug) ->setDescription('Description test') ->setAuthor('Author test') ->setPublicationYear(2020) ->setGenres(['action']) ->setStatus('ongoing') ->setRating(4.5) ->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->flush(); return $manga; } }