Coupon test matrix
Standing cases for the dev coupon flow. Source of truth for payloads is the coupon test sheet, tab test result - dev website. Run them with run-coupon-test-matrix.
Status as of 2026-07-29 (deploy 094bd0c)
| # | Type | Coupon | Status |
|---|---|---|---|
| 1, 2 | bogo, same / different SKU | 1260002128, 1260002754 | pass |
| 5, 6 | buy 2 get 1, same / different SKU | 1260002828, 1260002848 | pass |
| 7 | two-for-X, same SKU | 1260002784 | pass — was “no discount” |
| 8 | two-for-X, different SKU | 1260002613 | pass — was “no discount” |
| 9 | fixed, min 2000 save 50 | MINDIS50 | pass |
| 10 | specific SKU, 150 off | HACOD150 | pass — was “no discount” |
| 11 | shipping discount 50 | TSHIPDIS | pass — was waiving all 90 |
| 11b | shipping discount 50, express | TSHIPDIS | pass — was waiving all 90 |
| 12, 13 | free shipping, regular / express | FREESHIP | pass |
Fixes behind the four recoveries: 2026-07-29-coupon-test-sheet-failures.
The assertion that catches everything
Every response must balance. Both bugs above showed up as a failure of this identity before anyone looked at a coupon:
expected = subTotal + deliveryFee + expressShippingCost - totalDiscount - shippingDiscount
assert abs(grandTotal - expected) < 0.01Omitting expressShippingCost makes correct express orders look wrong by exactly 50 baht — that is a bug in the check, not in the response.
Gaps worth adding
The current sheet exercises one coupon type at a time, almost always on NATIONWIDE. These are untested and each maps to a plausible failure:
Percentage with maxDiscountAmount. The same capped-amount shape that broke TSHIPDIS. A percentage coupon that hits its cap should discount the cap, not the raw percentage.
Shipping discount larger than the delivery fee. Should clamp at the fee. A negative delivery fee would flow straight into the grand total.
Two-for-X where the set subtotal is below the discount. Per-set cap should bind, so the discount never exceeds what the items cost.
The same coupon across all three shipping modes. Fees differ (90 regular, 90+50 express, 115 nationwide) and only nationwide is covered today.
appOnly / webOnly with the wrong orderSource. Should land in failedCoupons, not apply silently.
Expired and not-yet-started coupons. This was the original report that started the July investigation and still isn’t a standing case.
Controlled products with excludeControlledProducts. Alcohol should drop out of the applicable total.
Stacking — bogo + two-for-X + free shipping on one basket, asserting the Discount line in the UI equals the drop in Total. Every bug so far has been a single-coupon case; the stacked path is unexercised.
Below minOrderAmount. Should produce no discount and no error. Distinguishing this from a broken coupon is currently guesswork for testers.
UI checks the API cannot cover
The API being right does not mean the customer sees it right — row 10 was correct at the API level for weeks while the UI showed 0.
- The Discount line equals the drop in Total
- Shipping discount appears as its own line
- Regular is selectable for a Bangkok address (2026-07-29-shipping-forced-nationwide)
- Network calls go to
/api/calculatePrice/calculateCost2, never tom4q33ulvm9