[
{
"name": "pro rata after 90 of 365 days: 600.00 keeps 147.95 and returns 452.05",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"pro-rata",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 90,
"totalDays": 365,
"retained": {
"minor": 14795,
"currency": "GBP"
},
"returnPremium": {
"minor": 45205,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "short period on the last day of the 3-month band keeps 40%",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 90,
"totalDays": 365,
"retained": {
"minor": 24000,
"currency": "GBP"
},
"returnPremium": {
"minor": 36000,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "one day into the 4th month moves to the 50% band",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-02",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 91,
"totalDays": 365,
"retained": {
"minor": 30000,
"currency": "GBP"
},
"returnPremium": {
"minor": 30000,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "four days in: the one-week band keeps 10%",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-01-05",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 4,
"totalDays": 365,
"retained": {
"minor": 6000,
"currency": "GBP"
},
"returnPremium": {
"minor": 54000,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "exactly 8 months keeps 80%",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-09-01",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 243,
"totalDays": 365,
"retained": {
"minor": 48000,
"currency": "GBP"
},
"returnPremium": {
"minor": 12000,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "longer than every band keeps the whole premium",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-09-02",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 244,
"totalDays": 365,
"retained": {
"minor": 60000,
"currency": "GBP"
},
"returnPremium": {
"minor": 0,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "pro rata cancelled on the inception date returns everything",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-01-01",
"pro-rata",
[],
null
],
"expect": {
"daysInForce": 0,
"totalDays": 365,
"retained": {
"minor": 0,
"currency": "GBP"
},
"returnPremium": {
"minor": 60000,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "pro rata cancelled on the expiry date returns nothing",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2027-01-01",
"pro-rata",
[],
null
],
"expect": {
"daysInForce": 365,
"totalDays": 365,
"retained": {
"minor": 60000,
"currency": "GBP"
},
"returnPremium": {
"minor": 0,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "a minimum retained premium of 75.00 beats 23.01 pro rata",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-01-15",
"pro-rata",
[],
{
"minor": 7500,
"currency": "GBP"
}
],
"expect": {
"daysInForce": 14,
"totalDays": 365,
"retained": {
"minor": 7500,
"currency": "GBP"
},
"returnPremium": {
"minor": 52500,
"currency": "GBP"
},
"minimumApplied": true
}
},
{
"name": "the minimum is capped at the premium: nothing more than was paid is kept",
"args": [
{
"minor": 5000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-01-11",
"pro-rata",
[],
{
"minor": 7500,
"currency": "GBP"
}
],
"expect": {
"daysInForce": 10,
"totalDays": 365,
"retained": {
"minor": 5000,
"currency": "GBP"
},
"returnPremium": {
"minor": 0,
"currency": "GBP"
},
"minimumApplied": true
}
},
{
"name": "a minimum below the scale's figure changes nothing",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
{
"minor": 7500,
"currency": "GBP"
}
],
"expect": {
"daysInForce": 90,
"totalDays": 365,
"retained": {
"minor": 24000,
"currency": "GBP"
},
"returnPremium": {
"minor": 36000,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "20% of 333.33 is 66.666, kept as 66.67",
"args": [
{
"minor": 33333,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-01-20",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 19,
"totalDays": 365,
"retained": {
"minor": 6667,
"currency": "GBP"
},
"returnPremium": {
"minor": 26666,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "a month is a calendar month: 30 days from 31 January passes 28 February, so the 2-month band",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-31",
"2027-01-31",
"2026-03-02",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 30,
"totalDays": 365,
"retained": {
"minor": 18000,
"currency": "GBP"
},
"returnPremium": {
"minor": 42000,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "28 February is exactly one month from 31 January",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-31",
"2027-01-31",
"2026-02-28",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 28,
"totalDays": 365,
"retained": {
"minor": 12000,
"currency": "GBP"
},
"returnPremium": {
"minor": 48000,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "a leap-year policy has 366 days: 274 of them keep 274.00 of 366.00",
"args": [
{
"minor": 36600,
"currency": "GBP"
},
"2027-06-01",
"2028-06-01",
"2028-03-01",
"pro-rata",
[],
null
],
"expect": {
"daysInForce": 274,
"totalDays": 366,
"retained": {
"minor": 27400,
"currency": "GBP"
},
"returnPremium": {
"minor": 9200,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "a zero premium returns zero",
"args": [
{
"minor": 0,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"short-period",
[
{
"upTo": 7,
"unit": "days",
"retainedBasisPoints": 1000
},
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 2000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 3,
"unit": "months",
"retainedBasisPoints": 4000
},
{
"upTo": 4,
"unit": "months",
"retainedBasisPoints": 5000
},
{
"upTo": 6,
"unit": "months",
"retainedBasisPoints": 7000
},
{
"upTo": 8,
"unit": "months",
"retainedBasisPoints": 8000
}
],
null
],
"expect": {
"daysInForce": 90,
"totalDays": 365,
"retained": {
"minor": 0,
"currency": "GBP"
},
"returnPremium": {
"minor": 0,
"currency": "GBP"
},
"minimumApplied": false
}
},
{
"name": "cancelling after expiry is refused",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2027-01-02",
"pro-rata",
[],
null
],
"expectError": "cancellationDate must be from inceptionDate to expiryDate"
},
{
"name": "cancelling before inception is refused",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2025-12-31",
"pro-rata",
[],
null
],
"expectError": "cancellationDate must be from inceptionDate to expiryDate"
},
{
"name": "expiry must be after inception",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2026-01-01",
"2026-01-01",
"pro-rata",
[],
null
],
"expectError": "expiryDate must be after inceptionDate"
},
{
"name": "short period without a scale is refused",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"short-period",
[],
null
],
"expectError": "a short-period cancellation needs a scale"
},
{
"name": "a share above 100% is refused",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"short-period",
[
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 10001
}
],
null
],
"expectError": "retainedBasisPoints must be from 0 to 10000"
},
{
"name": "a scale that keeps less for longer is refused",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"short-period",
[
{
"upTo": 1,
"unit": "months",
"retainedBasisPoints": 3000
},
{
"upTo": 2,
"unit": "months",
"retainedBasisPoints": 2000
}
],
null
],
"expectError": "must not keep less for a longer period"
},
{
"name": "a fractional upTo is refused",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"short-period",
[
{
"upTo": 1.5,
"unit": "months",
"retainedBasisPoints": 3000
}
],
null
],
"expectError": "upTo must be a whole number"
},
{
"name": "a negative premium is refused",
"args": [
{
"minor": -100,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"pro-rata",
[],
null
],
"expectError": "premium must not be negative"
},
{
"name": "a minimum in another currency is refused",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"pro-rata",
[],
{
"minor": 7500,
"currency": "EUR"
}
],
"expectError": "currency mismatch"
},
{
"name": "an unknown basis is refused",
"args": [
{
"minor": 60000,
"currency": "GBP"
},
"2026-01-01",
"2027-01-01",
"2026-04-01",
"flat",
[],
null
],
"expectError": "unknown basis"
}
]