parent item mutations
This commit is contained in:
@@ -229,6 +229,106 @@ func TestCartResponse_Conversion(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestCartResponse_EvaluatedItems verifies that the per-line breakdown the
|
||||
// canonical promotion pipeline populates on CartGrain.EvaluatedItems flows
|
||||
// verbatim into the UCP CartResponse's EvaluatedItems field. Conversion is a
|
||||
// straight pass-through now — we hand-construct the grain's EvaluatedItems
|
||||
// field with the expected values to lock down the wire shape independent of
|
||||
// the math MapEvaluatedItems applies (which has its own tests in pkg/cart).
|
||||
func TestCartResponse_EvaluatedItems(t *testing.T) {
|
||||
id := mustParseID("ABCD")
|
||||
g := cart.NewCartGrain(id, time.UnixMilli(1000000))
|
||||
g.Currency = "SEK"
|
||||
g.Items = append(g.Items, &cart.CartItem{
|
||||
Sku: "promo-1",
|
||||
Quantity: 2,
|
||||
Price: *mustPrice(10000, 2500),
|
||||
TotalPrice: *mustPrice(20000, 5000),
|
||||
Tax: 2500,
|
||||
OrgPrice: mustPrice(12000, 3000),
|
||||
Discount: mustPrice(2000, 500),
|
||||
Meta: &cart.ItemMeta{Name: "Promo Item"},
|
||||
})
|
||||
g.TotalPrice = mustPrice(20000, 5000)
|
||||
|
||||
// In the live cart, pkg/promotions.PromotionService.EvaluateAndApply
|
||||
// populates g.EvaluatedItems via cart.MapEvaluatedItems after every
|
||||
// successful mutation. The conversion test only cares that whatever
|
||||
// the grain carries projects into resp.EvaluatedItems unchanged — so
|
||||
// the input is the canonical shape, not the math's output.
|
||||
g.EvaluatedItems = []cart.EvaluatedItem{{
|
||||
Sku: "promo-1",
|
||||
Name: "Promo Item",
|
||||
Quantity: 2,
|
||||
PriceIncVat: 10000,
|
||||
OrgPriceIncVat: 12000,
|
||||
DiscountIncVat: 2000,
|
||||
EffectivePriceIncVat: 9000,
|
||||
EffectiveTotalIncVat: 18000,
|
||||
}}
|
||||
|
||||
resp := cartGrainToResponse(g.Id.String(), g)
|
||||
if len(resp.EvaluatedItems) != 1 {
|
||||
t.Fatalf("expected 1 evaluated item, got %d", len(resp.EvaluatedItems))
|
||||
}
|
||||
ev := resp.EvaluatedItems[0]
|
||||
if ev.Sku != "promo-1" {
|
||||
t.Fatalf("expected sku 'promo-1', got %q", ev.Sku)
|
||||
}
|
||||
if ev.Name != "Promo Item" {
|
||||
t.Fatalf("expected name 'Promo Item', got %q", ev.Name)
|
||||
}
|
||||
if ev.Quantity != 2 {
|
||||
t.Fatalf("expected qty 2, got %d", ev.Quantity)
|
||||
}
|
||||
if ev.PriceIncVat != 10000 {
|
||||
t.Fatalf("expected priceIncVat 10000, got %d", ev.PriceIncVat)
|
||||
}
|
||||
if ev.OrgPriceIncVat != 12000 {
|
||||
t.Fatalf("expected orgPriceIncVat 12000, got %d", ev.OrgPriceIncVat)
|
||||
}
|
||||
if ev.DiscountIncVat != 2000 {
|
||||
t.Fatalf("expected discountIncVat 2000, got %d", ev.DiscountIncVat)
|
||||
}
|
||||
if ev.EffectiveTotalIncVat != 18000 {
|
||||
t.Fatalf("expected effectiveTotalIncVat 18000, got %d", ev.EffectiveTotalIncVat)
|
||||
}
|
||||
if ev.EffectivePriceIncVat != 9000 {
|
||||
t.Fatalf("expected effectivePriceIncVat 9000, got %d", ev.EffectivePriceIncVat)
|
||||
}
|
||||
}
|
||||
|
||||
// TestCartResponse_EvaluatedItems_MapEquivalence confirms that
|
||||
// cart.MapEvaluatedItems produces the same shape the test's hand-built
|
||||
// []cart.EvaluatedItem entries contain, given matching inputs. This locks
|
||||
// the conversion path's output to the canonical pipeline's output — if
|
||||
// either side starts omitting or renaming a field, this fails.
|
||||
func TestCartResponse_EvaluatedItems_MapEquivalence(t *testing.T) {
|
||||
id := mustParseID("ABCD")
|
||||
g := cart.NewCartGrain(id, time.UnixMilli(1000000))
|
||||
g.Currency = "SEK"
|
||||
g.Items = append(g.Items, &cart.CartItem{
|
||||
Sku: "promo-1",
|
||||
Quantity: 2,
|
||||
Price: *mustPrice(10000, 2500),
|
||||
TotalPrice: *mustPrice(20000, 5000),
|
||||
Tax: 2500,
|
||||
OrgPrice: mustPrice(12000, 3000),
|
||||
Discount: mustPrice(2000, 500),
|
||||
Meta: &cart.ItemMeta{Name: "Promo Item"},
|
||||
})
|
||||
g.TotalPrice = mustPrice(20000, 5000)
|
||||
|
||||
canonical := cart.MapEvaluatedItems(g)
|
||||
if len(canonical) != 1 {
|
||||
t.Fatalf("expected 1 evaluated item from MapEvaluatedItems, got %d", len(canonical))
|
||||
}
|
||||
e := canonical[0]
|
||||
if e.DiscountIncVat != 2000 || e.EffectiveTotalIncVat != 18000 || e.EffectivePriceIncVat != 9000 {
|
||||
t.Fatalf("MapEvaluatedItems math off: %+v", e)
|
||||
}
|
||||
}
|
||||
|
||||
func mustPrice(incVat int64, totalVat int64) *cart.Price {
|
||||
return &cart.Price{
|
||||
IncVat: money.Cents(incVat),
|
||||
|
||||
Reference in New Issue
Block a user