feat: migrer vers Symfony 8, PHP 8.4 et les dépendances majeures associées
- PHP 8.3 → 8.4 (Dockerfile + composer.json) - Symfony 7.0 → 8.0 (tous les composants symfony/*) - API Platform 3.x → 4.x : migration openapiContext → openapi: new Operation(...) - Doctrine DBAL 3 → 4 : suppression use_savepoints, replace prepare/executeQuery - Doctrine ORM 2.x → 3.x : ClassMetadataInfo → ClassMetadata, setParameters → setParameter - Doctrine Bundle 2.x → 3.x, Fixtures Bundle 3.x → 4.x - zenstruck/foundry 1.x → 2.x : ModelFactory → PersistentObjectFactory, getDefaults → defaults - phpmd/phpmd 2.x → 3.x-dev (seule version supportant Symfony 8) - phparkitect 0.3 → 0.8 : NotDependsOnTheseNamespaces prend un array - symfony/mercure-bundle 0.3 → 0.4, symfony/monolog-bundle 3 → 4 - Suppression de runtime/frankenphp-symfony (intégré nativement dans symfony/runtime 8) - worker.Caddyfile : suppression de APP_RUNTIME (détection automatique Symfony 8) - Routes errors.xml/wdt.xml/profiler.xml → .php (Symfony 8 supprime le XML) - Types::ARRAY → Types::JSON dans Entity/Manga.php (DBAL 4 retire array type) - Suppression de src/Schedule.php (doublon vide avec MonitoringSchedule) - Tests : hydra:Collection → Collection, hydra:member → member (API Platform 4)
This commit is contained in:
parent
5a0888eb28
commit
5ed303612a
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Tests\Feature\Manga;
|
||||
|
||||
use App\Domain\Manga\Domain\Contract\Service\ImageProcessorInterface;
|
||||
use App\Tests\Feature\AbstractApiTestCase;
|
||||
use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
@@ -25,17 +24,17 @@ class CreateMangaDirectlyTest extends AbstractApiTestCase
|
||||
'status' => 'ongoing',
|
||||
'externalId' => 'external-123',
|
||||
'imageUrl' => 'http://example.com/image.jpg',
|
||||
'rating' => 4.5
|
||||
]
|
||||
'rating' => 4.5,
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
|
||||
// Verify the manga was created in database
|
||||
$entityManager = static::getContainer()->get('doctrine')->getManager();
|
||||
$manga = $entityManager->getRepository(\App\Entity\Manga::class)->findOneBy(['slug' => 'one-piece']);
|
||||
|
||||
|
||||
$this->assertNotNull($manga);
|
||||
$this->assertEquals('One Piece', $manga->getTitle());
|
||||
$this->assertEquals('Test description', $manga->getDescription());
|
||||
@@ -64,16 +63,16 @@ class CreateMangaDirectlyTest extends AbstractApiTestCase
|
||||
'status' => 'ongoing',
|
||||
'externalId' => 'external-123',
|
||||
'imageUrl' => null,
|
||||
'rating' => 4.5
|
||||
]
|
||||
'rating' => 4.5,
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
$this->assertResponseIsSuccessful();
|
||||
|
||||
|
||||
$entityManager = static::getContainer()->get('doctrine')->getManager();
|
||||
$manga = $entityManager->getRepository(\App\Entity\Manga::class)->findOneBy(['slug' => 'one-piece']);
|
||||
|
||||
|
||||
$this->assertNotNull($manga);
|
||||
$this->assertNull($manga->getImageUrl());
|
||||
$this->assertNull($manga->getThumbnailUrl());
|
||||
@@ -87,14 +86,14 @@ class CreateMangaDirectlyTest extends AbstractApiTestCase
|
||||
'json' => [
|
||||
'title' => '', // Invalid: empty title
|
||||
'publicationYear' => 'invalid', // Invalid: not a number
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
$this->assertResponseStatusCodeSame(400);
|
||||
$this->assertJsonContains([
|
||||
'hydra:title' => 'An error occurred',
|
||||
'hydra:description' => 'The type of the "publicationYear" attribute must be "int", "string" given.'
|
||||
'title' => 'An error occurred',
|
||||
'detail' => 'The type of the "publicationYear" attribute must be "int", "string" given.',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -113,16 +112,16 @@ class CreateMangaDirectlyTest extends AbstractApiTestCase
|
||||
'status' => 'ongoing',
|
||||
'externalId' => 'external-123',
|
||||
'imageUrl' => null,
|
||||
'rating' => 4.5
|
||||
]
|
||||
'rating' => 4.5,
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
$this->assertResponseStatusCodeSame(422);
|
||||
$this->assertJsonContains([
|
||||
'hydra:title' => 'An error occurred',
|
||||
'hydra:description' => 'publicationYear: L\'année de publication doit être comprise entre 1900 et 2100',
|
||||
'title' => 'An error occurred'
|
||||
'title' => 'An error occurred',
|
||||
'detail' => 'publicationYear: L\'année de publication doit être comprise entre 1900 et 2100',
|
||||
'title' => 'An error occurred',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,20 +6,20 @@ use App\Entity\Chapter;
|
||||
use App\Tests\Factory\ChapterFactory;
|
||||
use App\Tests\Factory\MangaFactory;
|
||||
use App\Tests\Feature\AbstractApiTestCase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Zenstruck\Foundry\Test\Factories;
|
||||
use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class DeleteCbzTest extends AbstractApiTestCase
|
||||
{
|
||||
use ResetDatabase, Factories;
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
|
||||
public function test_it_deletes_chapter_cbz_file(): void
|
||||
public function testItDeletesChapterCbzFile(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'One Piece',
|
||||
'slug' => 'one-piece'
|
||||
'slug' => 'one-piece',
|
||||
]);
|
||||
|
||||
$chapter = ChapterFactory::createOne([
|
||||
@@ -27,7 +27,7 @@ class DeleteCbzTest extends AbstractApiTestCase
|
||||
'number' => 1.0,
|
||||
'title' => 'Chapter 1',
|
||||
'visible' => true,
|
||||
'cbzPath' => '/path/to/test.cbz'
|
||||
'cbzPath' => '/path/to/test.cbz',
|
||||
]);
|
||||
|
||||
$this->entityManager->flush();
|
||||
@@ -45,7 +45,7 @@ class DeleteCbzTest extends AbstractApiTestCase
|
||||
$this->assertEmpty($freshChapter->getCbzPath());
|
||||
}
|
||||
|
||||
public function test_it_returns_404_for_non_existent_chapter(): void
|
||||
public function testItReturns404ForNonExistentChapter(): void
|
||||
{
|
||||
// When
|
||||
static::createClient()->request('DELETE', '/api/manga/chapters/999999/cbz');
|
||||
@@ -54,12 +54,12 @@ class DeleteCbzTest extends AbstractApiTestCase
|
||||
$this->assertResponseStatusCodeSame(404);
|
||||
}
|
||||
|
||||
public function test_it_returns_404_for_chapter_without_cbz(): void
|
||||
public function testItReturns404ForChapterWithoutCbz(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'Test Manga',
|
||||
'slug' => 'test-manga'
|
||||
'slug' => 'test-manga',
|
||||
]);
|
||||
|
||||
$chapter = ChapterFactory::createOne([
|
||||
@@ -67,7 +67,7 @@ class DeleteCbzTest extends AbstractApiTestCase
|
||||
'number' => 1.0,
|
||||
'title' => 'Test Chapter',
|
||||
'visible' => true,
|
||||
'cbzPath' => null // No CBZ file
|
||||
'cbzPath' => null, // No CBZ file
|
||||
]);
|
||||
|
||||
$this->entityManager->flush();
|
||||
@@ -80,12 +80,12 @@ class DeleteCbzTest extends AbstractApiTestCase
|
||||
$this->assertResponseStatusCodeSame(404);
|
||||
}
|
||||
|
||||
public function test_it_returns_404_for_invisible_chapter(): void
|
||||
public function testItReturns404ForInvisibleChapter(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'Test Manga',
|
||||
'slug' => 'test-manga'
|
||||
'slug' => 'test-manga',
|
||||
]);
|
||||
|
||||
$chapter = ChapterFactory::createOne([
|
||||
@@ -93,7 +93,7 @@ class DeleteCbzTest extends AbstractApiTestCase
|
||||
'number' => 1.0,
|
||||
'title' => 'Test Chapter',
|
||||
'visible' => false, // Invisible chapter
|
||||
'cbzPath' => '/path/to/test.cbz'
|
||||
'cbzPath' => '/path/to/test.cbz',
|
||||
]);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
@@ -6,27 +6,27 @@ use App\Entity\Chapter;
|
||||
use App\Tests\Factory\ChapterFactory;
|
||||
use App\Tests\Factory\MangaFactory;
|
||||
use App\Tests\Feature\AbstractApiTestCase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Zenstruck\Foundry\Test\Factories;
|
||||
use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class DeleteChapterTest extends AbstractApiTestCase
|
||||
{
|
||||
use ResetDatabase, Factories;
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
|
||||
public function test_it_soft_deletes_chapter(): void
|
||||
public function testItSoftDeletesChapter(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'One Piece',
|
||||
'slug' => 'one-piece'
|
||||
'slug' => 'one-piece',
|
||||
]);
|
||||
|
||||
$chapter = ChapterFactory::createOne([
|
||||
'manga' => $manga,
|
||||
'number' => 1.0,
|
||||
'title' => 'Chapter 1',
|
||||
'visible' => true
|
||||
'visible' => true,
|
||||
]);
|
||||
|
||||
$chapterId = $chapter->getId();
|
||||
@@ -42,7 +42,7 @@ class DeleteChapterTest extends AbstractApiTestCase
|
||||
$this->assertFalse($freshChapter->isVisible());
|
||||
}
|
||||
|
||||
public function test_it_returns_404_for_non_existent_chapter(): void
|
||||
public function testItReturns404ForNonExistentChapter(): void
|
||||
{
|
||||
// When
|
||||
static::createClient()->request('DELETE', '/api/manga/chapters/999999');
|
||||
@@ -51,19 +51,19 @@ class DeleteChapterTest extends AbstractApiTestCase
|
||||
$this->assertResponseStatusCodeSame(404);
|
||||
}
|
||||
|
||||
public function test_it_returns_404_for_already_soft_deleted_chapter(): void
|
||||
public function testItReturns404ForAlreadySoftDeletedChapter(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'Test Manga',
|
||||
'slug' => 'test-manga'
|
||||
'slug' => 'test-manga',
|
||||
]);
|
||||
|
||||
$chapter = ChapterFactory::createOne([
|
||||
'manga' => $manga,
|
||||
'number' => 1.0,
|
||||
'title' => 'Test Chapter',
|
||||
'visible' => false // Already soft deleted
|
||||
'visible' => false, // Already soft deleted
|
||||
]);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
|
||||
namespace App\Tests\Feature\Manga;
|
||||
|
||||
use App\Entity\Manga;
|
||||
use App\Entity\Chapter;
|
||||
use App\Tests\Factory\MangaFactory;
|
||||
use App\Entity\Manga;
|
||||
use App\Tests\Factory\ChapterFactory;
|
||||
use App\Tests\Factory\MangaFactory;
|
||||
use App\Tests\Feature\AbstractApiTestCase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Zenstruck\Foundry\Test\Factories;
|
||||
use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class DeleteMangaTest extends AbstractApiTestCase
|
||||
{
|
||||
use ResetDatabase, Factories;
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
|
||||
public function test_it_deletes_manga_with_chapters(): void
|
||||
public function testItDeletesMangaWithChapters(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'One Piece',
|
||||
'slug' => 'one-piece'
|
||||
'slug' => 'one-piece',
|
||||
]);
|
||||
|
||||
// Create chapters for the manga
|
||||
@@ -28,21 +28,21 @@ class DeleteMangaTest extends AbstractApiTestCase
|
||||
'manga' => $manga,
|
||||
'number' => 1.0,
|
||||
'title' => 'Chapter 1',
|
||||
'visible' => true
|
||||
'visible' => true,
|
||||
]);
|
||||
|
||||
ChapterFactory::createMany(2, [
|
||||
'manga' => $manga,
|
||||
'number' => 2.0,
|
||||
'title' => 'Chapter 2',
|
||||
'visible' => true
|
||||
'visible' => true,
|
||||
]);
|
||||
|
||||
ChapterFactory::createMany(1, [
|
||||
'manga' => $manga,
|
||||
'number' => 3.0,
|
||||
'title' => 'Chapter 3',
|
||||
'visible' => true
|
||||
'visible' => true,
|
||||
]);
|
||||
|
||||
$mangaId = $manga->getId();
|
||||
@@ -66,7 +66,7 @@ class DeleteMangaTest extends AbstractApiTestCase
|
||||
$this->assertCount(0, $chaptersAfter);
|
||||
}
|
||||
|
||||
public function test_it_returns_404_for_non_existent_manga(): void
|
||||
public function testItReturns404ForNonExistentManga(): void
|
||||
{
|
||||
// When
|
||||
static::createClient()->request('DELETE', '/api/mangas/999999');
|
||||
@@ -74,5 +74,4 @@ class DeleteMangaTest extends AbstractApiTestCase
|
||||
// Then
|
||||
$this->assertResponseStatusCodeSame(404);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Tests\Feature\Manga;
|
||||
|
||||
use App\Entity\Chapter;
|
||||
use App\Tests\Factory\ChapterFactory;
|
||||
use App\Tests\Factory\MangaFactory;
|
||||
use App\Tests\Feature\AbstractApiTestCase;
|
||||
@@ -12,14 +11,15 @@ use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class DownloadCbzTest extends AbstractApiTestCase
|
||||
{
|
||||
use ResetDatabase, Factories;
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
|
||||
public function test_it_downloads_chapter_cbz(): void
|
||||
public function testItDownloadsChapterCbz(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'One Piece',
|
||||
'slug' => 'one-piece'
|
||||
'slug' => 'one-piece',
|
||||
]);
|
||||
|
||||
$chapter = ChapterFactory::createOne([
|
||||
@@ -27,7 +27,7 @@ class DownloadCbzTest extends AbstractApiTestCase
|
||||
'number' => 1.0,
|
||||
'title' => 'Chapter 1',
|
||||
'visible' => true,
|
||||
'cbzPath' => '/app/tests/Shared/Files/test-chapter.cbz'
|
||||
'cbzPath' => '/app/tests/Shared/Files/test-chapter.cbz',
|
||||
]);
|
||||
|
||||
$chapterId = $chapter->getId();
|
||||
@@ -44,7 +44,7 @@ class DownloadCbzTest extends AbstractApiTestCase
|
||||
$this->assertStringContainsString('test-chapter.cbz', $response->headers->get('Content-Disposition'));
|
||||
}
|
||||
|
||||
public function test_it_returns_404_for_non_existent_chapter(): void
|
||||
public function testItReturns404ForNonExistentChapter(): void
|
||||
{
|
||||
// When
|
||||
static::createClient()->request('GET', '/api/manga/chapters/999999/download');
|
||||
@@ -53,12 +53,12 @@ class DownloadCbzTest extends AbstractApiTestCase
|
||||
$this->assertResponseStatusCodeSame(404);
|
||||
}
|
||||
|
||||
public function test_it_returns_404_for_chapter_without_cbz(): void
|
||||
public function testItReturns404ForChapterWithoutCbz(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'Test Manga',
|
||||
'slug' => 'test-manga'
|
||||
'slug' => 'test-manga',
|
||||
]);
|
||||
|
||||
$chapter = ChapterFactory::createOne([
|
||||
@@ -66,7 +66,7 @@ class DownloadCbzTest extends AbstractApiTestCase
|
||||
'number' => 1.0,
|
||||
'title' => 'Test Chapter',
|
||||
'visible' => true,
|
||||
'cbzPath' => null // No CBZ file
|
||||
'cbzPath' => null, // No CBZ file
|
||||
]);
|
||||
|
||||
$this->entityManager->flush();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Tests\Feature\Manga;
|
||||
|
||||
use App\Entity\Chapter;
|
||||
use App\Tests\Factory\ChapterFactory;
|
||||
use App\Tests\Factory\MangaFactory;
|
||||
use App\Tests\Feature\AbstractApiTestCase;
|
||||
@@ -12,14 +11,15 @@ use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class DownloadVolumeTest extends AbstractApiTestCase
|
||||
{
|
||||
use ResetDatabase, Factories;
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
|
||||
public function test_it_downloads_volume_cbz(): void
|
||||
public function testItDownloadsVolumeCbz(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'One Piece',
|
||||
'slug' => 'one-piece'
|
||||
'slug' => 'one-piece',
|
||||
]);
|
||||
|
||||
// Create chapters for volume 1
|
||||
@@ -27,7 +27,7 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
'manga' => $manga,
|
||||
'volume' => 1,
|
||||
'visible' => true,
|
||||
'cbzPath' => __DIR__ . '/../../Shared/Files/test-chapter.cbz'
|
||||
'cbzPath' => __DIR__.'/../../Shared/Files/test-chapter.cbz',
|
||||
]);
|
||||
|
||||
$mangaId = $manga->getId();
|
||||
@@ -43,7 +43,7 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
$this->assertStringContainsString('one-piece_vol1.cbz', $contentDisposition);
|
||||
}
|
||||
|
||||
public function test_it_returns_404_when_manga_not_found(): void
|
||||
public function testItReturns404WhenMangaNotFound(): void
|
||||
{
|
||||
// Act
|
||||
static::createClient()->request('GET', '/api/mangas/999999/volumes/1/download');
|
||||
@@ -52,12 +52,12 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
public function test_it_returns_404_when_volume_not_found(): void
|
||||
public function testItReturns404WhenVolumeNotFound(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'One Piece',
|
||||
'slug' => 'one-piece'
|
||||
'slug' => 'one-piece',
|
||||
]);
|
||||
|
||||
$mangaId = $manga->getId();
|
||||
@@ -69,12 +69,12 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
public function test_it_returns_404_when_no_available_chapters_in_volume(): void
|
||||
public function testItReturns404WhenNoAvailableChaptersInVolume(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'One Piece',
|
||||
'slug' => 'one-piece'
|
||||
'slug' => 'one-piece',
|
||||
]);
|
||||
|
||||
// Create chapters for volume 1 but all without CBZ files
|
||||
@@ -82,7 +82,7 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
'manga' => $manga,
|
||||
'volume' => 1,
|
||||
'visible' => true,
|
||||
'cbzPath' => null // No CBZ files
|
||||
'cbzPath' => null, // No CBZ files
|
||||
]);
|
||||
|
||||
$mangaId = $manga->getId();
|
||||
@@ -94,12 +94,12 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
public function test_it_only_includes_visible_chapters_with_cbz(): void
|
||||
public function testItOnlyIncludesVisibleChaptersWithCbz(): void
|
||||
{
|
||||
// Arrange
|
||||
$manga = MangaFactory::createOne([
|
||||
'title' => 'One Piece',
|
||||
'slug' => 'one-piece'
|
||||
'slug' => 'one-piece',
|
||||
]);
|
||||
|
||||
// Create a mix of chapters
|
||||
@@ -108,7 +108,7 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
'volume' => 1,
|
||||
'number' => 1.0,
|
||||
'visible' => true,
|
||||
'cbzPath' => __DIR__ . '/../../Shared/Files/test-chapter.cbz'
|
||||
'cbzPath' => __DIR__.'/../../Shared/Files/test-chapter.cbz',
|
||||
]);
|
||||
|
||||
ChapterFactory::createOne([
|
||||
@@ -116,7 +116,7 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
'volume' => 1,
|
||||
'number' => 2.0,
|
||||
'visible' => false, // Soft deleted
|
||||
'cbzPath' => __DIR__ . '/../../Shared/Files/test-chapter.cbz'
|
||||
'cbzPath' => __DIR__.'/../../Shared/Files/test-chapter.cbz',
|
||||
]);
|
||||
|
||||
ChapterFactory::createOne([
|
||||
@@ -124,7 +124,7 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
'volume' => 1,
|
||||
'number' => 3.0,
|
||||
'visible' => true,
|
||||
'cbzPath' => null // No CBZ
|
||||
'cbzPath' => null, // No CBZ
|
||||
]);
|
||||
|
||||
ChapterFactory::createOne([
|
||||
@@ -132,7 +132,7 @@ class DownloadVolumeTest extends AbstractApiTestCase
|
||||
'volume' => 1,
|
||||
'number' => 4.0,
|
||||
'visible' => true,
|
||||
'cbzPath' => __DIR__ . '/../../Shared/Files/test-chapter.cbz'
|
||||
'cbzPath' => __DIR__.'/../../Shared/Files/test-chapter.cbz',
|
||||
]);
|
||||
|
||||
$mangaId = $manga->getId();
|
||||
|
||||
@@ -24,8 +24,8 @@ class EditMangaTest extends AbstractApiTestCase
|
||||
'status' => 'ongoing',
|
||||
'externalId' => 'external-123',
|
||||
'imageUrl' => 'http://example.com/image.jpg',
|
||||
'rating' => 4.5
|
||||
]
|
||||
'rating' => 4.5,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
@@ -37,7 +37,7 @@ class EditMangaTest extends AbstractApiTestCase
|
||||
$mangaId = $createdManga->getId();
|
||||
|
||||
// When - Edit the manga
|
||||
$response = $client->request('PUT', '/api/mangas/' . $mangaId . '/edit', [
|
||||
$response = $client->request('PUT', '/api/mangas/'.$mangaId.'/edit', [
|
||||
'json' => [
|
||||
'title' => 'One Piece Updated',
|
||||
'description' => 'Updated description',
|
||||
@@ -46,8 +46,8 @@ class EditMangaTest extends AbstractApiTestCase
|
||||
'genres' => ['action', 'adventure', 'comedy'],
|
||||
'status' => 'completed',
|
||||
'rating' => 4.8,
|
||||
'alternativeSlugs' => ['onepiece', 'op']
|
||||
]
|
||||
'alternativeSlugs' => ['onepiece', 'op'],
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -80,8 +80,8 @@ class EditMangaTest extends AbstractApiTestCase
|
||||
'author' => 'Eiichiro Oda',
|
||||
'publicationYear' => 1997,
|
||||
'genres' => ['action', 'adventure'],
|
||||
'status' => 'ongoing'
|
||||
]
|
||||
'status' => 'ongoing',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
@@ -93,14 +93,14 @@ class EditMangaTest extends AbstractApiTestCase
|
||||
$mangaId = $createdManga->getId();
|
||||
|
||||
// When - Try to edit with invalid data
|
||||
$client->request('PUT', '/api/mangas/' . $mangaId . '/edit', [
|
||||
$client->request('PUT', '/api/mangas/'.$mangaId.'/edit', [
|
||||
'json' => [
|
||||
'title' => '', // Invalid: empty title
|
||||
'publicationYear' => 2200, // Invalid: year > 2100
|
||||
'genres' => [], // Invalid: empty genres
|
||||
'status' => 'invalid-status', // Invalid status
|
||||
'rating' => 6.0 // Invalid: rating > 5
|
||||
]
|
||||
'rating' => 6.0, // Invalid: rating > 5
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -113,8 +113,8 @@ class EditMangaTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$client->request('PUT', '/api/mangas/9999999/edit', [
|
||||
'json' => [
|
||||
'title' => 'Updated Title'
|
||||
]
|
||||
'title' => 'Updated Title',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -134,8 +134,8 @@ class EditMangaTest extends AbstractApiTestCase
|
||||
'publicationYear' => 1997,
|
||||
'genres' => ['action', 'adventure'],
|
||||
'status' => 'ongoing',
|
||||
'rating' => 4.5
|
||||
]
|
||||
'rating' => 4.5,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
@@ -147,11 +147,11 @@ class EditMangaTest extends AbstractApiTestCase
|
||||
$mangaId = $createdManga->getId();
|
||||
|
||||
// When - Edit only title and rating
|
||||
$client->request('PUT', '/api/mangas/' . $mangaId . '/edit', [
|
||||
$client->request('PUT', '/api/mangas/'.$mangaId.'/edit', [
|
||||
'json' => [
|
||||
'title' => 'One Piece - Updated Title Only',
|
||||
'rating' => 4.9
|
||||
]
|
||||
'rating' => 4.9,
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
|
||||
@@ -4,14 +4,14 @@ namespace Tests\Feature\Manga;
|
||||
|
||||
use App\Entity\Chapter;
|
||||
use App\Entity\Manga;
|
||||
use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class EditMultipleChaptersTest extends WebTestCase
|
||||
{
|
||||
use ResetDatabase;
|
||||
|
||||
public function test_it_edits_multiple_chapters(): void
|
||||
public function testItEditsMultipleChapters(): void
|
||||
{
|
||||
// Given
|
||||
$client = static::createClient();
|
||||
@@ -46,19 +46,19 @@ class EditMultipleChaptersTest extends WebTestCase
|
||||
[
|
||||
'id' => (string) $chapter1->getId(),
|
||||
'title' => 'New Title 1',
|
||||
'volume' => 2
|
||||
'volume' => 2,
|
||||
],
|
||||
[
|
||||
'id' => (string) $chapter2->getId(),
|
||||
'title' => null,
|
||||
'volume' => 3
|
||||
]
|
||||
]
|
||||
'volume' => 3,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// When
|
||||
$client->request('POST', '/api/chapters/batch-edit', [], [], [
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode($data));
|
||||
|
||||
// Then
|
||||
@@ -76,7 +76,7 @@ class EditMultipleChaptersTest extends WebTestCase
|
||||
$this->assertEquals(3, $updatedChapter2->getVolume());
|
||||
}
|
||||
|
||||
public function test_it_returns_404_when_chapter_not_found(): void
|
||||
public function testItReturns404WhenChapterNotFound(): void
|
||||
{
|
||||
// Given
|
||||
$client = static::createClient();
|
||||
@@ -86,21 +86,21 @@ class EditMultipleChaptersTest extends WebTestCase
|
||||
[
|
||||
'id' => '999',
|
||||
'title' => 'New Title',
|
||||
'volume' => 1
|
||||
]
|
||||
]
|
||||
'volume' => 1,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// When
|
||||
$client->request('POST', '/api/chapters/batch-edit', [], [], [
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode($data));
|
||||
|
||||
// Then
|
||||
$this->assertResponseStatusCodeSame(404);
|
||||
}
|
||||
|
||||
public function test_it_validates_required_fields(): void
|
||||
public function testItValidatesRequiredFields(): void
|
||||
{
|
||||
// Given
|
||||
$client = static::createClient();
|
||||
@@ -109,15 +109,15 @@ class EditMultipleChaptersTest extends WebTestCase
|
||||
'chapters' => [
|
||||
[
|
||||
'title' => 'New Title',
|
||||
'volume' => 1
|
||||
'volume' => 1,
|
||||
// id manquant
|
||||
]
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
// When
|
||||
$client->request('POST', '/api/chapters/batch-edit', [], [], [
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
], json_encode($data));
|
||||
|
||||
// Then
|
||||
|
||||
@@ -49,8 +49,8 @@ class FetchMangaChaptersTest extends AbstractApiTestCase
|
||||
|
||||
static::createClient()->request('POST', '/api/manga/chapters/fetch', [
|
||||
'json' => [
|
||||
'mangaId' => $mangaId
|
||||
]
|
||||
'mangaId' => $mangaId,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertResponseStatusCodeSame(202);
|
||||
@@ -65,8 +65,8 @@ class FetchMangaChaptersTest extends AbstractApiTestCase
|
||||
{
|
||||
$response = static::createClient()->request('POST', '/api/manga/chapters/fetch', [
|
||||
'json' => [
|
||||
'mangaId' => ''
|
||||
]
|
||||
'mangaId' => '',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertResponseStatusCodeSame(422);
|
||||
@@ -74,9 +74,9 @@ class FetchMangaChaptersTest extends AbstractApiTestCase
|
||||
'violations' => [
|
||||
[
|
||||
'propertyPath' => 'mangaId',
|
||||
'message' => 'L\'identifiant du manga est obligatoire'
|
||||
]
|
||||
]
|
||||
'message' => 'L\'identifiant du manga est obligatoire',
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
{
|
||||
use ResetDatabase;
|
||||
|
||||
public function test_it_finds_exact_match_by_filename(): void
|
||||
public function testItFindsExactMatchByFilename(): void
|
||||
{
|
||||
// Given
|
||||
$this->createManga('One Piece', 'one-piece');
|
||||
@@ -21,8 +21,8 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-matches', [
|
||||
'query' => [
|
||||
'filename' => 'one-piece_vol108_ch1094.cbz'
|
||||
]
|
||||
'filename' => 'one-piece_vol108_ch1094.cbz',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -37,10 +37,9 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$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
|
||||
public function testItReturnsEmptyMatchesWhenNoMangaFound(): void
|
||||
{
|
||||
// Given - no manga in database
|
||||
|
||||
@@ -48,8 +47,8 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-matches', [
|
||||
'query' => [
|
||||
'filename' => 'unknown-manga_vol1_ch1.cbz'
|
||||
]
|
||||
'filename' => 'unknown-manga_vol1_ch1.cbz',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -60,7 +59,7 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$this->assertCount(0, $data['matches']);
|
||||
}
|
||||
|
||||
public function test_it_returns_bad_request_when_filename_is_missing(): void
|
||||
public function testItReturnsBadRequestWhenFilenameIsMissing(): void
|
||||
{
|
||||
// When
|
||||
$client = static::createClient();
|
||||
@@ -70,7 +69,7 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$this->assertResponseStatusCodeSame(400);
|
||||
}
|
||||
|
||||
public function test_it_extracts_chapter_and_volume_correctly(): void
|
||||
public function testItExtractsChapterAndVolumeCorrectly(): void
|
||||
{
|
||||
// Given
|
||||
$this->createManga('Attack on Titan', 'attack-on-titan');
|
||||
@@ -79,8 +78,8 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-matches', [
|
||||
'query' => [
|
||||
'filename' => 'attack-on-titan_vol32_ch130.cbz'
|
||||
]
|
||||
'filename' => 'attack-on-titan_vol32_ch130.cbz',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -90,7 +89,7 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$this->assertNotEmpty($data['matches']);
|
||||
}
|
||||
|
||||
public function test_it_handles_filename_with_only_volume(): void
|
||||
public function testItHandlesFilenameWithOnlyVolume(): void
|
||||
{
|
||||
// Given
|
||||
$this->createManga('Naruto', 'naruto');
|
||||
@@ -99,8 +98,8 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-matches', [
|
||||
'query' => [
|
||||
'filename' => 'naruto_vol50.cbz'
|
||||
]
|
||||
'filename' => 'naruto_vol50.cbz',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -111,7 +110,7 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$this->assertEquals('Naruto', $data['matches'][0]['title']);
|
||||
}
|
||||
|
||||
public function test_it_handles_filename_with_only_chapter(): void
|
||||
public function testItHandlesFilenameWithOnlyChapter(): void
|
||||
{
|
||||
// Given
|
||||
$this->createManga('Bleach', 'bleach');
|
||||
@@ -120,8 +119,8 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-matches', [
|
||||
'query' => [
|
||||
'filename' => 'bleach_ch200.cbz'
|
||||
]
|
||||
'filename' => 'bleach_ch200.cbz',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -132,7 +131,7 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$this->assertEquals('Bleach', $data['matches'][0]['title']);
|
||||
}
|
||||
|
||||
public function test_it_sorts_matches_by_score(): void
|
||||
public function testItSortsMatchesByScore(): void
|
||||
{
|
||||
// Given
|
||||
$this->createManga('One Piece', 'one-piece');
|
||||
@@ -143,8 +142,8 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-matches', [
|
||||
'query' => [
|
||||
'filename' => 'one-piece_vol108_ch1094.cbz'
|
||||
]
|
||||
'filename' => 'one-piece_vol108_ch1094.cbz',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -158,13 +157,13 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$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']);
|
||||
$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
|
||||
public function testItHandlesAlternativeSlugs(): void
|
||||
{
|
||||
// Given
|
||||
$manga = $this->createManga('Shingeki no Kyojin', 'shingeki-no-kyojin');
|
||||
@@ -175,8 +174,8 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-matches', [
|
||||
'query' => [
|
||||
'filename' => 'attack-on-titan_vol1_ch1.cbz'
|
||||
]
|
||||
'filename' => 'attack-on-titan_vol1_ch1.cbz',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -189,7 +188,7 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$this->assertContains('attack-on-titan', $data['matches'][0]['alternativeSlugs']);
|
||||
}
|
||||
|
||||
public function test_it_provides_possible_titles_variants(): void
|
||||
public function testItProvidesPossibleTitlesVariants(): void
|
||||
{
|
||||
// Given
|
||||
$this->createManga('Dragon Ball', 'dragon-ball');
|
||||
@@ -198,8 +197,8 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-matches', [
|
||||
'query' => [
|
||||
'filename' => 'dragon-ball_vol1_ch5.cbz'
|
||||
]
|
||||
'filename' => 'dragon-ball_vol1_ch5.cbz',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -233,4 +232,3 @@ class FindMangaMatchByFilenameTest extends AbstractApiTestCase
|
||||
return $manga;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Tests\Feature\Manga;
|
||||
|
||||
use App\Entity\Manga;
|
||||
use App\Tests\Factory\MangaFactory;
|
||||
use App\Tests\Feature\AbstractApiTestCase;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -11,7 +10,8 @@ use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class GetMangaBySlugTest extends AbstractApiTestCase
|
||||
{
|
||||
use ResetDatabase, Factories;
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
|
||||
public function testGetMangaBySlugReturnsCorrectManga(): void
|
||||
{
|
||||
@@ -27,7 +27,7 @@ class GetMangaBySlugTest extends AbstractApiTestCase
|
||||
'imageUrl' => 'https://example.com/image.jpg',
|
||||
'thumbnailUrl' => 'https://example.com/thumbnail.jpg',
|
||||
'rating' => 4.5,
|
||||
'monitored' => true
|
||||
'monitored' => true,
|
||||
]);
|
||||
|
||||
// Act
|
||||
@@ -58,4 +58,4 @@ class GetMangaBySlugTest extends AbstractApiTestCase
|
||||
// Assert
|
||||
$this->assertResponseStatusCodeSame(Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class GetMangaChaptersTest extends AbstractApiTestCase
|
||||
|
||||
// When
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/mangas/' . $manga->getId() . '/chapters');
|
||||
$response = $client->request('GET', '/api/mangas/'.$manga->getId().'/chapters');
|
||||
|
||||
// Then
|
||||
$this->assertResponseIsSuccessful();
|
||||
@@ -38,7 +38,7 @@ class GetMangaChaptersTest extends AbstractApiTestCase
|
||||
'limit' => 20,
|
||||
'hasNextPage' => false,
|
||||
'hasPreviousPage' => false,
|
||||
'items' => []
|
||||
'items' => [],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -50,18 +50,18 @@ class GetMangaChaptersTest extends AbstractApiTestCase
|
||||
|
||||
// When
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/mangas/' . $manga->getId() . '/chapters', [
|
||||
$response = $client->request('GET', '/api/mangas/'.$manga->getId().'/chapters', [
|
||||
'query' => [
|
||||
'page' => 2,
|
||||
'limit' => 10,
|
||||
'sortOrder' => 'desc'
|
||||
]
|
||||
'sortOrder' => 'desc',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
$this->assertResponseIsSuccessful();
|
||||
$data = $response->toArray();
|
||||
|
||||
|
||||
$this->assertCount(10, $data['items']);
|
||||
$this->assertEquals(25, $data['total']);
|
||||
$this->assertEquals(2, $data['page']);
|
||||
@@ -69,7 +69,7 @@ class GetMangaChaptersTest extends AbstractApiTestCase
|
||||
$this->assertTrue($data['hasNextPage']);
|
||||
$this->assertTrue($data['hasPreviousPage']);
|
||||
|
||||
$numbers = array_map(fn($item) => $item['number'], $data['items']);
|
||||
$numbers = array_map(fn ($item) => $item['number'], $data['items']);
|
||||
|
||||
$expectedNumbers = $numbers;
|
||||
rsort($expectedNumbers);
|
||||
@@ -99,12 +99,12 @@ class GetMangaChaptersTest extends AbstractApiTestCase
|
||||
{
|
||||
$entityManager = static::getContainer()->get('doctrine')->getManager();
|
||||
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
for ($i = 1; $i <= $count; ++$i) {
|
||||
$chapter = new Chapter();
|
||||
$chapter->setManga($manga)
|
||||
->setNumber($i)
|
||||
->setTitle("Chapter $i")
|
||||
->setVolume((int)ceil($i / 10))
|
||||
->setVolume((int) ceil($i / 10))
|
||||
->setVisible(true);
|
||||
|
||||
$entityManager->persist($chapter);
|
||||
@@ -112,4 +112,4 @@ class GetMangaChaptersTest extends AbstractApiTestCase
|
||||
|
||||
$entityManager->flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,8 @@ use Zenstruck\Foundry\Test\ResetDatabase;
|
||||
|
||||
class GetMangaListTest extends AbstractApiTestCase
|
||||
{
|
||||
use ResetDatabase, Factories;
|
||||
use ResetDatabase;
|
||||
use Factories;
|
||||
|
||||
public function testGetEmptyMangaList(): void
|
||||
{
|
||||
@@ -27,7 +28,7 @@ class GetMangaListTest extends AbstractApiTestCase
|
||||
'limit' => 20,
|
||||
'hasNextPage' => false,
|
||||
'hasPreviousPage' => false,
|
||||
'items' => []
|
||||
'items' => [],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -41,8 +42,8 @@ class GetMangaListTest extends AbstractApiTestCase
|
||||
$response = $client->request('GET', '/api/mangas', [
|
||||
'query' => [
|
||||
'page' => 2,
|
||||
'limit' => 10
|
||||
]
|
||||
'limit' => 10,
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -69,8 +70,8 @@ class GetMangaListTest extends AbstractApiTestCase
|
||||
$response = $client->request('GET', '/api/mangas', [
|
||||
'query' => [
|
||||
'sortBy' => 'title',
|
||||
'sortOrder' => 'asc'
|
||||
]
|
||||
'sortOrder' => 'asc',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -113,7 +114,7 @@ class GetMangaListTest extends AbstractApiTestCase
|
||||
|
||||
private function createMangas(int $count): void
|
||||
{
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
for ($i = 1; $i <= $count; ++$i) {
|
||||
$this->createManga("Manga $i");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ class GetMangaTest extends AbstractApiTestCase
|
||||
|
||||
// When
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/mangas/by-id/' . $manga->getId());
|
||||
$response = $client->request('GET', '/api/mangas/by-id/'.$manga->getId());
|
||||
|
||||
// Then
|
||||
$this->assertResponseIsSuccessful();
|
||||
@@ -58,7 +58,7 @@ class GetMangaTest extends AbstractApiTestCase
|
||||
'status' => 'ongoing',
|
||||
'externalId' => 'external-123',
|
||||
'imageUrl' => 'http://example.com/image.jpg',
|
||||
'rating' => 4.5
|
||||
'rating' => 4.5,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class ImportChapterTest extends WebTestCase
|
||||
{
|
||||
private const API_ENDPOINT = '/api/chapters/import';
|
||||
|
||||
public function test_it_returns_404_when_manga_not_found(): void
|
||||
public function testItReturns404WhenMangaNotFound(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
$file = $this->createValidCbzFile();
|
||||
@@ -19,7 +19,7 @@ class ImportChapterTest extends WebTestCase
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'mangaId' => 'non-existent-manga-id',
|
||||
'chapterNumber' => '1.5'
|
||||
'chapterNumber' => '1.5',
|
||||
],
|
||||
['file' => $file],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -30,7 +30,7 @@ class ImportChapterTest extends WebTestCase
|
||||
$this->assertEquals('Manga not found', $response['error']);
|
||||
}
|
||||
|
||||
public function test_it_returns_422_when_manga_id_is_missing(): void
|
||||
public function testItReturns422WhenMangaIdIsMissing(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
$file = $this->createValidCbzFile();
|
||||
@@ -39,7 +39,7 @@ class ImportChapterTest extends WebTestCase
|
||||
'POST',
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'chapterNumber' => '1.5'
|
||||
'chapterNumber' => '1.5',
|
||||
],
|
||||
['file' => $file],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -50,7 +50,7 @@ class ImportChapterTest extends WebTestCase
|
||||
$this->assertStringContainsString('mangaId is required', $response[0]['message']);
|
||||
}
|
||||
|
||||
public function test_it_returns_422_when_chapter_number_is_missing(): void
|
||||
public function testItReturns422WhenChapterNumberIsMissing(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
$file = $this->createValidCbzFile();
|
||||
@@ -59,7 +59,7 @@ class ImportChapterTest extends WebTestCase
|
||||
'POST',
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'mangaId' => 'some-manga-id'
|
||||
'mangaId' => 'some-manga-id',
|
||||
],
|
||||
['file' => $file],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -70,7 +70,7 @@ class ImportChapterTest extends WebTestCase
|
||||
$this->assertStringContainsString('chapterNumber is required', $response[0]['message']);
|
||||
}
|
||||
|
||||
public function test_it_returns_422_when_file_is_missing(): void
|
||||
public function testItReturns422WhenFileIsMissing(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
@@ -79,7 +79,7 @@ class ImportChapterTest extends WebTestCase
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'mangaId' => 'some-manga-id',
|
||||
'chapterNumber' => '1.5'
|
||||
'chapterNumber' => '1.5',
|
||||
],
|
||||
[],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -90,7 +90,7 @@ class ImportChapterTest extends WebTestCase
|
||||
$this->assertStringContainsString('Please upload a file', $response[0]['message']);
|
||||
}
|
||||
|
||||
public function test_it_returns_422_when_file_is_not_cbz(): void
|
||||
public function testItReturns422WhenFileIsNotCbz(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
@@ -103,7 +103,7 @@ class ImportChapterTest extends WebTestCase
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'mangaId' => 'some-manga-id',
|
||||
'chapterNumber' => '1.5'
|
||||
'chapterNumber' => '1.5',
|
||||
],
|
||||
['file' => $file],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -120,7 +120,7 @@ class ImportChapterTest extends WebTestCase
|
||||
unlink($tmpFile);
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($tmpFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
|
||||
if (true !== $zip->open($tmpFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
|
||||
throw new \RuntimeException('Cannot create test CBZ file');
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
{
|
||||
private const API_ENDPOINT = '/api/volumes/import';
|
||||
|
||||
public function test_it_returns_404_when_manga_not_found(): void
|
||||
public function testItReturns404WhenMangaNotFound(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
$file = $this->createValidCbzFile();
|
||||
@@ -19,7 +19,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'mangaId' => 'non-existent-manga-id',
|
||||
'volumeNumber' => '1'
|
||||
'volumeNumber' => '1',
|
||||
],
|
||||
['file' => $file],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -30,7 +30,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
$this->assertEquals('Manga not found', $response['error']);
|
||||
}
|
||||
|
||||
public function test_it_returns_422_when_manga_id_is_missing(): void
|
||||
public function testItReturns422WhenMangaIdIsMissing(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
$file = $this->createValidCbzFile();
|
||||
@@ -39,7 +39,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
'POST',
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'volumeNumber' => '1'
|
||||
'volumeNumber' => '1',
|
||||
],
|
||||
['file' => $file],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -50,7 +50,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
$this->assertStringContainsString('mangaId is required', $response[0]['message']);
|
||||
}
|
||||
|
||||
public function test_it_returns_422_when_volume_number_is_missing(): void
|
||||
public function testItReturns422WhenVolumeNumberIsMissing(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
$file = $this->createValidCbzFile();
|
||||
@@ -59,7 +59,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
'POST',
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'mangaId' => 'some-manga-id'
|
||||
'mangaId' => 'some-manga-id',
|
||||
],
|
||||
['file' => $file],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -70,7 +70,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
$this->assertStringContainsString('volumeNumber is required', $response[0]['message']);
|
||||
}
|
||||
|
||||
public function test_it_returns_422_when_file_is_missing(): void
|
||||
public function testItReturns422WhenFileIsMissing(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
@@ -79,7 +79,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'mangaId' => 'some-manga-id',
|
||||
'volumeNumber' => '1'
|
||||
'volumeNumber' => '1',
|
||||
],
|
||||
[],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -90,7 +90,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
$this->assertStringContainsString('Please upload a file', $response[0]['message']);
|
||||
}
|
||||
|
||||
public function test_it_returns_422_when_file_is_not_cbz(): void
|
||||
public function testItReturns422WhenFileIsNotCbz(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
|
||||
@@ -103,7 +103,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
self::API_ENDPOINT,
|
||||
[
|
||||
'mangaId' => 'some-manga-id',
|
||||
'volumeNumber' => '1'
|
||||
'volumeNumber' => '1',
|
||||
],
|
||||
['file' => $file],
|
||||
['CONTENT_TYPE' => 'multipart/form-data']
|
||||
@@ -120,7 +120,7 @@ class ImportVolumeTest extends WebTestCase
|
||||
unlink($tmpFile);
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($tmpFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) !== true) {
|
||||
if (true !== $zip->open($tmpFile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
|
||||
throw new \RuntimeException('Cannot create test CBZ file');
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,15 @@ class SearchMangaTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-search', [
|
||||
'query' => [
|
||||
'q' => ''
|
||||
]
|
||||
'q' => '',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
$this->assertResponseStatusCodeSame(400);
|
||||
$this->assertJsonContains([
|
||||
'hydra:title' => 'An error occurred',
|
||||
'hydra:description' => 'Le terme de recherche doit contenir au moins 3 caractères'
|
||||
'title' => 'An error occurred',
|
||||
'detail' => 'Le terme de recherche doit contenir au moins 3 caractères',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -34,15 +34,15 @@ class SearchMangaTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-search', [
|
||||
'query' => [
|
||||
'q' => 'on'
|
||||
]
|
||||
'q' => 'on',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
$this->assertResponseStatusCodeSame(400);
|
||||
$this->assertJsonContains([
|
||||
'hydra:title' => 'An error occurred',
|
||||
'hydra:description' => 'Le terme de recherche doit contenir au moins 3 caractères'
|
||||
'title' => 'An error occurred',
|
||||
'detail' => 'Le terme de recherche doit contenir au moins 3 caractères',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -57,8 +57,8 @@ class SearchMangaTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-search', [
|
||||
'query' => [
|
||||
'q' => 'one'
|
||||
]
|
||||
'q' => 'one',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
@@ -66,9 +66,8 @@ class SearchMangaTest extends AbstractApiTestCase
|
||||
|
||||
$data = $response->toArray();
|
||||
|
||||
|
||||
$this->assertCount(2, $data['items']['hydra:member']);
|
||||
$titles = array_map(fn($item) => $item['title'], $data['items']['hydra:member']);
|
||||
$this->assertCount(2, $data['items']['member']);
|
||||
$titles = array_map(fn ($item) => $item['title'], $data['items']['member']);
|
||||
$this->assertContains('One Piece', $titles);
|
||||
$this->assertContains('One Punch Man', $titles);
|
||||
}
|
||||
@@ -83,17 +82,17 @@ class SearchMangaTest extends AbstractApiTestCase
|
||||
$client = static::createClient();
|
||||
$response = $client->request('GET', '/api/manga-search', [
|
||||
'query' => [
|
||||
'q' => 'dragon'
|
||||
]
|
||||
'q' => 'dragon',
|
||||
],
|
||||
]);
|
||||
|
||||
// Then
|
||||
$this->assertResponseIsSuccessful();
|
||||
$data = $response->toArray();
|
||||
|
||||
$this->assertCount(1, $data['items']['hydra:member']);
|
||||
$this->assertEquals('Dragon Ball', $data['items']['hydra:member'][0]['title']);
|
||||
$this->assertEquals('dragon-ball', $data['items']['hydra:member'][0]['slug']);
|
||||
$this->assertCount(1, $data['items']['member']);
|
||||
$this->assertEquals('Dragon Ball', $data['items']['member'][0]['title']);
|
||||
$this->assertEquals('dragon-ball', $data['items']['member'][0]['slug']);
|
||||
}
|
||||
|
||||
// public function testSearchMangaWithPagination(): void
|
||||
|
||||
@@ -39,8 +39,8 @@ class ToggleMonitoringTest extends AbstractApiTestCase
|
||||
// Act
|
||||
static::createClient()->request('POST', "/api/manga/{$mangaId}/monitoring/toggle", [
|
||||
'json' => [
|
||||
'enabled' => true
|
||||
]
|
||||
'enabled' => true,
|
||||
],
|
||||
]);
|
||||
|
||||
// Assert
|
||||
@@ -78,8 +78,8 @@ class ToggleMonitoringTest extends AbstractApiTestCase
|
||||
// Act
|
||||
static::createClient()->request('POST', "/api/manga/{$mangaId}/monitoring/toggle", [
|
||||
'json' => [
|
||||
'enabled' => false
|
||||
]
|
||||
'enabled' => false,
|
||||
],
|
||||
]);
|
||||
|
||||
// Assert
|
||||
@@ -96,8 +96,8 @@ class ToggleMonitoringTest extends AbstractApiTestCase
|
||||
// Act & Assert
|
||||
static::createClient()->request('POST', '/api/manga/99999/monitoring/toggle', [
|
||||
'json' => [
|
||||
'enabled' => true
|
||||
]
|
||||
'enabled' => true,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertResponseStatusCodeSame(404);
|
||||
@@ -127,7 +127,7 @@ class ToggleMonitoringTest extends AbstractApiTestCase
|
||||
|
||||
// Act & Assert
|
||||
static::createClient()->request('POST', "/api/manga/{$mangaId}/monitoring/toggle", [
|
||||
'json' => []
|
||||
'json' => [],
|
||||
]);
|
||||
|
||||
$this->assertResponseStatusCodeSame(422);
|
||||
@@ -135,9 +135,9 @@ class ToggleMonitoringTest extends AbstractApiTestCase
|
||||
'violations' => [
|
||||
[
|
||||
'propertyPath' => 'enabled',
|
||||
'message' => 'Le champ enabled est obligatoire'
|
||||
]
|
||||
]
|
||||
'message' => 'Le champ enabled est obligatoire',
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -166,8 +166,8 @@ class ToggleMonitoringTest extends AbstractApiTestCase
|
||||
// Act & Assert
|
||||
static::createClient()->request('POST', "/api/manga/{$mangaId}/monitoring/toggle", [
|
||||
'json' => [
|
||||
'enabled' => 'invalid'
|
||||
]
|
||||
'enabled' => 'invalid',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertResponseStatusCodeSame(422);
|
||||
@@ -175,9 +175,9 @@ class ToggleMonitoringTest extends AbstractApiTestCase
|
||||
'violations' => [
|
||||
[
|
||||
'propertyPath' => 'enabled',
|
||||
'message' => 'Cette valeur doit être de type bool.'
|
||||
]
|
||||
]
|
||||
'message' => 'Cette valeur doit être de type bool.',
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user