add open orders api route #86

Merged
lubiana merged 1 commit from add-open-orders-api-route into main 2025-04-23 17:00:13 +00:00
5 changed files with 79 additions and 0 deletions
Showing only changes of commit 96b246462a - Show all commits

View file

@ -3,7 +3,9 @@
namespace App\Entity; namespace App\Entity;
use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GetCollection;
use App\Repository\FoodOrderRepository; use App\Repository\FoodOrderRepository;
use App\State\OpenFoodOrderProvider;
use DateInterval; use DateInterval;
use DateTimeImmutable; use DateTimeImmutable;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
@ -15,6 +17,10 @@ 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] #[ApiResource]
class FoodOrder class FoodOrder
{ {

View file

@ -47,4 +47,19 @@ final class FoodOrderRepository extends ServiceEntityRepository
->filter(static fn(FoodOrder $order): bool => $order->getCreatedAt() >= $date) ->filter(static fn(FoodOrder $order): bool => $order->getCreatedAt() >= $date)
->getValues(); ->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(); $array = $response->toArray();
expect($array['member'][0]['orderItems'])->toHaveCount(10); 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); <?php declare(strict_types=1);
use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\Filesystem\Filesystem;
require dirname(__DIR__) . '/vendor/autoload.php'; require dirname(__DIR__) . '/vendor/autoload.php';
@ -13,3 +14,6 @@ if (method_exists(Dotenv::class, 'bootEnv')) {
if ($_SERVER['APP_DEBUG']) { if ($_SERVER['APP_DEBUG']) {
umask(0o000); umask(0o000);
} }
$fs = new Filesystem;
$fs->remove(dirname(__DIR__) . '/../var/cache/*');