package inventory import ( "context" "testing" "time" ) // ── Tests ──────────────────────────────────────────────────────────────── func TestInMemoryReserveAndRelease(t *testing.T) { ctx := context.Background() p := NewInMemoryReservationPolicy( SKU("ABC-1"), LocationID("se"), int64(10), SKU("ABC-1"), LocationID("no"), int64(5), ) // Reserve available stock err := p.Reserve(ctx, CartReserveRequest{ InventoryReference: &InventoryReference{SKU: "ABC-1", LocationID: "se"}, CartID: "cart-1", Quantity: 3, TTL: 15 * time.Minute, }) if err != nil { t.Fatalf("Reserve: %v", err) } avail, _ := p.Available(ctx, "ABC-1", "se") if avail != 7 { t.Fatalf("after reserve 3 of 10, expected 7 available, got %d", avail) } // Release if err := p.Release(ctx, "ABC-1", "se", "cart-1"); err != nil { t.Fatalf("Release: %v", err) } avail, _ = p.Available(ctx, "ABC-1", "se") if avail != 10 { t.Fatalf("after release, expected 10 available, got %d", avail) } } func TestInMemoryInsufficientStock(t *testing.T) { ctx := context.Background() p := NewInMemoryReservationPolicy( SKU("ABC-1"), LocationID("se"), int64(2), ) err := p.Reserve(ctx, CartReserveRequest{ InventoryReference: &InventoryReference{SKU: "ABC-1", LocationID: "se"}, CartID: "cart-1", Quantity: 5, TTL: 15 * time.Minute, }) if err == nil { t.Fatal("expected insufficient stock error, got nil") } } func TestInMemoryConcurrentReserves(t *testing.T) { ctx := context.Background() p := NewInMemoryReservationPolicy( SKU("ABC-1"), LocationID("se"), int64(100), ) errs := make(chan error, 10) for i := 0; i < 10; i++ { go func(n int) { errs <- p.Reserve(ctx, CartReserveRequest{ InventoryReference: &InventoryReference{SKU: "ABC-1", LocationID: "se"}, CartID: CartID(string(rune('0' + n))), Quantity: 10, TTL: 15 * time.Minute, }) }(i) } for i := 0; i < 10; i++ { if err := <-errs; err != nil { t.Errorf("concurrent reserve %d: %v", i, err) } } avail, _ := p.Available(ctx, "ABC-1", "se") if avail != 0 { t.Fatalf("after 10×10 reserves from 100, expected 0 available, got %d", avail) } }