getContainer()->get(OrderService::class); // Act $orders = $orderService->getAllOrders(); // Assert expect($orders)->toBeArray(); }); test('getOrderById returns correct order', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create an order $order = new Order(); $order->setStatus(OrderStatus::NEW); $em->persist($order); $em->flush(); $id = $order->getId(); // Act $retrievedOrder = $orderService->getOrderById($id); // Assert expect($retrievedOrder)->toBeInstanceOf(Order::class); expect($retrievedOrder->getId())->toBe($id); }); test('getOrderById returns null for non-existent id', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $nonExistentId = 9999; // Act $order = $orderService->getOrderById($nonExistentId); // Assert expect($order)->toBeNull(); }); test('getOrdersByStatus returns orders with specific status', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create orders with different statuses $order1 = new Order(); $order1->setStatus(OrderStatus::NEW); $em->persist($order1); $order2 = new Order(); $order2->setStatus(OrderStatus::ORDERED); $em->persist($order2); $order3 = new Order(); $order3->setStatus(OrderStatus::NEW); $em->persist($order3); $em->flush(); // Act $newOrders = $orderService->getOrdersByStatus(OrderStatus::NEW); $orderedOrders = $orderService->getOrdersByStatus(OrderStatus::ORDERED); // Assert expect($newOrders)->toBeArray(); expect(count($newOrders))->toBeGreaterThanOrEqual(2); expect($orderedOrders)->toBeArray(); expect(count($orderedOrders))->toBeGreaterThanOrEqual(1); foreach ($newOrders as $order) { expect($order)->toBeInstanceOf(Order::class); expect($order->getStatus())->toBe(OrderStatus::NEW); } foreach ($orderedOrders as $order) { expect($order)->toBeInstanceOf(Order::class); expect($order->getStatus())->toBe(OrderStatus::ORDERED); } }); test('getActiveOrders returns orders with active statuses', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create orders with different statuses $order1 = new Order(); $order1->setStatus(OrderStatus::NEW); $em->persist($order1); $order2 = new Order(); $order2->setStatus(OrderStatus::ORDERED); $em->persist($order2); $order3 = new Order(); $order3->setStatus(OrderStatus::FULFILLED); $em->persist($order3); $order4 = new Order(); $order4->setStatus(OrderStatus::CANCELLED); $em->persist($order4); $em->flush(); // Act $activeOrders = $orderService->getActiveOrders(); // Assert expect($activeOrders)->toBeArray(); foreach ($activeOrders as $order) { expect($order)->toBeInstanceOf(Order::class); expect($order->getStatus())->toBeIn([OrderStatus::NEW, OrderStatus::ORDERED, OrderStatus::IN_WORK]); } }); test('getMostRecentActiveOrder returns most recent active order', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create orders with different statuses and timestamps $order1 = new Order(); $order1->setStatus(OrderStatus::NEW); $order1->setUpdatedAt(new DateTimeImmutable('-2 days')); $em->persist($order1); $em->flush(); // Sleep to ensure different timestamps $order2 = new Order(); $order2->setStatus(OrderStatus::IN_WORK); $order2->setUpdatedAt(new DateTimeImmutable('-1 day')); $em->persist($order2); $em->flush(); // Act $recentOrder = $orderService->getMostRecentActiveOrder(); // Assert expect($recentOrder)->toBeInstanceOf(Order::class); expect($recentOrder->getId())->toBe($order2->getId()); }); test('hasActiveOrders returns true when active orders exist', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create an active order $order = new Order(); $order->setStatus(OrderStatus::NEW); $em->persist($order); $em->flush(); // Act $hasActiveOrders = $orderService->hasActiveOrders(); // Assert expect($hasActiveOrders)->toBeTrue(); }); test('getOrdersByDateRange returns orders within date range', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create orders $order1 = new Order(); $order1->setStatus(OrderStatus::NEW); $em->persist($order1); $em->flush(); $start = new DateTimeImmutable('-1 day'); $end = new DateTimeImmutable('+1 day'); // Act $orders = $orderService->getOrdersByDateRange($start, $end); // Assert expect($orders)->toBeArray(); expect(count($orders))->toBeGreaterThanOrEqual(1); foreach ($orders as $order) { expect($order)->toBeInstanceOf(Order::class); expect($order->getCreatedAt()->getTimestamp())->toBeGreaterThanOrEqual($start->getTimestamp()); expect($order->getCreatedAt()->getTimestamp())->toBeLessThanOrEqual($end->getTimestamp()); } }); test('createOrder creates new order with items', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create drink types $drinkType1 = new DrinkType(); $drinkType1->setName('Drink Type 1 for Order'); $drinkType1->setDesiredStock(10); $em->persist($drinkType1); $drinkType2 = new DrinkType(); $drinkType2->setName('Drink Type 2 for Order'); $drinkType2->setDesiredStock(5); $em->persist($drinkType2); $em->flush(); $items = [ [ 'drinkTypeId' => $drinkType1->getId(), 'quantity' => 3, ], [ 'drinkTypeId' => $drinkType2->getId(), 'quantity' => 2, ], ]; // Act $order = $orderService->createOrder($items); // Assert expect($order)->toBeInstanceOf(Order::class); expect($order->getStatus())->toBe(OrderStatus::NEW); expect($order->getOrderItems()->count())->toBe(2); $orderItems = $order->getOrderItems()->toArray(); expect($orderItems[0]->getDrinkType()->getId())->toBe($drinkType1->getId()); expect($orderItems[0]->getQuantity())->toBe(3); expect($orderItems[1]->getDrinkType()->getId())->toBe($drinkType2->getId()); expect($orderItems[1]->getQuantity())->toBe(2); }); test('createOrderFromStockLevels creates order based on stock levels', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $inventoryService = $this->getContainer()->get(InventoryService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create drink types with stock levels below desired stock $drinkType1 = new DrinkType(); $drinkType1->setName('Low Stock Drink Type 1'); $drinkType1->setDesiredStock(10); $em->persist($drinkType1); $drinkType2 = new DrinkType(); $drinkType2->setName('Low Stock Drink Type 2'); $drinkType2->setDesiredStock(8); $em->persist($drinkType2); $drinkType3 = new DrinkType(); $drinkType3->setName('Sufficient Stock Drink Type'); $drinkType3->setDesiredStock(5); $em->persist($drinkType3); $em->flush(); // Set stock levels $inventoryService->updateStockLevel($drinkType1, 2); // Low stock $inventoryService->updateStockLevel($drinkType2, 3); // Low stock $inventoryService->updateStockLevel($drinkType3, 10); // Sufficient stock // Act $order = $orderService->createOrderFromStockLevels(); // Assert expect($order)->toBeInstanceOf(Order::class); expect($order->getStatus())->toBe(OrderStatus::NEW); // Should only include items for drink types with low stock $orderItems = $order->getOrderItems()->toArray(); $drinkTypeIds = array_map(fn($item) => $item->getDrinkType()->getId(), $orderItems); expect($drinkTypeIds)->toContain($drinkType1->getId()); expect($drinkTypeIds)->toContain($drinkType2->getId()); expect($drinkTypeIds)->not->toContain($drinkType3->getId()); // Check quantities foreach ($orderItems as $item) { $drinkType = $item->getDrinkType(); $currentStock = $inventoryService->getCurrentStockLevel($drinkType); $desiredStock = $drinkType->getDesiredStock(); $expectedQuantity = $desiredStock - $currentStock; expect($item->getQuantity())->toBe($expectedQuantity); } }); test('updateOrderStatus updates order status', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create an order $order = new Order(); $order->setStatus(OrderStatus::NEW); $em->persist($order); $em->flush(); // Act $updatedOrder = $orderService->updateOrderStatus($order, OrderStatus::ORDERED); // Assert expect($updatedOrder)->toBeInstanceOf(Order::class); expect($updatedOrder->getStatus())->toBe(OrderStatus::ORDERED); // Verify the status was updated in the database }); test('addOrderItem adds item to order', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create an order $order = new Order(); $order->setStatus(OrderStatus::NEW); $em->persist($order); // Create a drink type $drinkType = new DrinkType(); $drinkType->setName('Drink Type for Order Item'); $drinkType->setDesiredStock(10); $em->persist($drinkType); $em->flush(); $quantity = 5; // Act $orderItem = $orderService->addOrderItem($order, $drinkType, $quantity); // Assert expect($orderItem)->toBeInstanceOf(OrderItem::class); expect($orderItem->getOrder()->getId())->toBe($order->getId()); expect($orderItem->getDrinkType()->getId())->toBe($drinkType->getId()); expect($orderItem->getQuantity())->toBe($quantity); // Verify the item was added to the order expect($order->getOrderItems()->contains($orderItem))->toBeTrue(); }); test('addOrderItem updates quantity if item already exists', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create an order $order = new Order(); $order->setStatus(OrderStatus::NEW); $em->persist($order); // Create a drink type $drinkType = new DrinkType(); $drinkType->setName('Drink Type for Existing Order Item'); $drinkType->setDesiredStock(10); $em->persist($drinkType); $em->flush(); // Add an item $initialQuantity = 3; $orderItem = $orderService->addOrderItem($order, $drinkType, $initialQuantity); // Act - add another item with the same drink type $additionalQuantity = 2; $updatedOrderItem = $orderService->addOrderItem($order, $drinkType, $additionalQuantity); // Assert expect($updatedOrderItem)->toBeInstanceOf(OrderItem::class); expect($updatedOrderItem->getId())->toBe($orderItem->getId()); expect($updatedOrderItem->getQuantity())->toBe($initialQuantity + $additionalQuantity); // Verify the order still has only one item for this drink type $matchingItems = $order->getOrderItems()->filter( fn($item): bool => $item->getDrinkType()->getId() === $drinkType->getId() ); expect($matchingItems->count())->toBe(1); }); test('removeOrderItem removes item from order', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create an order $order = new Order(); $order->setStatus(OrderStatus::NEW); $em->persist($order); // Create a drink type $drinkType = new DrinkType(); $drinkType->setName('Drink Type for Order Item Removal'); $drinkType->setDesiredStock(10); $em->persist($drinkType); $em->flush(); // Add an item $orderItem = $orderService->addOrderItem($order, $drinkType, 5); // Act $orderService->removeOrderItem($order, $orderItem); // Assert expect($order->getOrderItems()->contains($orderItem))->toBeFalse(); // Verify the item was removed from the database $em->refresh($order); $matchingItems = $order->getOrderItems()->filter( fn($item): bool => $item->getDrinkType()->getId() === $drinkType->getId() ); expect($matchingItems->count())->toBe(0); }); test('deleteOrder removes order and its items', function (): void { // Arrange $orderService = $this->getContainer()->get(OrderService::class); $em = $this->getContainer()->get(EntityManagerInterface::class); // Create an order $order = new Order(); $order->setStatus(OrderStatus::NEW); $em->persist($order); // Create a drink type $drinkType = new DrinkType(); $drinkType->setName('Drink Type for Order Deletion'); $drinkType->setDesiredStock(10); $em->persist($drinkType); $em->flush(); // Add an item $orderItem = $orderService->addOrderItem($order, $drinkType, 5); $orderItemId = $orderItem->getId(); $orderId = $order->getId(); // Act $orderService->deleteOrder($order); // Assert $deletedOrder = $orderService->getOrderById($orderId); expect($deletedOrder)->toBeNull(); // Verify the order items were also deleted $orderItemRepo = $this->getContainer()->get(OrderItemRepository::class); $deletedOrderItem = $orderItemRepo->find($orderItemId); expect($deletedOrderItem)->toBeNull(); });