promotions
Build and Publish / BuildAndDeployArm64 (push) Failing after 6s
Build and Publish / BuildAndDeployAmd64 (push) Has been cancelled

This commit is contained in:
2026-06-18 11:32:19 +02:00
parent 2545be4315
commit 2443fd8b49
9 changed files with 583 additions and 55 deletions
+42
View File
@@ -0,0 +1,42 @@
package promotions
import "testing"
// TestEvaluatePartialCart exercises the stateless evaluation path used by
// POST /promotions/evaluate: items drive the total, qualifying effects apply,
// and near-miss rules surface as pending nudges.
func TestEvaluatePartialCart(t *testing.T) {
svc := NewPromotionService(nil)
rules := []PromotionRule{volymrabattRule()}
now := timeZero()
t.Run("items qualify for a tier", func(t *testing.T) {
// 2 × 25 000 kr (incl. VAT) = 50 000 kr -> 9% tier.
resp := svc.Evaluate(rules, EvaluateRequest{
Now: &now,
Items: []EvalItem{
{Sku: "A", Quantity: 2, PriceIncVat: 2500000},
},
})
if resp.TotalDiscount.IncVat != 450000 {
t.Errorf("discount = %d, want 450000", resp.TotalDiscount.IncVat)
}
if len(resp.AppliedPromotions) != 1 || resp.AppliedPromotions[0].Pending {
t.Fatalf("want 1 applied (non-pending) effect, got %+v", resp.AppliedPromotions)
}
})
t.Run("total-only fallback surfaces a pending nudge", func(t *testing.T) {
// No items, just a total below the entry tier.
resp := svc.Evaluate(rules, EvaluateRequest{Now: &now, CartTotalIncVat: 1500000})
if resp.TotalDiscount.IncVat != 0 {
t.Errorf("nothing should apply, discount = %d", resp.TotalDiscount.IncVat)
}
if len(resp.AppliedPromotions) != 1 || !resp.AppliedPromotions[0].Pending {
t.Fatalf("want 1 pending nudge, got %+v", resp.AppliedPromotions)
}
if got := resp.AppliedPromotions[0].Progress["remaining"]; got != int64(500000) {
t.Errorf("remaining = %v, want 500000", got)
}
})
}