chore: build
Backend - Build & Lint / build (push) Canceled after 0s

This commit is contained in:
Xor290
2026-08-25 18:52:55 +02:00
parent f469e52c32
commit 30eebd12d2
3 changed files with 108 additions and 3 deletions
@@ -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)
}
}