[ { "name": "1,000 car miles in 2025-26 paid at 45p: all approved, nothing taxable", "args": [ "car-van", 0, 1000, 0, { "minor": 45000, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expect": { "approved": { "minor": 45000, "currency": "GBP" }, "paid": { "minor": 45000, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 1000, "milesAtSecondRate": 0, "firstRatePence": 45, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "a claim that crosses 10,000 miles splits: 500 at 45p and 500 at 25p, so a flat 45p leaves 100.00 taxable", "args": [ "car-van", 9500, 1000, 0, { "minor": 45000, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expect": { "approved": { "minor": 35000, "currency": "GBP" }, "paid": { "minor": 45000, "currency": "GBP" }, "taxableExcess": { "minor": 10000, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 500, "milesAtSecondRate": 500, "firstRatePence": 45, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "every mile past 10,000 is at 25p; nothing paid gives relief on all of it", "args": [ "car-van", 12000, 200, 0, { "minor": 0, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-12-01" ], "expect": { "approved": { "minor": 5000, "currency": "GBP" }, "paid": { "minor": 0, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 5000, "currency": "GBP" }, "milesAtFirstRate": 0, "milesAtSecondRate": 200, "firstRatePence": 45, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "a claim ending exactly on the 10,000th mile is all at the first rate", "args": [ "car-van", 9000, 1000, 0, { "minor": 40000, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expect": { "approved": { "minor": 45000, "currency": "GBP" }, "paid": { "minor": 40000, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 5000, "currency": "GBP" }, "milesAtFirstRate": 1000, "milesAtSecondRate": 0, "firstRatePence": 45, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "55p from 6 April 2026: an employer still paying 45p leaves 10p a mile of relief", "args": [ "car-van", 0, 100, 0, { "minor": 4500, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2026-04-06" ], "expect": { "approved": { "minor": 5500, "currency": "GBP" }, "paid": { "minor": 4500, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 1000, "currency": "GBP" }, "milesAtFirstRate": 100, "milesAtSecondRate": 0, "firstRatePence": 55, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "5 April 2026 is still the 2025-26 tax year at 45p", "args": [ "car-van", 0, 100, 0, { "minor": 4500, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2026-04-05" ], "expect": { "approved": { "minor": 4500, "currency": "GBP" }, "paid": { "minor": 4500, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 100, "milesAtSecondRate": 0, "firstRatePence": 45, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "40p in the last day of 2010-11", "args": [ "car-van", 0, 100, 0, { "minor": 4000, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2011-04-05" ], "expect": { "approved": { "minor": 4000, "currency": "GBP" }, "paid": { "minor": 4000, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 100, "milesAtSecondRate": 0, "firstRatePence": 40, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "45p from 6 April 2011", "args": [ "car-van", 0, 100, 0, { "minor": 4000, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2011-04-06" ], "expect": { "approved": { "minor": 4500, "currency": "GBP" }, "paid": { "minor": 4000, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 500, "currency": "GBP" }, "milesAtFirstRate": 100, "milesAtSecondRate": 0, "firstRatePence": 45, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "the first day of the scheme, 6 April 2002, is 40p", "args": [ "car-van", 0, 10, 0, { "minor": 400, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2002-04-06" ], "expect": { "approved": { "minor": 400, "currency": "GBP" }, "paid": { "minor": 400, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 10, "milesAtSecondRate": 0, "firstRatePence": 40, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "a motorcycle is 24p a mile with no threshold", "args": [ "motorcycle", 20000, 100, 0, { "minor": 2400, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expect": { "approved": { "minor": 2400, "currency": "GBP" }, "paid": { "minor": 2400, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 100, "milesAtSecondRate": 0, "firstRatePence": 24, "secondRatePence": 24, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "a bicycle at 20p, paid 30p a mile: 10p a mile is taxable", "args": [ "bicycle", 0, 50, 0, { "minor": 1500, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expect": { "approved": { "minor": 1000, "currency": "GBP" }, "paid": { "minor": 1500, "currency": "GBP" }, "taxableExcess": { "minor": 500, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 50, "milesAtSecondRate": 0, "firstRatePence": 20, "secondRatePence": 20, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "two passengers for 75 miles are 150 passenger miles at 5p; 1.00 paid leaves 2.50 taxable", "args": [ "car-van", 0, 75, 150, { "minor": 3375, "currency": "GBP" }, { "minor": 1000, "currency": "GBP" }, "2025-06-01" ], "expect": { "approved": { "minor": 3375, "currency": "GBP" }, "paid": { "minor": 3375, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 75, "milesAtSecondRate": 0, "firstRatePence": 45, "secondRatePence": 25, "passengerApproved": { "minor": 750, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 250, "currency": "GBP" } } }, { "name": "passenger payments below 5p give no relief", "args": [ "car-van", 0, 75, 150, { "minor": 3375, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expect": { "approved": { "minor": 3375, "currency": "GBP" }, "paid": { "minor": 3375, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 75, "milesAtSecondRate": 0, "firstRatePence": 45, "secondRatePence": 25, "passengerApproved": { "minor": 750, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "no miles is nothing approved", "args": [ "car-van", 0, 0, 0, { "minor": 0, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expect": { "approved": { "minor": 0, "currency": "GBP" }, "paid": { "minor": 0, "currency": "GBP" }, "taxableExcess": { "minor": 0, "currency": "GBP" }, "relief": { "minor": 0, "currency": "GBP" }, "milesAtFirstRate": 0, "milesAtSecondRate": 0, "firstRatePence": 45, "secondRatePence": 25, "passengerApproved": { "minor": 0, "currency": "GBP" }, "passengerTaxableExcess": { "minor": 0, "currency": "GBP" } } }, { "name": "passenger payments on a motorcycle are refused", "args": [ "motorcycle", 0, 10, 10, { "minor": 240, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expectError": "passenger payments apply only to cars and vans" }, { "name": "no approved mileage rate before 6 April 2002", "args": [ "car-van", 0, 10, 0, { "minor": 0, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2002-04-05" ], "expectError": "no approved mileage rate for car-van on 2002-04-05" }, { "name": "negative miles are refused", "args": [ "car-van", 0, -5, 0, { "minor": 0, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expectError": "miles must be a whole number of miles, not negative" }, { "name": "fractional miles are refused", "args": [ "car-van", 0, 10.5, 0, { "minor": 0, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expectError": "miles must be a whole number of miles, not negative" }, { "name": "a payment in another currency is refused", "args": [ "car-van", 0, 10, 0, { "minor": 450, "currency": "EUR" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expectError": "paid must be in GBP" }, { "name": "an unknown vehicle is refused", "args": [ "lorry", 0, 10, 0, { "minor": 0, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "2025-06-01" ], "expectError": "unknown vehicle \"lorry\"" }, { "name": "a malformed date is refused", "args": [ "car-van", 0, 10, 0, { "minor": 0, "currency": "GBP" }, { "minor": 0, "currency": "GBP" }, "6/4/2025" ], "expectError": "onDate must be an ISO date" }, {"name": "a onDate with a trailing newline is refused", "args": ["car-van", 0, 10, 0, {"minor": 0, "currency": "GBP"}, {"minor": 0, "currency": "GBP"}, "2026-09-16\n"], "expectError": "onDate must be an ISO date (YYYY-MM-DD), received \"2026-09-16\n\""}, {"name": "a onDate in Arabic-Indic digits is refused", "args": ["car-van", 0, 10, 0, {"minor": 0, "currency": "GBP"}, {"minor": 0, "currency": "GBP"}, "٢٠٢٦-٠٩-١٦"], "expectError": "onDate must be an ISO date (YYYY-MM-DD), received \"٢٠٢٦-٠٩-١٦\""} ]