add open orders api route
All checks were successful
/ ls (pull_request) Successful in 1m31s
/ ls (push) Successful in 1m25s
/ ls (release) Successful in 1m0s

This commit is contained in:
lubiana 2025-04-23 18:56:59 +02:00
parent 5de80b0da0
commit 96b246462a
Signed by: lubiana
SSH key fingerprint: SHA256:vW1EA0fRR3Fw+dD/sM0K+x3Il2gSry6YRYHqOeQwrfk
5 changed files with 79 additions and 0 deletions

View file

@ -3,7 +3,9 @@
namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GetCollection;
use App\Repository\FoodOrderRepository;
use App\State\OpenFoodOrderProvider;
use DateInterval;
use DateTimeImmutable;
use Doctrine\Common\Collections\ArrayCollection;
@ -15,6 +17,10 @@ use Symfony\Component\Uid\Ulid;
use function iterator_to_array;
#[ORM\Entity(repositoryClass: FoodOrderRepository::class)]
#[GetCollection(
uriTemplate: '/food_orders/open',
provider: OpenFoodOrderProvider::class,
)]
#[ApiResource]
class FoodOrder
{

View file

@ -47,4 +47,19 @@ final class FoodOrderRepository extends ServiceEntityRepository
->filter(static fn(FoodOrder $order): bool => $order->getCreatedAt() >= $date)
->getValues();
}
/**
* @return FoodOrder[]
*/
public function findOpenOrders(): array
{
$now = new DateTimeImmutable;
return $this->createQueryBuilder('o')
->where('o.closedAt IS NULL OR o.closedAt > :now')
->setParameter('now', $now)
->orderBy('o.id', 'DESC')
->getQuery()
->getResult();
}
}

View file

@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Repository\FoodOrderRepository;
use Override;
final readonly class OpenFoodOrderProvider implements ProviderInterface
{
public function __construct(
private FoodOrderRepository $repository
) {}
#[Override]
public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
return $this->repository->findOpenOrders();
}
}

View file

@ -13,3 +13,36 @@ test('orders', function (): void {
$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

@ -1,6 +1,7 @@
<?php declare(strict_types=1);
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\Filesystem\Filesystem;
require dirname(__DIR__) . '/vendor/autoload.php';
@ -13,3 +14,6 @@ if (method_exists(Dotenv::class, 'bootEnv')) {
if ($_SERVER['APP_DEBUG']) {
umask(0o000);
}
$fs = new Filesystem;
$fs->remove(dirname(__DIR__) . '/../var/cache/*');