[
{
"name": "adding a driver half way: 120.00 more a year for 183 of 365 days is 60.16, plus a 25.00 fee",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-07-02",
{
"minor": 2500,
"currency": "GBP"
},
"half-up"
],
"expect": {
"totalDays": 365,
"remainingDays": 183,
"premiumChange": {
"minor": 6016,
"currency": "GBP"
},
"adminFee": {
"minor": 2500,
"currency": "GBP"
},
"amountDue": {
"minor": 8516,
"currency": "GBP"
},
"kind": "additional"
}
},
{
"name": "one rounding of the difference, not two: pro-rating 500.00 and 620.00 separately would give 60.17",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-07-02",
{
"minor": 0,
"currency": "GBP"
},
"half-up"
],
"expect": {
"totalDays": 365,
"remainingDays": 183,
"premiumChange": {
"minor": 6016,
"currency": "GBP"
},
"adminFee": {
"minor": 0,
"currency": "GBP"
},
"amountDue": {
"minor": 6016,
"currency": "GBP"
},
"kind": "additional"
}
},
{
"name": "removing the driver returns 60.16, less the 25.00 fee",
"args": [
{
"minor": 62000,
"currency": "GBP"
},
{
"minor": 50000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-07-02",
{
"minor": 2500,
"currency": "GBP"
},
"half-up"
],
"expect": {
"totalDays": 365,
"remainingDays": 183,
"premiumChange": {
"minor": -6016,
"currency": "GBP"
},
"adminFee": {
"minor": 2500,
"currency": "GBP"
},
"amountDue": {
"minor": -3516,
"currency": "GBP"
},
"kind": "return"
}
},
{
"name": "rounding up charges the part penny",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-07-02",
{
"minor": 0,
"currency": "GBP"
},
"up"
],
"expect": {
"totalDays": 365,
"remainingDays": 183,
"premiumChange": {
"minor": 6017,
"currency": "GBP"
},
"adminFee": {
"minor": 0,
"currency": "GBP"
},
"amountDue": {
"minor": 6017,
"currency": "GBP"
},
"kind": "additional"
}
},
{
"name": "a change from inception is the whole difference",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-01-01",
{
"minor": 0,
"currency": "GBP"
},
"half-up"
],
"expect": {
"totalDays": 365,
"remainingDays": 365,
"premiumChange": {
"minor": 12000,
"currency": "GBP"
},
"adminFee": {
"minor": 0,
"currency": "GBP"
},
"amountDue": {
"minor": 12000,
"currency": "GBP"
},
"kind": "additional"
}
},
{
"name": "a change on the expiry date costs nothing but the fee",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2027-01-01",
{
"minor": 2500,
"currency": "GBP"
},
"half-up"
],
"expect": {
"totalDays": 365,
"remainingDays": 0,
"premiumChange": {
"minor": 0,
"currency": "GBP"
},
"adminFee": {
"minor": 2500,
"currency": "GBP"
},
"amountDue": {
"minor": 2500,
"currency": "GBP"
},
"kind": "none"
}
},
{
"name": "a change with no premium effect still carries its fee",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 50000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-03-15",
{
"minor": 1500,
"currency": "GBP"
},
"half-up"
],
"expect": {
"totalDays": 365,
"remainingDays": 292,
"premiumChange": {
"minor": 0,
"currency": "GBP"
},
"adminFee": {
"minor": 1500,
"currency": "GBP"
},
"amountDue": {
"minor": 1500,
"currency": "GBP"
},
"kind": "none"
}
},
{
"name": "a leap-year term has 366 days: 366.00 more for the last 31 is 31.00",
"args": [
{
"minor": 0,
"currency": "GBP"
},
{
"minor": 36600,
"currency": "GBP"
},
"2028-01-01",
"2029-01-01",
"2028-12-01",
{
"minor": 0,
"currency": "GBP"
},
"half-up"
],
"expect": {
"totalDays": 366,
"remainingDays": 31,
"premiumChange": {
"minor": 3100,
"currency": "GBP"
},
"adminFee": {
"minor": 0,
"currency": "GBP"
},
"amountDue": {
"minor": 3100,
"currency": "GBP"
},
"kind": "additional"
}
},
{
"name": "exactly half a penny rounds up half-up",
"args": [
{
"minor": 10000,
"currency": "GBP"
},
{
"minor": 10001,
"currency": "GBP"
},
"2026-01-01",
"2026-01-05",
"2026-01-03",
{
"minor": 0,
"currency": "GBP"
},
"half-up"
],
"expect": {
"totalDays": 4,
"remainingDays": 2,
"premiumChange": {
"minor": 1,
"currency": "GBP"
},
"adminFee": {
"minor": 0,
"currency": "GBP"
},
"amountDue": {
"minor": 1,
"currency": "GBP"
},
"kind": "additional"
}
},
{
"name": "exactly half a penny rounds to even: nothing to charge",
"args": [
{
"minor": 10000,
"currency": "GBP"
},
{
"minor": 10001,
"currency": "GBP"
},
"2026-01-01",
"2026-01-05",
"2026-01-03",
{
"minor": 0,
"currency": "GBP"
},
"half-even"
],
"expect": {
"totalDays": 4,
"remainingDays": 2,
"premiumChange": {
"minor": 0,
"currency": "GBP"
},
"adminFee": {
"minor": 0,
"currency": "GBP"
},
"amountDue": {
"minor": 0,
"currency": "GBP"
},
"kind": "none"
}
},
{
"name": "a return premium smaller than the fee still leaves something to pay",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 49000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-07-02",
{
"minor": 2500,
"currency": "GBP"
},
"half-up"
],
"expect": {
"totalDays": 365,
"remainingDays": 183,
"premiumChange": {
"minor": -501,
"currency": "GBP"
},
"adminFee": {
"minor": 2500,
"currency": "GBP"
},
"amountDue": {
"minor": 1999,
"currency": "GBP"
},
"kind": "return"
}
},
{
"name": "a change before inception is refused",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2025-12-31",
{
"minor": 0,
"currency": "GBP"
},
"half-up"
],
"expectError": "changeDate must be from inceptionDate to expiryDate"
},
{
"name": "a change after expiry is refused",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2027-01-02",
{
"minor": 0,
"currency": "GBP"
},
"half-up"
],
"expectError": "changeDate must be from inceptionDate to expiryDate"
},
{
"name": "expiry must be after inception",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2027-01-01",
"2026-01-01",
"2026-01-01",
{
"minor": 0,
"currency": "GBP"
},
"half-up"
],
"expectError": "expiryDate must be after inceptionDate"
},
{
"name": "a negative fee is refused",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-07-02",
{
"minor": -1,
"currency": "GBP"
},
"half-up"
],
"expectError": "adminFee must not be negative"
},
{
"name": "a negative premium is refused",
"args": [
{
"minor": -50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-07-02",
{
"minor": 0,
"currency": "GBP"
},
"half-up"
],
"expectError": "premiums must not be negative"
},
{
"name": "premiums in two currencies are refused",
"args": [
{
"minor": 50000,
"currency": "GBP"
},
{
"minor": 62000,
"currency": "EUR"
},
"2026-01-01",
"2027-01-01",
"2026-07-02",
{
"minor": 0,
"currency": "GBP"
},
"half-up"
],
"expectError": "currency mismatch"
}
]