From 3ad249d8d8482f57a7704fafdfe38572fd3ea7cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Fr=C3=A9mont?= Date: Wed, 15 Jan 2025 12:36:38 +0100 Subject: [PATCH] [DX][Internal] use Foundry for comic books --- Dockerfile | 2 + .../src/Foundry/Factory/AuthorFactory.php | 46 +++++++++++++ .../src/Foundry/Factory/ComicBookFactory.php | 54 +++++++++++++++ .../Foundry/Story/DefaultComicBooksStory.php | 44 +++++++++++++ .../src/Foundry/Story/MoreBooksStory.php | 16 ++--- .../src/Tests/Controller/ComicBookApiTest.php | 66 ++++++++++++------- .../Tests/DataFixtures/ORM/comic_books.yml | 15 ----- 7 files changed, 195 insertions(+), 48 deletions(-) create mode 100644 tests/Application/src/Foundry/Factory/AuthorFactory.php create mode 100644 tests/Application/src/Foundry/Factory/ComicBookFactory.php create mode 100644 tests/Application/src/Foundry/Story/DefaultComicBooksStory.php delete mode 100644 tests/Application/src/Tests/DataFixtures/ORM/comic_books.yml diff --git a/Dockerfile b/Dockerfile index f95848270..aff34abd1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,8 @@ COPY . /app WORKDIR /app +ENV PHP_MEMORY_LIMIT=512M + RUN composer global config --no-plugins allow-plugins.symfony/flex true RUN composer global require --no-progress --no-scripts --no-plugins "symfony/flex:^1.10" RUN composer update --with-all-dependencies --no-interaction --no-progress diff --git a/tests/Application/src/Foundry/Factory/AuthorFactory.php b/tests/Application/src/Foundry/Factory/AuthorFactory.php new file mode 100644 index 000000000..26372c328 --- /dev/null +++ b/tests/Application/src/Foundry/Factory/AuthorFactory.php @@ -0,0 +1,46 @@ + + */ +final class AuthorFactory extends ObjectFactory +{ + public static function class(): string + { + return Author::class; + } + + public function withFirstName(string $firstName): self + { + return $this->with(['firstName' => $firstName]); + } + + public function withLastName(string $lastName): self + { + return $this->with(['lastName' => $lastName]); + } + + protected function defaults(): array + { + return [ + 'firstName' => self::faker()->firstName(), + 'lastName' => self::faker()->lastName(), + ]; + } +} diff --git a/tests/Application/src/Foundry/Factory/ComicBookFactory.php b/tests/Application/src/Foundry/Factory/ComicBookFactory.php new file mode 100644 index 000000000..f13b3d7bd --- /dev/null +++ b/tests/Application/src/Foundry/Factory/ComicBookFactory.php @@ -0,0 +1,54 @@ + + */ +final class ComicBookFactory extends PersistentProxyObjectFactory +{ + public static function class(): string + { + return ComicBook::class; + } + + public function withTitle(string $title): self + { + return $this->with(['title' => $title]); + } + + /** + * @param AuthorFactory|Proxy $author + */ + public function withAuthor(AuthorFactory|Proxy $author): self + { + return $this->with(['author' => $author]); + } + + protected function defaults(): array + { + $author = LazyValue::memoize(fn () => AuthorFactory::createOne()); + + return [ + 'title' => ucfirst(self::faker()->words(2, true)), + 'author' => $author, + ]; + } +} diff --git a/tests/Application/src/Foundry/Story/DefaultComicBooksStory.php b/tests/Application/src/Foundry/Story/DefaultComicBooksStory.php new file mode 100644 index 000000000..08db0ebe0 --- /dev/null +++ b/tests/Application/src/Foundry/Story/DefaultComicBooksStory.php @@ -0,0 +1,44 @@ +withTitle('Old Man Logan') + ->withAuthor( + AuthorFactory::new() + ->withFirstName('Andrea') + ->withLastName('Sorrentino'), + ) + ->create() + ; + + ComicBookFactory::new() + ->withTitle('Civil War II') + ->withAuthor( + AuthorFactory::new() + ->withFirstName('Brian Michael') + ->withLastName('Bendis'), + ) + ->create() + ; + } +} diff --git a/tests/Application/src/Foundry/Story/MoreBooksStory.php b/tests/Application/src/Foundry/Story/MoreBooksStory.php index 07599bc99..67e14249d 100644 --- a/tests/Application/src/Foundry/Story/MoreBooksStory.php +++ b/tests/Application/src/Foundry/Story/MoreBooksStory.php @@ -14,20 +14,18 @@ namespace App\Foundry\Story; use App\Foundry\Factory\BookFactory; -use function Zenstruck\Foundry\Persistence\flush_after; use Zenstruck\Foundry\Story; final class MoreBooksStory extends Story { public function build(): void { - flush_after(function () { - foreach (range(1, 22) as $number) { - BookFactory::new() - ->withTitle('Book ' . $number) - ->create() - ; - } - }); + BookFactory::createSequence( + function () { + foreach (range(1, 22) as $number) { + yield ['title' => 'Book ' . $number]; + } + }, + ); } } diff --git a/tests/Application/src/Tests/Controller/ComicBookApiTest.php b/tests/Application/src/Tests/Controller/ComicBookApiTest.php index 7a5286a79..57af7e7aa 100644 --- a/tests/Application/src/Tests/Controller/ComicBookApiTest.php +++ b/tests/Application/src/Tests/Controller/ComicBookApiTest.php @@ -14,14 +14,22 @@ namespace App\Tests\Controller; use ApiTestCase\JsonApiTestCase; +use App\Foundry\Factory\AuthorFactory; +use App\Foundry\Factory\ComicBookFactory; +use App\Foundry\Story\DefaultComicBooksStory; use Symfony\Component\HttpFoundation\Response; +use Zenstruck\Foundry\Test\Factories; +use Zenstruck\Foundry\Test\ResetDatabase; final class ComicBookApiTest extends JsonApiTestCase { + use Factories; + use ResetDatabase; + /** * @test */ - public function it_allows_creating_a_comic_book() + public function it_allows_creating_a_comic_book(): void { $data = <<markAsSkippedIfNecessary(); @@ -65,9 +73,9 @@ public function it_allows_versioned_creating_a_comic_book() /** * @test */ - public function it_allows_updating_a_comic_book() + public function it_allows_updating_a_comic_book(): void { - $objects = $this->loadFixturesFromFile('comic_books.yml'); + $comicBook = self::someComicBook()->create(); $data = <<client->request('PUT', '/v1/comic-books/' . $objects['comic-book1']->getId(), [], [], ['CONTENT_TYPE' => 'application/json'], $data); + $this->client->request('PUT', '/v1/comic-books/' . $comicBook->getId(), [], [], ['CONTENT_TYPE' => 'application/json'], $data); $response = $this->client->getResponse(); $this->assertResponseCode($response, Response::HTTP_NO_CONTENT); } @@ -88,9 +96,9 @@ public function it_allows_updating_a_comic_book() /** * @test */ - public function it_allows_updating_partial_information_about_a_comic_book() + public function it_allows_updating_partial_information_about_a_comic_book(): void { - $objects = $this->loadFixturesFromFile('comic_books.yml'); + $comicBook = self::someComicBook()->create(); $data = <<client->request('PATCH', '/v1/comic-books/' . $objects['comic-book1']->getId(), [], [], ['CONTENT_TYPE' => 'application/json'], $data); + $this->client->request('PATCH', '/v1/comic-books/' . $comicBook->getId(), [], [], ['CONTENT_TYPE' => 'application/json'], $data); $response = $this->client->getResponse(); $this->assertResponseCode($response, Response::HTTP_NO_CONTENT); } @@ -110,11 +118,11 @@ public function it_allows_updating_partial_information_about_a_comic_book() /** * @test */ - public function it_allows_removing_a_comic_book() + public function it_allows_removing_a_comic_book(): void { - $objects = $this->loadFixturesFromFile('comic_books.yml'); + $comicBook = self::someComicBook()->create(); - $this->client->request('DELETE', '/v1/comic-books/' . $objects['comic-book1']->getId()); + $this->client->request('DELETE', '/v1/comic-books/' . $comicBook->getId()); $response = $this->client->getResponse(); $this->assertResponseCode($response, Response::HTTP_NO_CONTENT); } @@ -122,11 +130,11 @@ public function it_allows_removing_a_comic_book() /** * @test */ - public function it_allows_showing_a_comic_book() + public function it_allows_showing_a_comic_book(): void { - $objects = $this->loadFixturesFromFile('comic_books.yml'); + $comicBook = self::someComicBook()->create(); - $this->client->request('GET', '/v1/comic-books/' . $objects['comic-book1']->getId()); + $this->client->request('GET', '/v1/comic-books/' . $comicBook->getId()); $response = $this->client->getResponse(); $this->assertResponse($response, 'comic-books/show_response'); } @@ -134,13 +142,13 @@ public function it_allows_showing_a_comic_book() /** * @test */ - public function it_allows_versioning_of_a_showing_comic_book_serialization() + public function it_allows_versioning_of_a_showing_comic_book_serialization(): void { $this->markAsSkippedIfNecessary(); - $objects = $this->loadFixturesFromFile('comic_books.yml'); + $comicBook = self::someComicBook()->create(); - $this->client->request('GET', '/v1.2/comic-books/' . $objects['comic-book1']->getId()); + $this->client->request('GET', '/v1.2/comic-books/' . $comicBook->getId()); $response = $this->client->getResponse(); $this->assertResponse($response, 'comic-books/versioned_show_response'); } @@ -148,11 +156,11 @@ public function it_allows_versioning_of_a_showing_comic_book_serialization() /** * @test */ - public function it_allows_indexing_of_comic_books() + public function it_allows_indexing_of_comic_books(): void { $this->markAsSkippedIfNecessary(); - $this->loadFixturesFromFile('comic_books.yml'); + DefaultComicBooksStory::load(); $this->client->request('GET', '/v1/comic-books/'); $response = $this->client->getResponse(); @@ -162,11 +170,11 @@ public function it_allows_indexing_of_comic_books() /** * @test */ - public function it_allows_versioned_indexing_of_comic_books() + public function it_allows_versioned_indexing_of_comic_books(): void { $this->markAsSkippedIfNecessary(); - $this->loadFixturesFromFile('comic_books.yml'); + DefaultComicBooksStory::load(); $this->client->request('GET', '/v1.2/comic-books/'); $response = $this->client->getResponse(); @@ -176,10 +184,8 @@ public function it_allows_versioned_indexing_of_comic_books() /** * @test */ - public function it_does_not_allow_showing_resource_if_it_does_not_exist() + public function it_does_not_allow_showing_resource_if_it_does_not_exist(): void { - $this->loadFixturesFromFile('comic_books.yml'); - $this->client->request('GET', '/v1/comic-books/3'); $response = $this->client->getResponse(); $this->assertResponseCode($response, Response::HTTP_NOT_FOUND); @@ -191,4 +197,16 @@ private function markAsSkippedIfNecessary(): void $this->markTestSkipped(); } } + + private static function someComicBook(): ComicBookFactory + { + return ComicBookFactory::new() + ->withTitle('Old Man Logan') + ->withAuthor( + AuthorFactory::new() + ->withFirstName('Andrea') + ->withLastName('Sorrentino'), + ) + ; + } } diff --git a/tests/Application/src/Tests/DataFixtures/ORM/comic_books.yml b/tests/Application/src/Tests/DataFixtures/ORM/comic_books.yml deleted file mode 100644 index a49ad3c7f..000000000 --- a/tests/Application/src/Tests/DataFixtures/ORM/comic_books.yml +++ /dev/null @@ -1,15 +0,0 @@ -App\Entity\ComicBook: - comic-book1: - title: "Old Man Logan" - author: "@sorrentino" - comic-book2: - title: "Civil War II" - author: "@bendis" - -App\Entity\Author: - sorrentino: - firstName: "Andrea" - lastName: "Sorrentino" - bendis: - firstName: "Brian Michael" - lastName: "Bendis"