This commit is contained in:
lubiana 2025-06-15 12:55:41 +02:00
parent 314063f15c
commit 937973e8e9
Signed by: lubiana
SSH key fingerprint: SHA256:vW1EA0fRR3Fw+dD/sM0K+x3Il2gSry6YRYHqOeQwrfk
20 changed files with 725 additions and 2221 deletions

View file

@ -3,7 +3,7 @@ jobs:
ls: ls:
runs-on: docker runs-on: docker
container: container:
image: git.php.fail/lubiana/container/php:8.4.3-ci image: git.php.fail/lubiana/container/php:8.4.8-ci
steps: steps:
- name: Manually checkout - name: Manually checkout
env: env:

View file

@ -6,7 +6,7 @@ jobs:
ls: ls:
runs-on: docker runs-on: docker
container: container:
image: git.php.fail/lubiana/container/php:8.4.3-ci image: git.php.fail/lubiana/container/php:8.4.8-ci
steps: steps:
- name: Manually checkout - name: Manually checkout
env: env:

View file

@ -4,7 +4,7 @@ jobs:
ls: ls:
runs-on: docker runs-on: docker
container: container:
image: git.php.fail/lubiana/container/php:8.4.3-ci image: git.php.fail/lubiana/container/php:8.4.8-ci
steps: steps:
- name: Manually checkout - name: Manually checkout
env: env:

View file

@ -7,46 +7,44 @@
"php": ">=8.4", "php": ">=8.4",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"api-platform/doctrine-orm": "^4.0.0", "doctrine/dbal": "^4.2.3",
"api-platform/symfony": "4.1.4", "doctrine/doctrine-bundle": "^2.14.1",
"doctrine/dbal": "^4.1", "doctrine/doctrine-migrations-bundle": "^3.4.2",
"doctrine/doctrine-bundle": "^2.12", "doctrine/orm": "^3.4.0",
"doctrine/doctrine-migrations-bundle": "^3.3.1",
"doctrine/orm": "^3.2.1",
"nelmio/cors-bundle": "^2.5", "nelmio/cors-bundle": "^2.5",
"phpdocumentor/reflection-docblock": "^5.6", "phpdocumentor/reflection-docblock": "^5.6.2",
"phpstan/phpdoc-parser": "^1.33", "phpstan/phpdoc-parser": "^1.33",
"psr/clock": "^1.0", "psr/clock": "^1.0",
"symfony/asset": "7.2.*", "symfony/asset": "7.3.*",
"symfony/console": "7.1.*", "symfony/console": "7.3.*",
"symfony/dotenv": "7.1.*", "symfony/dotenv": "7.3.*",
"symfony/expression-language": "7.2.*", "symfony/expression-language": "7.3.*",
"symfony/flex": "^2.4.6", "symfony/flex": "^2.7.1",
"symfony/form": "7.1.*", "symfony/form": "7.3.*",
"symfony/framework-bundle": "7.1.*", "symfony/framework-bundle": "7.3.*",
"symfony/property-access": "7.2.*", "symfony/property-access": "7.3.*",
"symfony/property-info": "7.2.*", "symfony/property-info": "7.3.*",
"symfony/runtime": "7.1.*", "symfony/runtime": "7.3.*",
"symfony/security-bundle": "7.2.*", "symfony/security-bundle": "7.3.*",
"symfony/security-csrf": "7.1.*", "symfony/security-csrf": "7.3.*",
"symfony/serializer": "7.2.*", "symfony/serializer": "7.3.*",
"symfony/twig-bundle": "7.1.*", "symfony/twig-bundle": "7.3.*",
"symfony/uid": "7.1.*", "symfony/uid": "7.3.*",
"symfony/validator": "7.1.*", "symfony/validator": "7.3.*",
"symfony/yaml": "7.1.*" "symfony/yaml": "7.3.*"
}, },
"require-dev": { "require-dev": {
"doctrine/doctrine-fixtures-bundle": "^4.0", "doctrine/doctrine-fixtures-bundle": "^4.1",
"liip/test-fixtures-bundle": "^3.2", "liip/test-fixtures-bundle": "^3.4",
"lubiana/code-quality": "^1.7.2", "lubiana/code-quality": "^1.7.2",
"pestphp/pest": "^3.6", "pestphp/pest": "^3.8.2",
"symfony/browser-kit": "7.2.*", "symfony/browser-kit": "7.3.*",
"symfony/css-selector": "7.2.*", "symfony/css-selector": "7.3.*",
"symfony/http-client": "7.2.*", "symfony/http-client": "7.3.*",
"symfony/maker-bundle": "^1.60", "symfony/maker-bundle": "^1.63",
"symfony/stopwatch": "7.2.*", "symfony/stopwatch": "7.3.*",
"symfony/web-profiler-bundle": "7.2.*", "symfony/web-profiler-bundle": "7.3.*",
"symplify/config-transformer": "^12.3.4" "symplify/config-transformer": "^12.4.0"
}, },
"config": { "config": {
"allow-plugins": { "allow-plugins": {
@ -80,7 +78,8 @@
"symfony/polyfill-php80": "*", "symfony/polyfill-php80": "*",
"symfony/polyfill-php81": "*", "symfony/polyfill-php81": "*",
"symfony/polyfill-php82": "*", "symfony/polyfill-php82": "*",
"symfony/polyfill-php83": "*" "symfony/polyfill-php83": "*",
"symfony/polyfill-php84": "*"
}, },
"scripts": { "scripts": {
"auto-scripts": { "auto-scripts": {
@ -106,7 +105,7 @@
"extra": { "extra": {
"symfony": { "symfony": {
"allow-contrib": false, "allow-contrib": false,
"require": "7.2.*" "require": "7.3.*"
} }
} }
} }

2601
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -1,52 +1,14 @@
<?php declare(strict_types=1); <?php
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;
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Bundle\WebProfilerBundle\WebProfilerBundle;
return [ return [
FrameworkBundle::class => [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
'all' => true, Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
], Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
MakerBundle::class => [ Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
'dev' => true, Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
], Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
DoctrineBundle::class => [ Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
'all' => true, Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
], Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
DoctrineMigrationsBundle::class => [ Liip\TestFixturesBundle\LiipTestFixturesBundle::class => ['dev' => true, 'test' => true],
'all' => true,
],
TwigBundle::class => [
'all' => true,
],
DoctrineFixturesBundle::class => [
'dev' => true,
'test' => true,
],
WebProfilerBundle::class => [
'dev' => true,
'test' => true,
],
SecurityBundle::class => [
'all' => true,
],
NelmioCorsBundle::class => [
'all' => true,
],
ApiPlatformBundle::class => [
'all' => true,
],
LiipTestFixturesBundle::class => [
'dev' => true,
'test' => true,
],
]; ];

View file

@ -1,22 +0,0 @@
<?php declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('api_platform', [
'title' => 'Futtern API',
'version' => '1.0.0',
'show_webby' => false,
'enable_swagger' => true,
'defaults' => [
'stateless' => true,
'cache_headers' => [
'vary' => [
'Content-Type',
'Authorization',
'Origin',
],
],
],
]);
};

22
config/packages/csrf.php Normal file
View file

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('framework', [
'form' => [
'csrf_protection' => [
'token_id' => 'submit',
],
],
'csrf_protection' => [
'stateless_token_ids' => [
'submit',
'authenticate',
'logout',
],
],
]);
};

View file

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->extension('framework', [
'property_info' => [
'with_constructor_extractor' => true,
],
]);
};

View file

@ -1,8 +0,0 @@
<?php declare(strict_types=1);
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
return static function (RoutingConfigurator $routingConfigurator): void {
$routingConfigurator->import('.', 'api_platform')
->prefix('/api');
};

View file

@ -1,20 +0,0 @@
<?php declare(strict_types=1);
use PhpStyler\Config;
use PhpStyler\Files;
use PhpStyler\Styler;
return new Config(
styler: new Styler(lineLen: 79),
files: new Files(
__DIR__ . '/bin',
__DIR__ . '/public',
__DIR__ . '/src',
__DIR__ . '/config',
__DIR__ . '/tests',
__DIR__ . '/php-styler.php',
__DIR__ . '/ecs.php',
__DIR__ . '/rector.php',
),
cache: __DIR__ . '/.php-styler.cache',
);

View file

View file

@ -17,11 +17,6 @@ use Symfony\Component\Uid\Ulid;
use function iterator_to_array; use function iterator_to_array;
#[ORM\Entity(repositoryClass: FoodOrderRepository::class)] #[ORM\Entity(repositoryClass: FoodOrderRepository::class)]
#[GetCollection(
uriTemplate: '/food_orders/open',
provider: OpenFoodOrderProvider::class,
)]
#[ApiResource]
class FoodOrder class FoodOrder
{ {
#[ORM\Column(nullable: true)] #[ORM\Column(nullable: true)]

View file

@ -12,7 +12,6 @@ use Symfony\Bridge\Doctrine\Types\UlidType;
use Symfony\Component\Uid\Ulid; use Symfony\Component\Uid\Ulid;
#[ORM\Entity(repositoryClass: FoodVendorRepository::class)] #[ORM\Entity(repositoryClass: FoodVendorRepository::class)]
#[ApiResource]
class FoodVendor class FoodVendor
{ {
#[ORM\Column(length: 50)] #[ORM\Column(length: 50)]

View file

@ -13,7 +13,6 @@ use Symfony\Bridge\Doctrine\Types\UlidType;
use Symfony\Component\Uid\Ulid; use Symfony\Component\Uid\Ulid;
#[ORM\Entity(repositoryClass: MenuItemRepository::class)] #[ORM\Entity(repositoryClass: MenuItemRepository::class)]
#[ApiResource]
class MenuItem class MenuItem
{ {
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]

View file

@ -10,7 +10,6 @@ use Symfony\Bridge\Doctrine\Types\UlidType;
use Symfony\Component\Uid\Ulid; use Symfony\Component\Uid\Ulid;
#[ORM\Entity(repositoryClass: OrderItemRepository::class)] #[ORM\Entity(repositoryClass: OrderItemRepository::class)]
#[ApiResource]
class OrderItem class OrderItem
{ {
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]

View file

@ -1,17 +1,12 @@
{ {
"api-platform/symfony": { "doctrine/deprecations": {
"version": "4.0", "version": "1.1",
"recipe": { "recipe": {
"repo": "github.com/symfony/recipes", "repo": "github.com/symfony/recipes",
"branch": "main", "branch": "main",
"version": "4.0", "version": "1.0",
"ref": "e9952e9f393c2d048f10a78f272cd35e807d972b" "ref": "87424683adc81d7dc305eefec1fced883084aab9"
}, }
"files": [
"config/packages/api_platform.yaml",
"config/routes/api_platform.yaml",
"src/ApiResource/.gitignore"
]
}, },
"doctrine/doctrine-bundle": { "doctrine/doctrine-bundle": {
"version": "2.12", "version": "2.12",
@ -123,6 +118,18 @@
".env" ".env"
] ]
}, },
"symfony/form": {
"version": "7.3",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "7.2",
"ref": "7d86a6723f4a623f59e2bf966b6aad2fc461d36b"
},
"files": [
"config/packages/csrf.yaml"
]
},
"symfony/framework-bundle": { "symfony/framework-bundle": {
"version": "7.1", "version": "7.1",
"recipe": { "recipe": {
@ -151,6 +158,18 @@
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f" "ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
} }
}, },
"symfony/property-info": {
"version": "7.3",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "7.3",
"ref": "dae70df71978ae9226ae915ffd5fad817f5ca1f7"
},
"files": [
"config/packages/property_info.yaml"
]
},
"symfony/routing": { "symfony/routing": {
"version": "7.1", "version": "7.1",
"recipe": { "recipe": {

View file

@ -1,26 +0,0 @@
<?php declare(strict_types=1);
namespace App\Tests;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use ApiPlatform\Symfony\Bundle\Test\Client;
use App\DataFixtures\AppFixtures;
use Doctrine\ORM\EntityManagerInterface;
use Liip\TestFixturesBundle\Services\DatabaseToolCollection;
use Override;
abstract class DbApiTestCase extends ApiTestCase
{
protected EntityManagerInterface $manager;
protected Client $client;
#[Override]
protected function setUp(): void
{
parent::setUp();
$this->client = static::createClient();
$this->manager = static::getContainer()->get('doctrine')->getManager();
$toolKit = self::getContainer()->get(DatabaseToolCollection::class)->get();
$toolKit->loadFixtures([AppFixtures::class]);
}
}

View file

@ -1,48 +0,0 @@
<?php declare(strict_types=1);
test('orders', function (): void {
$response = $this->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);
});
test('open orders', function (): void {
$response = $this->client->request('GET', '/api/food_orders/open');
$this->assertResponseIsSuccessful();
$this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
$this->assertJsonContains([
'@context' => '/api/contexts/FoodOrder',
'@id' => '/api/food_orders/open',
'@type' => 'Collection',
]);
// Get the response content and verify that all returned orders are open
$array = $response->toArray();
// If we have no items, we should still have a successful response
if ($array['totalItems'] === 0) {
return;
}
// For each order in the response, check that it is not closed
foreach ($array['member'] as $order) {
// An order is considered open if either:
// 1. closedAt is null or
// 2. closedAt is in the future
$closedAt = isset($order['closedAt']) ? new DateTimeImmutable($order['closedAt']) : null;
$now = new DateTimeImmutable;
// Assert that the order is open (not closed)
$isOpen = (! $closedAt instanceof DateTimeImmutable || $closedAt > $now);
expect($isOpen)
->toBeTrue('Order should be open but is closed');
}
});

View file

@ -16,8 +16,6 @@ use App\Tests\DbWebTest;
pest() pest()
->extends(DbWebTest::class)->in('Feature/Controller/*.php'); ->extends(DbWebTest::class)->in('Feature/Controller/*.php');
pest()
->extends(DbApiTestCase::class)->in('Feature/Api/*.php');
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------