@@ -175,3 +175,64 @@ func TestClaimMyReward_HTTPFlow_FailsAtomicallyWhenProductMissing(t *testing.T)
|
||||
t.Errorf("la récompense ne doit PAS être consommée si le produit est introuvable: got redeemed=%d want=0", redeemed["pool_0"])
|
||||
}
|
||||
}
|
||||
|
||||
// Une même catégorie peut avoir les deux types de récompense actifs en
|
||||
// parallèle (un lot de produits offerts + un lot de produits à -50%), chacun
|
||||
// avec sa propre sélection de produits (voir eligibleRewardProducts, qui
|
||||
// n'impose aucune unicité de catégorie dans CategoryConfigs). Un seul claim
|
||||
// doit alors ajouter les deux produits au panier, chacun tarifé selon son
|
||||
// propre type.
|
||||
func TestClaimMyReward_HTTPFlow_CategoryWithBothTypesSimultaneously(t *testing.T) {
|
||||
cleanupStockTestData(t)
|
||||
username := newTestClient(t, "reward_http_dual_type")
|
||||
freeProductID := newTestProduct(t, "RewardHTTPDualFree", 5)
|
||||
halfProductID := newTestProduct(t, "RewardHTTPDualHalf", 5)
|
||||
// newTestProduct crée les deux produits dans la catégorie "test", avec un
|
||||
// prix actif de 10.00€ pour quantity=1 (voir tests/main_test.go).
|
||||
|
||||
configureRewardSettings(t, &models.PointsReward{
|
||||
Threshold: 20,
|
||||
Description: "Un produit offert + un produit à -50%",
|
||||
CategoryConfigs: []models.RewardCategoryConfig{
|
||||
{Category: "test", Type: "free_product", ProductIDs: []int{freeProductID}},
|
||||
{Category: "test", Type: "half_price_product", ProductIDs: []int{halfProductID}},
|
||||
},
|
||||
RewardItems: []models.RewardItem{
|
||||
{ProductID: freeProductID, Quantity: 1, Price: 12},
|
||||
{ProductID: halfProductID, Quantity: 1, Price: 12},
|
||||
},
|
||||
})
|
||||
setClientPoolPoints(t, username, "pool_0", 20)
|
||||
|
||||
body, _ := json.Marshal(map[string]string{"pool_key": "pool_0"})
|
||||
c, rec := claimRewardContext(username, body)
|
||||
handlers.ClaimMyReward(c)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status HTTP: got=%d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
|
||||
rows := basketRewardItems(t, username)
|
||||
if len(rows) != 2 {
|
||||
t.Fatalf("les deux produits récompense doivent être dans le panier: %+v", rows)
|
||||
}
|
||||
|
||||
var freeRow, halfRow *rewardBasketRow
|
||||
for i := range rows {
|
||||
switch rows[i].ProductID {
|
||||
case freeProductID:
|
||||
freeRow = &rows[i]
|
||||
case halfProductID:
|
||||
halfRow = &rows[i]
|
||||
}
|
||||
}
|
||||
if freeRow == nil || halfRow == nil {
|
||||
t.Fatalf("les deux produits attendus doivent être présents: %+v", rows)
|
||||
}
|
||||
if freeRow.Price != 0 {
|
||||
t.Errorf("produit de la config free_product: le prix en panier doit être 0: got=%.2f", freeRow.Price)
|
||||
}
|
||||
if halfRow.Price != 5.0 {
|
||||
t.Errorf("produit de la config half_price_product: prix attendu = 50%% de 10.00€ = 5.00€: got=%.2f", halfRow.Price)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user