[
{"name": "1 point per whole pound at the base tier", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 2349, "currency": "GBP"}, {"minor": 10000, "currency": "GBP"}, 0, 0], "expect": {"tier": "Bronze", "multiplierBasisPoints": 10000, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 2349, "currency": "GBP"}, "earnedPoints": 23, "newBalance": 23}},
{"name": "Silver earns 1.25x, rounded down", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 2349, "currency": "GBP"}, {"minor": 60000, "currency": "GBP"}, 0, 0], "expect": {"tier": "Silver", "multiplierBasisPoints": 12500, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 2349, "currency": "GBP"}, "earnedPoints": 28, "newBalance": 28}},
{"name": "reaching the Gold threshold exactly gives Gold", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 2349, "currency": "GBP"}, {"minor": 150000, "currency": "GBP"}, 100, 0], "expect": {"tier": "Gold", "multiplierBasisPoints": 20000, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 2349, "currency": "GBP"}, "earnedPoints": 46, "newBalance": 146}},
{"name": "one penny under the Gold threshold is Silver", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 2349, "currency": "GBP"}, {"minor": 149999, "currency": "GBP"}, 0, 0], "expect": {"tier": "Silver", "multiplierBasisPoints": 12500, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 2349, "currency": "GBP"}, "earnedPoints": 28, "newBalance": 28}},
{"name": "double points doubles whole-pound points: 9.99 earns 18, not 19", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 999, "currency": "GBP"}, {"minor": 200000, "currency": "GBP"}, 0, 0], "expect": {"tier": "Gold", "multiplierBasisPoints": 20000, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 999, "currency": "GBP"}, "earnedPoints": 18, "newBalance": 18}},
{"name": "redeemed points are not earned on", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 2349, "currency": "GBP"}, {"minor": 10000, "currency": "GBP"}, 450, 300], "expect": {"tier": "Bronze", "multiplierBasisPoints": 10000, "redeemedPoints": 300, "discount": {"minor": 300, "currency": "GBP"}, "amountPayable": {"minor": 2049, "currency": "GBP"}, "earnedPoints": 20, "newBalance": 170}},
{"name": "points can pay for the whole purchase, earning nothing", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 300, "currency": "GBP"}, {"minor": 10000, "currency": "GBP"}, 300, 300], "expect": {"tier": "Bronze", "multiplierBasisPoints": 10000, "redeemedPoints": 300, "discount": {"minor": 300, "currency": "GBP"}, "amountPayable": {"minor": 0, "currency": "GBP"}, "earnedPoints": 0, "newBalance": 0}},
{"name": "no tiers at all is 1x and no tier name", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": []}, {"minor": 2349, "currency": "GBP"}, {"minor": 10000, "currency": "GBP"}, 5, 0], "expect": {"tier": null, "multiplierBasisPoints": 10000, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 2349, "currency": "GBP"}, "earnedPoints": 23, "newBalance": 28}},
{"name": "below every threshold is 1x and no tier name", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 2349, "currency": "GBP"}, {"minor": 10000, "currency": "GBP"}, 0, 0], "expect": {"tier": null, "multiplierBasisPoints": 10000, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 2349, "currency": "GBP"}, "earnedPoints": 23, "newBalance": 23}},
{"name": "half-up earning rounds 2.50 to 3 points", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "half-up", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 250, "currency": "GBP"}, {"minor": 0, "currency": "GBP"}, 0, 0], "expect": {"tier": "Bronze", "multiplierBasisPoints": 10000, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 250, "currency": "GBP"}, "earnedPoints": 3, "newBalance": 3}},
{"name": "4 points per pound, redeemable one at a time at 1p each", "args": [{"earnPoints": 4, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 1, "blockValue": {"minor": 1, "currency": "GBP"}, "tiers": []}, {"minor": 1237, "currency": "GBP"}, {"minor": 0, "currency": "GBP"}, 57, 57], "expect": {"tier": null, "multiplierBasisPoints": 10000, "redeemedPoints": 57, "discount": {"minor": 57, "currency": "GBP"}, "amountPayable": {"minor": 1180, "currency": "GBP"}, "earnedPoints": 47, "newBalance": 47}},
{"name": "points worth half a penny: 500 points for 2.50", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 500, "blockValue": {"minor": 250, "currency": "GBP"}, "tiers": []}, {"minor": 1000, "currency": "GBP"}, {"minor": 0, "currency": "GBP"}, 1200, 1000], "expect": {"tier": null, "multiplierBasisPoints": 10000, "redeemedPoints": 1000, "discount": {"minor": 500, "currency": "GBP"}, "amountPayable": {"minor": 500, "currency": "GBP"}, "earnedPoints": 5, "newBalance": 205}},
{"name": "a zero spend earns nothing", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 0, "currency": "GBP"}, {"minor": 10000, "currency": "GBP"}, 10, 0], "expect": {"tier": "Bronze", "multiplierBasisPoints": 10000, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 0, "currency": "GBP"}, "earnedPoints": 0, "newBalance": 10}},
{"name": "tiers listed out of order still pick the highest reached", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}, {"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}]}, {"minor": 1000, "currency": "GBP"}, {"minor": 60000, "currency": "GBP"}, 0, 0], "expect": {"tier": "Silver", "multiplierBasisPoints": 12500, "redeemedPoints": 0, "discount": {"minor": 0, "currency": "GBP"}, "amountPayable": {"minor": 1000, "currency": "GBP"}, "earnedPoints": 12, "newBalance": 12}},
{"name": "redeeming more value than the spend is an error", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 100, "currency": "GBP"}, {"minor": 0, "currency": "GBP"}, 150, 150], "expectError": "redeeming 150 points is worth 150, more than the spend of 100"},
{"name": "a redemption that is not whole blocks is an error", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 2000, "currency": "GBP"}, {"minor": 0, "currency": "GBP"}, 450, 100], "expectError": "points are redeemed in blocks of 150"},
{"name": "redeeming more points than the balance is an error", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 2000, "currency": "GBP"}, {"minor": 0, "currency": "GBP"}, 450, 600], "expectError": "cannot redeem 600 points from a balance of 450"},
{"name": "a spend in another currency is an error", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": 2000, "currency": "EUR"}, {"minor": 0, "currency": "EUR"}, 0, 0], "expectError": "currency mismatch"},
{"name": "a negative spend is an error", "args": [{"earnPoints": 1, "earnPer": {"minor": 100, "currency": "GBP"}, "earnRounding": "down", "redeemBlock": 150, "blockValue": {"minor": 150, "currency": "GBP"}, "tiers": [{"name": "Bronze", "threshold": {"minor": 0, "currency": "GBP"}, "multiplierBasisPoints": 10000}, {"name": "Silver", "threshold": {"minor": 50000, "currency": "GBP"}, "multiplierBasisPoints": 12500}, {"name": "Gold", "threshold": {"minor": 150000, "currency": "GBP"}, "multiplierBasisPoints": 20000}]}, {"minor": -100, "currency": "GBP"}, {"minor": 0, "currency": "GBP"}, 0, 0], "expectError": "spend must not be negative"}
]