'https://example.com', 'chapterUrlFormat' => 'https://example.com/manga/{slug}/chapter/{chapter}', 'scrapingType' => 'html', 'testUrl' => 'https://httpbin.org/html', 'mangaSlug' => 'test-manga', 'chapterNumber' => 1.0, 'imageSelector' => 'img', 'nextPageSelector' => null, 'chapterSelector' => null, ]; // When $response = static::createClient()->request('POST', '/api/scraping/test-configuration', [ 'json' => $payload, 'headers' => ['Accept' => 'application/json'], ]); // Then $this->assertResponseStatusCodeSame(200); $responseData = $response->toArray(); $this->assertArrayHasKey('success', $responseData); $this->assertArrayHasKey('imageUrls', $responseData); $this->assertArrayHasKey('totalImages', $responseData); $this->assertArrayHasKey('testedUrl', $responseData); $this->assertArrayHasKey('scrapingType', $responseData); $this->assertArrayHasKey('errors', $responseData); $this->assertEquals('https://httpbin.org/html', $responseData['testedUrl']); $this->assertEquals('html', $responseData['scrapingType']); } public function testTestScraperConfigurationWithInvalidUrl(): void { // Given - Configuration avec une URL invalide $payload = [ 'baseUrl' => 'https://example.com', 'chapterUrlFormat' => 'https://example.com/manga/{slug}/chapter/{chapter}', 'scrapingType' => 'html', 'testUrl' => 'https://invalid-url-that-does-not-exist-12345.com', 'mangaSlug' => 'test-manga', 'chapterNumber' => 1.0, 'imageSelector' => 'img', 'nextPageSelector' => null, 'chapterSelector' => null, ]; // When $response = static::createClient()->request('POST', '/api/scraping/test-configuration', [ 'json' => $payload, 'headers' => ['Accept' => 'application/json'], ]); // Then $this->assertResponseStatusCodeSame(200); $responseData = $response->toArray(); $this->assertFalse($responseData['success']); $this->assertEquals(0, $responseData['totalImages']); $this->assertEmpty($responseData['imageUrls']); $this->assertNotEmpty($responseData['errors']); // Vérifier qu'on a une erreur détaillée $this->assertIsArray($responseData['errors']); $this->assertGreaterThan(0, count($responseData['errors'])); } public function testTestScraperConfigurationWithInvalidSelector(): void { // Given - Configuration avec un sélecteur CSS qui ne trouvera rien $payload = [ 'baseUrl' => 'https://example.com', 'chapterUrlFormat' => 'https://example.com/manga/{slug}/chapter/{chapter}', 'scrapingType' => 'html', 'testUrl' => 'https://httpbin.org/html', 'mangaSlug' => 'test-manga', 'chapterNumber' => 1.0, 'imageSelector' => '.non-existent-class-selector-12345', 'nextPageSelector' => null, 'chapterSelector' => null, ]; // When $response = static::createClient()->request('POST', '/api/scraping/test-configuration', [ 'json' => $payload, 'headers' => ['Accept' => 'application/json'], ]); // Then $this->assertResponseStatusCodeSame(200); $responseData = $response->toArray(); // Le sélecteur invalide peut ne pas retourner d'images, ou juste retourner un tableau vide // C'est un comportement acceptable, le test vérifie juste que ça ne plante pas $this->assertArrayHasKey('success', $responseData); $this->assertArrayHasKey('imageUrls', $responseData); $this->assertArrayHasKey('totalImages', $responseData); $this->assertArrayHasKey('errors', $responseData); } public function testTestScraperConfigurationWithInvalidValidation(): void { // Given - Payload avec des données invalides $payload = [ 'baseUrl' => 'invalid-url', 'chapterUrlFormat' => '', 'scrapingType' => 'invalid-type', 'testUrl' => 'not-a-url', 'mangaSlug' => '', 'chapterNumber' => -1, 'imageSelector' => str_repeat('x', 501), // Trop long ]; // When $response = static::createClient()->request('POST', '/api/scraping/test-configuration', [ 'json' => $payload, 'headers' => ['Accept' => 'application/json'], ]); // Then $this->assertResponseStatusCodeSame(422); $this->assertJsonContains([ 'violations' => [ [ 'propertyPath' => 'baseUrl', 'message' => 'L\'URL de base doit être une URL valide', ], [ 'propertyPath' => 'chapterUrlFormat', 'message' => 'Le format d\'URL de chapitre est obligatoire', ], [ 'propertyPath' => 'scrapingType', 'message' => 'Le type de scraping doit être html ou javascript', ], [ 'propertyPath' => 'testUrl', 'message' => 'L\'URL de test doit être une URL valide', ], [ 'propertyPath' => 'mangaSlug', 'message' => 'Le slug du manga est obligatoire', ], [ 'propertyPath' => 'chapterNumber', 'message' => 'Le numéro de chapitre doit être positif', ], [ 'propertyPath' => 'imageSelector', 'message' => 'Le sélecteur d\'image est trop long', ], ], ]); } public function testTestScraperConfigurationWithUnsupportedScrapingType(): void { // Given - Type de scraping non supporté $payload = [ 'baseUrl' => 'https://example.com', 'chapterUrlFormat' => 'https://example.com/manga/{slug}/chapter/{chapter}', 'scrapingType' => 'unsupported-type', // Type vraiment non supporté 'testUrl' => 'https://httpbin.org/html', 'mangaSlug' => 'test-manga', 'chapterNumber' => 1.0, 'imageSelector' => 'img', ]; // When $response = static::createClient()->request('POST', '/api/scraping/test-configuration', [ 'json' => $payload, 'headers' => ['Accept' => 'application/json'], ]); // Then $this->assertResponseStatusCodeSame(422); // Validation error $this->assertJsonContains([ 'violations' => [ [ 'propertyPath' => 'scrapingType', 'message' => 'Le type de scraping doit être html ou javascript', ], ], ]); } }