[
{
"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 \"٢٠٢٦-٠٩-١٦\""}
]