[ { "name": "a first claim-free year earns 30%", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 0, 0, null ], "expect": { "years": 1, "discountBasisPoints": 3000, "protectionApplied": false } }, { "name": "four years claim-free becomes five: 65%", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 4, 0, null ], "expect": { "years": 5, "discountBasisPoints": 6500, "protectionApplied": false } }, { "name": "six years sits on the 5-year level until 9 years", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 5, 0, null ], "expect": { "years": 6, "discountBasisPoints": 6500, "protectionApplied": false } }, { "name": "reaching 9 years: the top of the scale", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 8, 0, null ], "expect": { "years": 9, "discountBasisPoints": 7000, "protectionApplied": false } }, { "name": "years keep counting past the top; the discount stays at the top", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 12, 0, null ], "expect": { "years": 13, "discountBasisPoints": 7000, "protectionApplied": false } }, { "name": "one claim at 5 years steps back to 3 years: 50%", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 5, 1, null ], "expect": { "years": 3, "discountBasisPoints": 5000, "protectionApplied": false } }, { "name": "two claims at 5 years step back to 1 year", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 5, 2, null ], "expect": { "years": 1, "discountBasisPoints": 3000, "protectionApplied": false } }, { "name": "three claims at 5 years lose it all", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 5, 3, null ], "expect": { "years": 0, "discountBasisPoints": 0, "protectionApplied": false } }, { "name": "more claims than the scale lists use its last step", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 5, 4, null ], "expect": { "years": 0, "discountBasisPoints": 0, "protectionApplied": false } }, { "name": "above the top level the top level's step-back applies: 12 years, one claim, 7 years at 65%", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 12, 1, null ], "expect": { "years": 7, "discountBasisPoints": 6500, "protectionApplied": false } }, { "name": "between levels the level below applies: 7 years, one claim, the 5-year step to 3", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 7, 1, null ], "expect": { "years": 3, "discountBasisPoints": 5000, "protectionApplied": false } }, { "name": "one claim at 1 year loses it", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 1, 1, null ], "expect": { "years": 0, "discountBasisPoints": 0, "protectionApplied": false } }, { "name": "a claim with no NCD stays at 0", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 0, 1, null ], "expect": { "years": 0, "discountBasisPoints": 0, "protectionApplied": false } }, { "name": "protected NCD, one claim of two allowed: years kept, none earned", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 9, 1, { "claimLimit": 2, "claimsInWindow": 1 } ], "expect": { "years": 9, "discountBasisPoints": 7000, "protectionApplied": true } }, { "name": "protected NCD, the second allowed claim in the window is still covered", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 9, 1, { "claimLimit": 2, "claimsInWindow": 2 } ], "expect": { "years": 9, "discountBasisPoints": 7000, "protectionApplied": true } }, { "name": "protected NCD exceeded: the third claim in the window steps back as usual", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 9, 1, { "claimLimit": 2, "claimsInWindow": 3 } ], "expect": { "years": 7, "discountBasisPoints": 6500, "protectionApplied": false } }, { "name": "protection with no claims earns a year as normal", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 9, 0, { "claimLimit": 2, "claimsInWindow": 0 } ], "expect": { "years": 10, "discountBasisPoints": 7000, "protectionApplied": false } }, { "name": "an empty scale is refused", "args": [ [], 3, 0, null ], "expectError": "the NCD scale must not be empty" }, { "name": "a scale must start at 0 years", "args": [ [ { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] } ], 3, 0, null ], "expectError": "the NCD scale must start at 0 years" }, { "name": "a scale out of order is refused", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] } ], 3, 0, null ], "expectError": "ascending order of years" }, { "name": "a step-back above the level is refused", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 3 ] } ], 2, 1, null ], "expectError": "must not rise above the level" }, { "name": "a discount above 100% is refused", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 10001, "stepBack": [ 0 ] } ], 1, 0, null ], "expectError": "discountBasisPoints must be from 0 to 10000" }, { "name": "negative claims are refused", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 3, -1, null ], "expectError": "claims must be a whole number of 0 or more" }, { "name": "fractional years are refused", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 2.5, 0, null ], "expectError": "currentYears must be a whole number of 0 or more" }, { "name": "a protection window without this year's claims is refused", "args": [ [ { "years": 0, "discountBasisPoints": 0, "stepBack": [] }, { "years": 1, "discountBasisPoints": 3000, "stepBack": [ 0 ] }, { "years": 2, "discountBasisPoints": 4000, "stepBack": [ 0 ] }, { "years": 3, "discountBasisPoints": 5000, "stepBack": [ 1, 0 ] }, { "years": 4, "discountBasisPoints": 6000, "stepBack": [ 2, 0 ] }, { "years": 5, "discountBasisPoints": 6500, "stepBack": [ 3, 1, 0 ] }, { "years": 9, "discountBasisPoints": 7000, "stepBack": [ 7, 4, 0 ] } ], 5, 2, { "claimLimit": 2, "claimsInWindow": 1 } ], "expectError": "claimsInWindow must include this year's claims" } ]