fixie
All checks were successful
/ ls (pull_request) Successful in 1m33s
/ ls (push) Successful in 1m28s
/ ls (release) Successful in 1m0s

This commit is contained in:
lubiana 2025-06-18 16:56:49 +02:00
parent 300c8cafc9
commit 6bb49e8f79
Signed by: lubiana
SSH key fingerprint: SHA256:vW1EA0fRR3Fw+dD/sM0K+x3Il2gSry6YRYHqOeQwrfk
6 changed files with 26 additions and 33 deletions

View file

@ -9,14 +9,15 @@ use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Post; use ApiPlatform\Metadata\Post;
use ApiPlatform\Metadata\Put; use ApiPlatform\Metadata\Put;
use App\Repository\FoodOrderRepository; use App\Repository\FoodOrderRepository;
use App\State\OpenOrdersProvider;
use App\State\LatestOrderProvider; use App\State\LatestOrderProvider;
use App\State\OpenOrdersProvider;
use DateInterval; use DateInterval;
use DateTimeImmutable; use DateTimeImmutable;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UlidType; use Symfony\Bridge\Doctrine\Types\UlidType;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Uid\Ulid; use Symfony\Component\Uid\Ulid;
use function iterator_to_array; use function iterator_to_array;
@ -28,10 +29,13 @@ use function iterator_to_array;
description: 'Get only open orders', description: 'Get only open orders',
provider: OpenOrdersProvider::class, provider: OpenOrdersProvider::class,
), ),
new GetCollection( new Get(
uriTemplate: 'food_orders/latest', uriTemplate: 'food_orders/latest',
description: 'Get the latest created order', description: 'Get the latest created order',
provider: LatestOrderProvider::class, provider: LatestOrderProvider::class,
normalizationContext: [
'groups' => ['food_order:read', 'food_order:latest'],
]
), ),
new GetCollection, new GetCollection,
new Get, new Get,
@ -44,26 +48,31 @@ use function iterator_to_array;
class FoodOrder class FoodOrder
{ {
#[ORM\Column(nullable: true)] #[ORM\Column(nullable: true)]
#[Groups(['food_order:read'])]
private DateTimeImmutable|null $closedAt = null; private DateTimeImmutable|null $closedAt = null;
#[ORM\ManyToOne(inversedBy: 'foodOrders')] #[ORM\ManyToOne(inversedBy: 'foodOrders')]
#[ORM\JoinColumn(nullable: false)] #[ORM\JoinColumn(nullable: false)]
#[Groups(['food_order:read', 'food_order:latest'])]
private FoodVendor|null $foodVendor = null; private FoodVendor|null $foodVendor = null;
/** /**
* @var Collection<int, OrderItem> * @var Collection<int, OrderItem>
*/ */
#[ORM\OneToMany(targetEntity: OrderItem::class, mappedBy: 'foodOrder', orphanRemoval: true)] #[ORM\OneToMany(targetEntity: OrderItem::class, mappedBy: 'foodOrder', orphanRemoval: true)]
#[Groups(['food_order:read', 'food_order:latest'])]
private Collection $orderItems; private Collection $orderItems;
#[ORM\Column(length: 255, options: [ #[ORM\Column(length: 255, options: [
'default' => 'nobody', 'default' => 'nobody',
])] ])]
#[Groups(['food_order:read'])]
private string|null $createdBy = 'nobody'; private string|null $createdBy = 'nobody';
public function __construct( public function __construct(
#[ORM\Id] #[ORM\Id]
#[ORM\Column(type: UlidType::NAME, unique: true)] #[ORM\Column(type: UlidType::NAME, unique: true)]
#[Groups(['food_order:read'])]
private Ulid|null $id = new Ulid private Ulid|null $id = new Ulid
) { ) {
$this->id ??= new Ulid; $this->id ??= new Ulid;
@ -76,6 +85,7 @@ class FoodOrder
return $this->id; return $this->id;
} }
#[Groups(['food_order:read'])]
public function getCreatedAt(): DateTimeImmutable public function getCreatedAt(): DateTimeImmutable
{ {
return $this->id->getDateTime(); return $this->id->getDateTime();

View file

@ -9,6 +9,7 @@ use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator; use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator;
use Symfony\Bridge\Doctrine\Types\UlidType; use Symfony\Bridge\Doctrine\Types\UlidType;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Uid\Ulid; use Symfony\Component\Uid\Ulid;
#[ORM\Entity(repositoryClass: FoodVendorRepository::class)] #[ORM\Entity(repositoryClass: FoodVendorRepository::class)]
@ -16,11 +17,13 @@ use Symfony\Component\Uid\Ulid;
class FoodVendor class FoodVendor
{ {
#[ORM\Column(length: 50)] #[ORM\Column(length: 50)]
#[Groups(['food_order:latest'])]
private string|null $name = null; private string|null $name = null;
#[ORM\Column(length: 50, nullable: true, options: [ #[ORM\Column(length: 50, nullable: true, options: [
'default' => '', 'default' => '',
])] ])]
#[Groups(['food_order:latest'])]
private string|null $phone = null; private string|null $phone = null;
/** /**
@ -36,6 +39,7 @@ class FoodVendor
private Collection $menuItems; private Collection $menuItems;
#[ORM\Column(length: 255, nullable: true)] #[ORM\Column(length: 255, nullable: true)]
#[Groups(['food_order:latest'])]
private string|null $menuLink = null; private string|null $menuLink = null;
public function __construct( public function __construct(
@ -43,6 +47,7 @@ class FoodVendor
#[ORM\GeneratedValue(strategy: 'CUSTOM')] #[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\Column(type: UlidType::NAME, unique: true)] #[ORM\Column(type: UlidType::NAME, unique: true)]
#[ORM\CustomIdGenerator(class: UlidGenerator::class)] #[ORM\CustomIdGenerator(class: UlidGenerator::class)]
#[Groups(['food_order:latest'])]
private Ulid|null $id = new Ulid private Ulid|null $id = new Ulid
) { ) {
$this->id ??= new Ulid; $this->id ??= new Ulid;

View file

@ -7,6 +7,7 @@ use App\Repository\OrderItemRepository;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator; use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator;
use Symfony\Bridge\Doctrine\Types\UlidType; use Symfony\Bridge\Doctrine\Types\UlidType;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Uid\Ulid; use Symfony\Component\Uid\Ulid;
#[ApiResource] #[ApiResource]
@ -14,9 +15,11 @@ use Symfony\Component\Uid\Ulid;
class OrderItem class OrderItem
{ {
#[ORM\Column(length: 255)] #[ORM\Column(length: 255)]
#[Groups(['food_order:latest'])]
private string|null $name = null; private string|null $name = null;
#[ORM\Column(length: 255, nullable: true)] #[ORM\Column(length: 255, nullable: true)]
#[Groups(['food_order:latest'])]
private string|null $extras = null; private string|null $extras = null;
#[ORM\ManyToOne(inversedBy: 'orderItems')] #[ORM\ManyToOne(inversedBy: 'orderItems')]
@ -25,11 +28,13 @@ class OrderItem
#[ORM\ManyToOne] #[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)] #[ORM\JoinColumn(nullable: false)]
#[Groups(['food_order:latest'])]
private MenuItem|null $menuItem = null; private MenuItem|null $menuItem = null;
#[ORM\Column(length: 255, options: [ #[ORM\Column(length: 255, options: [
'default' => 'nobody', 'default' => 'nobody',
])] ])]
#[Groups(['food_order:latest'])]
private string|null $createdBy = 'nobody'; private string|null $createdBy = 'nobody';
public function __construct( public function __construct(
@ -37,6 +42,7 @@ class OrderItem
#[ORM\GeneratedValue(strategy: 'CUSTOM')] #[ORM\GeneratedValue(strategy: 'CUSTOM')]
#[ORM\Column(type: UlidType::NAME, unique: true)] #[ORM\Column(type: UlidType::NAME, unique: true)]
#[ORM\CustomIdGenerator(class: UlidGenerator::class)] #[ORM\CustomIdGenerator(class: UlidGenerator::class)]
#[Groups(['food_order:latest'])]
private Ulid|null $id = new Ulid private Ulid|null $id = new Ulid
) { ) {
$this->id ??= new Ulid; $this->id ??= new Ulid;

View file

@ -63,10 +63,7 @@ final class FoodOrderRepository extends ServiceEntityRepository
->getResult(); ->getResult();
} }
/** public function findLatestOrder(): FoodOrder|null
* @return FoodOrder|null
*/
public function findLatestOrder(): ?FoodOrder
{ {
return $this->createQueryBuilder('alias') return $this->createQueryBuilder('alias')
->orderBy('alias.id', 'DESC') ->orderBy('alias.id', 'DESC')

View file

@ -15,8 +15,8 @@ final readonly class LatestOrderProvider implements ProviderInterface
) {} ) {}
#[Override] #[Override]
public function provide(Operation $operation, array $uriVariables = [], array $context = []): ?FoodOrder public function provide(Operation $operation, array $uriVariables = [], array $context = []): FoodOrder|null
{ {
return $this->repository->findLatestOrder(); return $this->repository->findLatestOrder();
} }
} }

View file

@ -230,31 +230,6 @@ describe(FoodOrderController::class, function (): void {
$openOrder = $this->repository->find($order->getId()); $openOrder = $this->repository->find($order->getId());
$this->assertTrue($openOrder->isClosed()); $this->assertTrue($openOrder->isClosed());
}); });
test('api_latest_order', function (): void {
// Create an older order
$olderOrder = new FoodOrder($this->generateOldUlid());
$olderOrder->setFoodVendor($this->vendor);
$this->manager->persist($olderOrder);
// Create the latest order
$latestOrder = new FoodOrder;
$latestOrder->setFoodVendor($this->vendor);
$this->manager->persist($latestOrder);
$this->manager->flush();
// Test the API endpoint
$this->client->request('GET', '/api/food_orders/latest');
$this->assertResponseIsSuccessful();
$this->assertResponseHeaderSame('Content-Type', 'application/ld+json; charset=utf-8');
$response = json_decode($this->client->getResponse()->getContent(), true);
$this->assertIsArray($response);
$this->assertArrayHasKey('@id', $response);
$this->assertStringContainsString($latestOrder->getId()->__toString(), $response['@id']);
});
}) })
->covers( ->covers(
FoodOrderController::class, FoodOrderController::class,