operations-service/tests/Operations.Service.Application.UnitTests/OperationsWorkflowUseCasesTests.cs
2026-03-31 20:21:41 -06:00

194 lines
7.2 KiB
C#

using Operations.Service.Application.Ports;
using Operations.Service.Application.UseCases;
using Operations.Service.Contracts.Requests;
namespace Operations.Service.Application.UnitTests;
public class OperationsWorkflowUseCasesTests
{
private readonly InMemoryRestaurantLifecycleStorePort lifecycleStore = new();
private readonly DefaultOperationsWorkflowPort workflowPort;
public OperationsWorkflowUseCasesTests()
{
workflowPort = new DefaultOperationsWorkflowPort(lifecycleStore);
}
[Fact]
public async Task GetWaiterAssignmentsUseCase_ReturnsAssignmentsAndActivity()
{
var useCase = new GetWaiterAssignmentsUseCase(workflowPort);
var response = await useCase.HandleAsync(new GetWaiterAssignmentsRequest("demo-context"), CancellationToken.None);
Assert.Equal("demo-context", response.ContextId);
Assert.NotEmpty(response.Assignments);
Assert.NotEmpty(response.RecentActivity);
Assert.Contains(response.Assignments, assignment => assignment.Status == "ready-for-check");
}
[Fact]
public async Task SubmitRestaurantOrderUseCase_WhenRequestValid_PersistsAcceptedOrder()
{
var useCase = new SubmitRestaurantOrderUseCase(workflowPort);
var response = await useCase.HandleAsync(
new SubmitRestaurantOrderRequest("demo-context", "ORD-101", "T-12", 3),
CancellationToken.None);
var persisted = await lifecycleStore.GetOrderAsync("demo-context", "ORD-101", CancellationToken.None);
Assert.True(response.Accepted);
Assert.Equal("accepted", response.Status);
Assert.NotNull(persisted);
Assert.Equal("Accepted", persisted!.OrderState);
}
[Fact]
public async Task GetCustomerOrderStatusUseCase_ReturnsOrdersFromSharedLifecycleStore()
{
var useCase = new GetCustomerOrderStatusUseCase(workflowPort);
var response = await useCase.HandleAsync(new GetCustomerOrderStatusRequest("demo-context"), CancellationToken.None);
Assert.Equal("demo-context", response.ContextId);
Assert.NotEmpty(response.Orders);
Assert.NotEmpty(response.RecentEvents);
Assert.Contains(response.Orders, order => order.OrderId == "ORD-1001");
}
[Fact]
public async Task GetCustomerOrderDetailUseCase_ReturnsSpecificLifecycleOrder()
{
var useCase = new GetCustomerOrderDetailUseCase(workflowPort);
var response = await useCase.HandleAsync(
new GetCustomerOrderDetailRequest("demo-context", "ORD-1001"),
CancellationToken.None);
Assert.Equal("demo-context", response.ContextId);
Assert.NotNull(response.Order);
Assert.Equal("ORD-1001", response.Order!.OrderId);
Assert.NotEmpty(response.RecentEvents);
}
[Fact]
public async Task GetCustomerOrderHistoryUseCase_ReturnsLifecycleBackedHistory()
{
var useCase = new GetCustomerOrderHistoryUseCase(workflowPort);
var response = await useCase.HandleAsync(
new GetCustomerOrderHistoryRequest("demo-context"),
CancellationToken.None);
Assert.Equal("demo-context", response.ContextId);
Assert.NotEmpty(response.Orders);
Assert.NotEmpty(response.RecentEvents);
Assert.Contains("lifecycle-backed history", response.Summary);
}
[Fact]
public async Task GetPosTransactionSummaryUseCase_ReturnsOnlyPayableChecks()
{
var useCase = new GetPosTransactionSummaryUseCase(workflowPort);
var response = await useCase.HandleAsync(new GetPosTransactionSummaryRequest("demo-context"), CancellationToken.None);
Assert.Equal("USD", response.Currency);
Assert.NotEmpty(response.RecentPayments);
Assert.All(response.RecentPayments, payment => Assert.Equal("check", payment.PaymentMethod));
}
[Fact]
public async Task GetPosTransactionDetailUseCase_ReturnsLifecycleBackedCheck()
{
var useCase = new GetPosTransactionDetailUseCase(workflowPort);
var response = await useCase.HandleAsync(
new GetPosTransactionDetailRequest("demo-context", "CHK-1002"),
CancellationToken.None);
Assert.Equal("demo-context", response.ContextId);
Assert.NotNull(response.Transaction);
Assert.Equal("CHK-1002", response.Transaction!.TransactionId);
Assert.Equal("awaiting-payment", response.Transaction.Status);
}
[Fact]
public async Task CapturePosPaymentUseCase_WhenOrderServed_ReturnsCapturedStatus()
{
var useCase = new CapturePosPaymentUseCase(workflowPort);
var response = await useCase.HandleAsync(
new CapturePosPaymentRequest("demo-context", "CHK-1002", 37.50m, "USD", "card"),
CancellationToken.None);
var updated = await lifecycleStore.GetOrderAsync("demo-context", "ORD-1002", CancellationToken.None);
Assert.True(response.Succeeded);
Assert.Equal("captured", response.Status);
Assert.NotNull(updated);
Assert.Equal("Paid", updated!.OrderState);
Assert.Equal("Paid", updated!.CheckState);
Assert.Equal(0m, updated.OutstandingBalance);
}
[Fact]
public async Task CapturePosPaymentUseCase_WhenPaymentIsPartial_KeepsOrderServed()
{
var useCase = new CapturePosPaymentUseCase(workflowPort);
var response = await useCase.HandleAsync(
new CapturePosPaymentRequest("demo-context", "CHK-1002", 12.50m, "USD", "card"),
CancellationToken.None);
var updated = await lifecycleStore.GetOrderAsync("demo-context", "ORD-1002", CancellationToken.None);
Assert.True(response.Succeeded);
Assert.Equal("partial", response.Status);
Assert.NotNull(updated);
Assert.Equal("Served", updated!.OrderState);
Assert.Equal("AwaitingPayment", updated.CheckState);
Assert.Equal(25.00m, updated.OutstandingBalance);
}
[Fact]
public async Task CapturePosPaymentUseCase_WhenOrderNotServed_ReturnsBlockedStatus()
{
var useCase = new CapturePosPaymentUseCase(workflowPort);
var response = await useCase.HandleAsync(
new CapturePosPaymentRequest("demo-context", "ORD-1001", 12m, "USD", "card"),
CancellationToken.None);
Assert.False(response.Succeeded);
Assert.Equal("blocked", response.Status);
}
[Fact]
public async Task GetRestaurantAdminConfigUseCase_ReturnsFlagsWindowsAndChanges()
{
var useCase = new GetRestaurantAdminConfigUseCase(workflowPort);
var response = await useCase.HandleAsync(new GetRestaurantAdminConfigRequest("demo-context"), CancellationToken.None);
Assert.Equal("demo-context", response.ContextId);
Assert.NotEmpty(response.FeatureFlags);
Assert.NotEmpty(response.ServiceWindows);
Assert.NotEmpty(response.RecentChanges);
}
[Fact]
public async Task SetServiceWindowUseCase_WhenRequestValid_ReturnsAppliedResponse()
{
var useCase = new SetServiceWindowUseCase(workflowPort);
var response = await useCase.HandleAsync(
new SetServiceWindowRequest("demo-context", 1, "08:00:00", "22:00:00", "admin-operator"),
CancellationToken.None);
Assert.True(response.Applied);
Assert.Equal(1, response.ServiceWindow.DayOfWeek);
}
}