131 lines
5.1 KiB
C#
131 lines
5.1 KiB
C#
using Kitchen.Service.Application.Ports;
|
|
using Kitchen.Service.Application.UseCases;
|
|
using Kitchen.Service.Contracts.Requests;
|
|
|
|
namespace Kitchen.Service.Application.UnitTests;
|
|
|
|
public class KitchenWorkflowUseCasesTests
|
|
{
|
|
private readonly InMemoryKitchenWorkItemStorePort workItemStore = new();
|
|
private readonly InMemoryRestaurantLifecycleSyncPort restaurantLifecycle = new();
|
|
private readonly DefaultKitchenWorkflowPort workflowPort;
|
|
|
|
public KitchenWorkflowUseCasesTests()
|
|
{
|
|
workflowPort = new DefaultKitchenWorkflowPort(workItemStore, restaurantLifecycle);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetKitchenBoardUseCase_ReturnsLanesAndStations()
|
|
{
|
|
var useCase = new GetKitchenBoardUseCase(workflowPort);
|
|
|
|
var response = await useCase.HandleAsync(new GetKitchenBoardRequest("demo-context"), CancellationToken.None);
|
|
|
|
Assert.Equal("demo-context", response.ContextId);
|
|
Assert.NotEmpty(response.Lanes);
|
|
Assert.NotEmpty(response.AvailableStations);
|
|
Assert.Contains(response.Lanes, lane => lane.Lane == "queued");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetKitchenBoardUseCase_DerivesTicketForAcceptedRestaurantOrder()
|
|
{
|
|
await restaurantLifecycle.UpsertOrderAsync(
|
|
new Kitchen.Service.Application.State.PersistedRestaurantLifecycleRecord(
|
|
"demo-context",
|
|
"ORD-1099",
|
|
"CHK-1099",
|
|
"T-31",
|
|
"Accepted",
|
|
"Open",
|
|
3,
|
|
false,
|
|
42.00m,
|
|
"USD",
|
|
"customer-orders",
|
|
new[] { "ITEM-701", "ITEM-702" },
|
|
DateTime.UtcNow),
|
|
CancellationToken.None);
|
|
|
|
var useCase = new GetKitchenBoardUseCase(workflowPort);
|
|
var response = await useCase.HandleAsync(new GetKitchenBoardRequest("demo-context"), CancellationToken.None);
|
|
|
|
var queuedLane = Assert.Single(response.Lanes, lane => lane.Lane == "queued");
|
|
var derivedItem = Assert.Single(queuedLane.Items, item => item.OrderId == "ORD-1099");
|
|
|
|
Assert.Equal("hot-line", derivedItem.Station);
|
|
Assert.Equal("Queued", derivedItem.State);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ClaimKitchenWorkItemUseCase_ReturnsClaimedResponse()
|
|
{
|
|
var useCase = new ClaimKitchenWorkItemUseCase(workflowPort);
|
|
|
|
var response = await useCase.HandleAsync(
|
|
new ClaimKitchenWorkItemRequest("demo-context", "WK-1001", "chef-maya"),
|
|
CancellationToken.None);
|
|
|
|
var updated = await workItemStore.GetAsync("demo-context", "WK-1001", CancellationToken.None);
|
|
|
|
Assert.True(response.Claimed);
|
|
Assert.Equal("chef-maya", response.ClaimedBy);
|
|
Assert.Equal("chef-maya", updated!.ClaimedBy);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateKitchenPriorityUseCase_NormalizesPriority()
|
|
{
|
|
var useCase = new UpdateKitchenPriorityUseCase(workflowPort);
|
|
|
|
var response = await useCase.HandleAsync(
|
|
new UpdateKitchenPriorityRequest("demo-context", "WK-1001", 0, "expo-noah"),
|
|
CancellationToken.None);
|
|
|
|
var updated = await workItemStore.GetAsync("demo-context", "WK-1001", CancellationToken.None);
|
|
|
|
Assert.Equal(1, response.Priority);
|
|
Assert.Equal(1, updated!.Priority);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task TransitionKitchenOrderStateUseCase_UpdatesKitchenAndRestaurantFlow()
|
|
{
|
|
var useCase = new TransitionKitchenOrderStateUseCase(workflowPort);
|
|
|
|
var response = await useCase.HandleAsync(
|
|
new TransitionKitchenOrderStateRequest("ORD-1001", "KT-1001", "Preparing", "chef-maya"),
|
|
CancellationToken.None);
|
|
|
|
var updatedWorkItem = await workItemStore.GetAsync("demo-context", "WK-1001", CancellationToken.None);
|
|
var updatedOrder = await restaurantLifecycle.GetOrderAsync("demo-context", "ORD-1001", CancellationToken.None);
|
|
|
|
Assert.True(response.Applied);
|
|
Assert.Equal("Queued", response.PreviousState);
|
|
Assert.Equal("Preparing", response.CurrentState);
|
|
Assert.Equal("Preparing", updatedWorkItem!.State);
|
|
Assert.Equal("Preparing", updatedOrder!.OrderState);
|
|
Assert.True(updatedOrder.HasKitchenTicket);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task TransitionKitchenOrderStateUseCase_MarksOrderServedWhenKitchenDelivers()
|
|
{
|
|
var useCase = new TransitionKitchenOrderStateUseCase(workflowPort);
|
|
|
|
var response = await useCase.HandleAsync(
|
|
new TransitionKitchenOrderStateRequest("ORD-1003", "KT-1003", "Delivered", "expo-noah"),
|
|
CancellationToken.None);
|
|
|
|
var updatedWorkItem = await workItemStore.GetAsync("demo-context", "WK-1003", CancellationToken.None);
|
|
var updatedOrder = await restaurantLifecycle.GetOrderAsync("demo-context", "ORD-1003", CancellationToken.None);
|
|
|
|
Assert.True(response.Applied);
|
|
Assert.Equal("ReadyForPickup", response.PreviousState);
|
|
Assert.Equal("Delivered", response.CurrentState);
|
|
Assert.Equal("Delivered", updatedWorkItem!.State);
|
|
Assert.Equal("Served", updatedOrder!.OrderState);
|
|
}
|
|
}
|