From b00b923d4353833ba0a18bde7d0d560402020d68 Mon Sep 17 00:00:00 2001 From: lubiana Date: Thu, 6 Feb 2025 20:35:49 +0100 Subject: [PATCH] add simple apitest --- composer.json | 2 + composer.lock | 263 ++++++++++++++++++++++++++++- config/bundles.php | 5 + config/packages/api_platform.php | 4 +- src/DataFixtures/AppFixtures.php | 16 ++ src/Entity/FoodOrder.php | 1 + src/Entity/FoodVendor.php | 1 + src/Entity/MenuItem.php | 1 + src/Entity/OrderItem.php | 17 +- symfony.lock | 3 + tests/DbApiTestCase.php | 26 +++ tests/Feature/Api/ApiSmokeTest.php | 15 ++ tests/Pest.php | 3 + 13 files changed, 349 insertions(+), 8 deletions(-) create mode 100644 tests/DbApiTestCase.php create mode 100644 tests/Feature/Api/ApiSmokeTest.php diff --git a/composer.json b/composer.json index b06f07b..892ba47 100644 --- a/composer.json +++ b/composer.json @@ -37,10 +37,12 @@ }, "require-dev": { "doctrine/doctrine-fixtures-bundle": "^4.0", + "liip/test-fixtures-bundle": "^3.2", "lubiana/code-quality": "^1.7.2", "pestphp/pest": "^3.6", "symfony/browser-kit": "7.2.*", "symfony/css-selector": "7.2.*", + "symfony/http-client": "7.2.*", "symfony/maker-bundle": "^1.60", "symfony/stopwatch": "7.2.*", "symfony/web-profiler-bundle": "7.2.*", diff --git a/composer.lock b/composer.lock index d104303..42932ab 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "610e21b494f3d6bc7b60e6fca581969a", + "content-hash": "58d99660391be2cef8cd8e1edb56f8c0", "packages": [ { "name": "api-platform/doctrine-common", @@ -7845,6 +7845,94 @@ }, "time": "2024-11-18T16:19:46+00:00" }, + { + "name": "liip/test-fixtures-bundle", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/liip/LiipTestFixturesBundle.git", + "reference": "e38c03180a855824b848ca2d5727765500efc6e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/liip/LiipTestFixturesBundle/zipball/e38c03180a855824b848ca2d5727765500efc6e8", + "reference": "e38c03180a855824b848ca2d5727765500efc6e8", + "shasum": "" + }, + "require": { + "doctrine/common": "^2.13 || ^3.0", + "doctrine/persistence": "^1.3.3 || ^2.0 || ^3.0", + "php": "^8.1", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/event-dispatcher": "^5.4 || ^6.3 || ^7.0", + "symfony/event-dispatcher-contracts": "^1 || ^2 || ^3", + "symfony/framework-bundle": "^5.4 || ^6.3 || ^7.0", + "symfony/yaml": "^5.4 || ^6.3 || ^7.0" + }, + "conflict": { + "doctrine/annotations": "<1.13.1 || >=3.0", + "doctrine/dbal": "<2.13.1 || ~3.0.0 || >=5.0", + "doctrine/mongodb-odm": "<2.2 || >=3.0", + "doctrine/orm": "<2.14 || >=4.0" + }, + "require-dev": { + "doctrine/data-fixtures": "^1.7 || ^2.0.1", + "doctrine/doctrine-bundle": "^2.11", + "doctrine/doctrine-fixtures-bundle": "^3.5.1 || ^4.0", + "doctrine/mongodb-odm": "^2.5", + "doctrine/mongodb-odm-bundle": "^4.4 || ^5.0", + "doctrine/orm": "^2.14 || ^3.0", + "monolog/monolog": "^1.25.1 || ^2.0 || ^3.0", + "phpunit/phpunit": "^10.5.11 || ^11.0.4", + "symfony/doctrine-bridge": "^5.4 || ^6.3 || ^7.0", + "symfony/monolog-bridge": "^5.4 || ^6.3 || ^7.0", + "symfony/monolog-bundle": "^3.2", + "theofidry/alice-data-fixtures": "^1.5.2" + }, + "suggest": { + "doctrine/dbal": "Required when using the fixture loading functionality with an ORM and SQLite", + "doctrine/doctrine-fixtures-bundle": "Required when using the fixture loading functionality", + "doctrine/orm": "Required when using the fixture loading functionality with an ORM and SQLite", + "hautelook/alice-bundle": "Required when using loadFixtureFiles functionality with custom providers", + "theofidry/alice-data-fixtures": "Required when using loadFixtureFiles functionality" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Liip\\TestFixturesBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Liip AG", + "homepage": "http://www.liip.ch/" + }, + { + "name": "Community contributions", + "homepage": "https://github.com/liip/LiipTestFixturesBundle/contributors" + } + ], + "description": "This bundles enables efficient loading of Doctrine fixtures in functional test-cases for Symfony applications", + "keywords": [ + "fixtures", + "symfony", + "testing" + ], + "support": { + "issues": "https://github.com/liip/LiipTestFixturesBundle/issues", + "source": "https://github.com/liip/LiipTestFixturesBundle/tree/3.2.1" + }, + "time": "2024-12-16T16:13:15+00:00" + }, { "name": "lubiana/code-quality", "version": "1.7.2", @@ -10551,6 +10639,179 @@ ], "time": "2025-01-27T11:08:17+00:00" }, + { + "name": "symfony/http-client", + "version": "v7.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/7ce6078c79a4a7afff931c413d2959d3bffbfb8d", + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "amphp/amp": "<2.5", + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/http-client": "^4.2.1|^5.0", + "amphp/http-tunnel": "^1.0|^2.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/amphp-http-client-meta": "^1.0|^2.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.2.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-28T15:51:35+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:49:48+00:00" + }, { "name": "symfony/maker-bundle", "version": "v1.62.1", diff --git a/config/bundles.php b/config/bundles.php index e09b92e..1aed8f6 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -4,6 +4,7 @@ use ApiPlatform\Symfony\Bundle\ApiPlatformBundle; use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle; use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle; +use Liip\TestFixturesBundle\LiipTestFixturesBundle; use Nelmio\CorsBundle\NelmioCorsBundle; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\MakerBundle\MakerBundle; @@ -44,4 +45,8 @@ return [ ApiPlatformBundle::class => [ 'all' => true, ], + LiipTestFixturesBundle::class => [ + 'dev' => true, + 'test' => true, + ], ]; diff --git a/config/packages/api_platform.php b/config/packages/api_platform.php index d19bc6e..64a1f26 100644 --- a/config/packages/api_platform.php +++ b/config/packages/api_platform.php @@ -4,8 +4,10 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigura return static function (ContainerConfigurator $containerConfigurator): void { $containerConfigurator->extension('api_platform', [ - 'title' => 'Hello API Platform', + 'title' => 'Futtern API', 'version' => '1.0.0', + 'show_webby' => false, + 'enable_swagger' => true, 'defaults' => [ 'stateless' => true, 'cache_headers' => [ diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php index b392bbb..327df22 100644 --- a/src/DataFixtures/AppFixtures.php +++ b/src/DataFixtures/AppFixtures.php @@ -2,8 +2,10 @@ namespace App\DataFixtures; +use App\Entity\FoodOrder; use App\Entity\FoodVendor; use App\Entity\MenuItem; +use App\Entity\OrderItem; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; use Override; @@ -39,12 +41,26 @@ final class AppFixtures extends Fixture public function addMenuItemsToVendor(FoodVendor $vendor): void { + $menuItems = []; foreach (range(1, 10) as $i) { $item = new MenuItem; $item->setName("{$vendor->getName()} Item {$i}"); $item->setFoodVendor($vendor); $this->manager->persist($item); $this->manager->flush(); + $menuItems[] = $item; + } + + $order = new FoodOrder; + $order->setFoodVendor($vendor); + + $this->manager->persist($order); + foreach ($menuItems as $item) { + $orderItem = new OrderItem; + $orderItem->setMenuItem($item); + $orderItem->setCreatedBy('John'); + $order->addOrderItem($orderItem); + $this->manager->persist($orderItem); } } } diff --git a/src/Entity/FoodOrder.php b/src/Entity/FoodOrder.php index c3cece1..29ea46f 100644 --- a/src/Entity/FoodOrder.php +++ b/src/Entity/FoodOrder.php @@ -41,6 +41,7 @@ class FoodOrder #[ORM\Column(type: UlidType::NAME, unique: true)] private Ulid|null $id = new Ulid ) { + $this->id ??= new Ulid; $this->orderItems = new ArrayCollection; $this->open(); } diff --git a/src/Entity/FoodVendor.php b/src/Entity/FoodVendor.php index 8312304..890c674 100644 --- a/src/Entity/FoodVendor.php +++ b/src/Entity/FoodVendor.php @@ -45,6 +45,7 @@ class FoodVendor #[ORM\CustomIdGenerator(class: UlidGenerator::class)] private Ulid|null $id = new Ulid ) { + $this->id ??= new Ulid; $this->foodOrders = new ArrayCollection; $this->menuItems = new ArrayCollection; } diff --git a/src/Entity/MenuItem.php b/src/Entity/MenuItem.php index 86e6c61..7dbc110 100644 --- a/src/Entity/MenuItem.php +++ b/src/Entity/MenuItem.php @@ -42,6 +42,7 @@ class MenuItem #[ORM\CustomIdGenerator(class: UlidGenerator::class)] private Ulid|null $id = new Ulid ) { + $this->id ??= new Ulid; $this->aliases = new ArrayCollection; } diff --git a/src/Entity/OrderItem.php b/src/Entity/OrderItem.php index 6930c68..8c90bba 100644 --- a/src/Entity/OrderItem.php +++ b/src/Entity/OrderItem.php @@ -13,12 +13,6 @@ use Symfony\Component\Uid\Ulid; #[ApiResource] class OrderItem { - #[ORM\Id] - #[ORM\GeneratedValue(strategy: 'CUSTOM')] - #[ORM\Column(type: UlidType::NAME, unique: true)] - #[ORM\CustomIdGenerator(class: UlidGenerator::class)] - private Ulid|null $id = null; - #[ORM\Column(length: 255)] private string|null $name = null; @@ -38,6 +32,16 @@ class OrderItem ])] private string|null $createdBy = 'nobody'; + public function __construct( + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'CUSTOM')] + #[ORM\Column(type: UlidType::NAME, unique: true)] + #[ORM\CustomIdGenerator(class: UlidGenerator::class)] + private Ulid|null $id = new Ulid + ) { + $this->id ??= new Ulid; + } + public function getId(): Ulid|null { return $this->id; @@ -87,6 +91,7 @@ class OrderItem public function setMenuItem(MenuItem|null $menuItem): static { $this->menuItem = $menuItem; + $this->name = $menuItem->getName(); return $this; } diff --git a/symfony.lock b/symfony.lock index a53b7f8..17beb57 100644 --- a/symfony.lock +++ b/symfony.lock @@ -52,6 +52,9 @@ "migrations/.gitignore" ] }, + "liip/test-fixtures-bundle": { + "version": "3.2.1" + }, "nelmio/cors-bundle": { "version": "2.5", "recipe": { diff --git a/tests/DbApiTestCase.php b/tests/DbApiTestCase.php new file mode 100644 index 0000000..3041e30 --- /dev/null +++ b/tests/DbApiTestCase.php @@ -0,0 +1,26 @@ +client = static::createClient(); + $this->manager = static::getContainer()->get('doctrine')->getManager(); + $toolKit = self::getContainer()->get(DatabaseToolCollection::class)->get(); + $toolKit->loadFixtures([AppFixtures::class]); + } +} diff --git a/tests/Feature/Api/ApiSmokeTest.php b/tests/Feature/Api/ApiSmokeTest.php new file mode 100644 index 0000000..b18e141 --- /dev/null +++ b/tests/Feature/Api/ApiSmokeTest.php @@ -0,0 +1,15 @@ +client->request('GET', '/api/food_orders'); + $this->assertResponseIsSuccessful(); + $this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8'); + $this->assertJsonContains([ + '@context' => '/api/contexts/FoodOrder', + '@id' => '/api/food_orders', + '@type' => 'Collection', + 'totalItems' => 1, + ]); + $array = $response->toArray(); + expect($array['member'][0]['orderItems'])->toHaveCount(10); +}); diff --git a/tests/Pest.php b/tests/Pest.php index 846dfad..8eae8ad 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -1,5 +1,6 @@ extends(DbWebTest::class)->in('Feature/Controller/*.php'); +pest() + ->extends(DbApiTestCase::class)->in('Feature/Api/*.php'); /* |-------------------------------------------------------------------------- -- 2.39.5