Add round 2: split multi-step OrderBook tests (example created by participant)

- Add OrderBookDomain: in-memory order book with Pending →
  WaitingForPayment → Fulfilling → Delivered state machine, payment
  window based on passed-in timestamps, cancellation rules
- Add OrderBookTests: 7 integration tests in given/when/then/when/then
  anti-pattern style as starting material for the exercise
- Learning hour: add round 2 where participants create the example
  themselves before showing it to the agent (no refactored test given)
- Fix sln: OrderTests Debug config was mapped to Release
This commit is contained in:
Your Name
2026-09-03 13:50:38 +00:00
parent 3b7e880717
commit e8748ee697
7 changed files with 292 additions and 5 deletions
@@ -0,0 +1,69 @@
namespace OrderBookDomain;
public class OrderBook
{
private readonly TimeSpan _paymentWindow;
private readonly Dictionary<int, Order> _ordersById = new();
private int _nextId = 1;
public OrderBook(TimeSpan? paymentWindow = null)
=> _paymentWindow = paymentWindow ?? TimeSpan.FromDays(14);
public IReadOnlyList<Order> Orders => _ordersById.Values.ToList();
public Order OpenOrder(string customer)
{
var order = new Order(_nextId++, customer);
_ordersById[order.Id] = order;
return order;
}
public Order GetOrder(int orderId)
=> _ordersById.TryGetValue(orderId, out var order)
? order
: throw new InvalidOperationException($"Unknown order id {orderId}.");
public void FinalizeOrder(int orderId, DateTimeOffset finalizedAt)
{
var order = GetOrder(orderId);
RequireStatus(order, OrderStatus.Pending, "finalize");
order.Status = OrderStatus.WaitingForPayment;
order.FinalizedAt = finalizedAt;
}
public void PayOrder(int orderId, DateTimeOffset paidAt)
{
var order = GetOrder(orderId);
RequireStatus(order, OrderStatus.WaitingForPayment, "pay");
if (paidAt - order.FinalizedAt > _paymentWindow)
{
order.Status = OrderStatus.Cancelled;
throw new InvalidOperationException(
$"Payment for order {orderId} arrived after the payment window; the order was cancelled.");
}
order.Status = OrderStatus.Fulfilling;
}
public void ShipOrder(int orderId)
{
var order = GetOrder(orderId);
RequireStatus(order, OrderStatus.Fulfilling, "ship");
order.Status = OrderStatus.Delivered;
}
public void CancelOrder(int orderId)
{
var order = GetOrder(orderId);
if (order.Status is not (OrderStatus.Pending or OrderStatus.WaitingForPayment))
throw new InvalidOperationException(
$"Cannot cancel order {orderId} in status {order.Status}.");
order.Status = OrderStatus.Cancelled;
}
private static void RequireStatus(Order order, OrderStatus expected, string action)
{
if (order.Status != expected)
throw new InvalidOperationException(
$"Cannot {action} order {order.Id} in status {order.Status} (expected {expected}).");
}
}