kitchen-service/tests/Kitchen.Service.Application.UnitTests/KitchenWorkflowUseCasesTests.cs

101 lines
4.0 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 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);
}
}