diff --git a/src/Entity/FoodOrder.php b/src/Entity/FoodOrder.php index 29ea46f..3778038 100644 --- a/src/Entity/FoodOrder.php +++ b/src/Entity/FoodOrder.php @@ -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 { diff --git a/src/Repository/FoodOrderRepository.php b/src/Repository/FoodOrderRepository.php index 0df83aa..09445f9 100644 --- a/src/Repository/FoodOrderRepository.php +++ b/src/Repository/FoodOrderRepository.php @@ -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(); + } } diff --git a/src/State/OpenFoodOrderProvider.php b/src/State/OpenFoodOrderProvider.php new file mode 100644 index 0000000..a6ae882 --- /dev/null +++ b/src/State/OpenFoodOrderProvider.php @@ -0,0 +1,21 @@ +repository->findOpenOrders(); + } +} diff --git a/tests/Feature/Api/ApiSmokeTest.php b/tests/Feature/Api/ApiSmokeTest.php index b18e141..df0bda1 100644 --- a/tests/Feature/Api/ApiSmokeTest.php +++ b/tests/Feature/Api/ApiSmokeTest.php @@ -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'); + } +}); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c79f857..11702bc 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,6 +1,7 @@ remove(dirname(__DIR__) . '/../var/cache/*');