Run the coupon test matrix against dev

Replays every case from the coupon test sheet against dev and checks each response balances. See coupon-test-matrix for what is covered.

Pull the sheet

It is readable without credentials, so no OAuth setup is needed:

SHEET=15ZfsUYVf4n-x4_j9p07OCV56UYpavRUvSbfnHgfK_VM
curl -sSL -o /tmp/devtest.csv \
  "https://docs.google.com/spreadsheets/d/$SHEET/gviz/tq?tqx=out:csv&sheet=test%20result%20-%20dev%20website"

Get an API key

python3 - <<'PY'
import json, boto3
r = boto3.Session(profile_name='default').client('lambda', region_name='ap-southeast-1') \
      .invoke(FunctionName='get-apikey-master', Payload=b'{}')
open('/tmp/key.txt','w').write(json.loads(json.loads(r['Payload'].read())['body'])['key'])
PY

Keys expire after five hours; regenerate rather than debugging failed checking for expiry.

Replay

import csv, json, urllib.request
 
KEY = open('/tmp/key.txt').read().strip()
URL = 'https://dev.villamarket.net/api/calculatePrice/calculateCost2'
 
for row in csv.DictReader(open('/tmp/devtest.csv')):
    payload = json.loads(row['payload'])
    payload['bypassCache'] = True                 # or you read yesterday's shipping cost
    payload.setdefault('orderSource', 'WEB')
 
    req = urllib.request.Request(URL, json.dumps(payload).encode(), {
        'Content-Type': 'application/json',
        'Authorization': f'Bearer {KEY}',
    })
    d = json.loads(urllib.request.urlopen(req, timeout=90).read())
 
    expected = (d['subTotal'] + d['deliveryFee'] + (d.get('expressShippingCost') or 0)
                - d['totalDiscount'] - d['shippingDiscount'])
    ok = abs(d['grandTotal'] - expected) < 0.01
    print(row['no'], row['coupon code'] or row['coupon id'],
          'OK' if ok else 'IMBALANCED',
          {k: d.get(k) for k in ('totalDiscount', 'shippingDiscount', 'grandTotal')})

Reading a failure

An imbalance means calculatecost2 contradicted itself — a discount it reported was not applied. Compare totalDiscount against the individual fields to find which one is missing, then check discount-fields.

A zero discount is different and usually not a bug. Check in this order:

  1. Is the subtotal above the coupon’s minOrderAmount?
  2. Does orderSource match the coupon’s restriction?
  3. Is the coupon inside its date window?
  4. Does the shipping mode satisfy applicableWithNationwide?

If all four are fine, ask the checker directly — if VillaCoupon3 returns the discount and calculatecost2 doesn’t apply it, the bug is in the mapping, not the coupon:

curl -sS -X POST 'https://dev.villamarket.net/api/coupon2/couponChecker' \
  -H "Authorization: Bearer $(cat /tmp/key.txt)" -H 'Content-Type: application/json' \
  -d '{"couponCodeList":["TSHIPDIS"],"branchId":"1000","subTotal":3862,"deliveryFee":90,"orderSource":"WEB","productList":[]}'