testitest
This commit is contained in:
parent
43ca79f650
commit
66c4c1fe4f
30 changed files with 4443 additions and 184 deletions
455
tests/Feature/Service/OrderServiceTest.php
Normal file
455
tests/Feature/Service/OrderServiceTest.php
Normal file
|
@ -0,0 +1,455 @@
|
|||
<?php
|
||||
|
||||
use App\Entity\DrinkType;
|
||||
use App\Entity\Order;
|
||||
use App\Entity\OrderItem;
|
||||
use App\Enum\OrderStatus;
|
||||
use App\Repository\DrinkTypeRepository;
|
||||
use App\Repository\OrderItemRepository;
|
||||
use App\Repository\OrderRepository;
|
||||
use App\Service\InventoryService;
|
||||
use App\Service\OrderService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
test('getAllOrders returns all orders', function () {
|
||||
// Arrange
|
||||
$orderService = $this->getContainer()->get(OrderService::class);
|
||||
|
||||
// Act
|
||||
$orders = $orderService->getAllOrders();
|
||||
|
||||
// Assert
|
||||
expect($orders)->toBeArray();
|
||||
});
|
||||
|
||||
test('getOrderById returns correct order', function () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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 () {
|
||||
// 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) => $item->getDrinkType()->getId() === $drinkType->getId()
|
||||
);
|
||||
expect($matchingItems->count())->toBe(1);
|
||||
});
|
||||
|
||||
test('removeOrderItem removes item from order', function () {
|
||||
// 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) => $item->getDrinkType()->getId() === $drinkType->getId()
|
||||
);
|
||||
expect($matchingItems->count())->toBe(0);
|
||||
});
|
||||
|
||||
test('deleteOrder removes order and its items', function () {
|
||||
// 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();
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue