diff --git a/changelog.d/2116.fixed.md b/changelog.d/2116.fixed.md new file mode 100644 index 0000000000..87f51f8729 --- /dev/null +++ b/changelog.d/2116.fixed.md @@ -0,0 +1 @@ +- Corrected the JSA, ESA and DLA program registry variable mappings, narrowed Benefit Cap's parameter prefix to its own subtree, removed Maternity Allowance's unrelated DWP parameter prefix, and added validation of all declared registry variables and parameter prefixes. diff --git a/policyengine_uk/programs.yaml b/policyengine_uk/programs.yaml index 2fa867458d..11657e674c 100644 --- a/policyengine_uk/programs.yaml +++ b/policyengine_uk/programs.yaml @@ -249,7 +249,7 @@ programs: agency: DWP status: complete coverage: UK - variable: JSA + variable: jsa parameter_prefix: gov.dwp.JSA verified_start_year: 2022 notes: Income-based and contribution-based @@ -261,7 +261,7 @@ programs: agency: DWP status: complete coverage: UK - variable: ESA + variable: esa parameter_prefix: gov.dwp.ESA verified_start_year: 2022 notes: Income-related and contribution-based @@ -296,7 +296,7 @@ programs: agency: DWP status: complete coverage: UK - variable: DLA + variable: dla parameter_prefix: gov.dwp.dla verified_start_year: 2022 @@ -319,7 +319,7 @@ programs: status: complete coverage: UK variable: benefit_cap_reduction - parameter_prefix: gov.dwp + parameter_prefix: gov.dwp.benefit_cap verified_start_year: 2022 notes: Universal Credit (uc_benefit_cap) and Housing Benefit (housing_benefit_benefit_cap) each apply their own cap; benefit_cap_reduction is the sum of their reductions @@ -377,7 +377,6 @@ programs: status: complete coverage: UK variable: maternity_allowance - parameter_prefix: gov.dwp verified_start_year: 2022 # --- DfE programs --- diff --git a/policyengine_uk/tests/test_program_registry.py b/policyengine_uk/tests/test_program_registry.py new file mode 100644 index 0000000000..f4214066d8 --- /dev/null +++ b/policyengine_uk/tests/test_program_registry.py @@ -0,0 +1,56 @@ +"""Keep the public program registry linked to real model objects.""" + +import pytest +import yaml +from policyengine_core.parameters import ParameterNode + +from policyengine_uk import CountryTaxBenefitSystem + +PROGRAMS = yaml.safe_load(CountryTaxBenefitSystem.modelled_policies.read_text())[ + "programs" +] + + +@pytest.fixture(scope="module") +def tax_benefit_system(): + return CountryTaxBenefitSystem() + + +@pytest.mark.parametrize( + "program", [p for p in PROGRAMS if "variable" in p], ids=lambda p: p["id"] +) +def test_program_variables_exist(program, tax_benefit_system): + assert program["variable"] in tax_benefit_system.variables, ( + f"{program['id']} references unknown variable {program['variable']!r}" + ) + + +@pytest.mark.parametrize( + "program", [p for p in PROGRAMS if "parameter_prefix" in p], ids=lambda p: p["id"] +) +def test_program_parameter_prefixes_exist(program, tax_benefit_system): + prefix = program["parameter_prefix"] + assert isinstance(tax_benefit_system.parameters.get_child(prefix), ParameterNode), ( + f"{program['id']} parameter prefix {prefix!r} does not name a parameter node" + ) + + +def test_maternity_allowance_does_not_advertise_unrelated_parameters(): + """Reported Maternity Allowance has no policy parameter subtree (#2116).""" + program = next(p for p in PROGRAMS if p["id"] == "maternity_allowance") + assert "parameter_prefix" not in program + + +def test_benefit_cap_does_not_advertise_unrelated_parameters(tax_benefit_system): + """The advertised Benefit Cap subtree excludes other DWP programs (#2116).""" + program = next(p for p in PROGRAMS if p["id"] == "benefit_cap") + advertised = tax_benefit_system.parameters.get_child(program["parameter_prefix"]) + benefit_cap = tax_benefit_system.parameters.gov.dwp.benefit_cap + + assert "universal_credit" not in advertised.children + assert "JSA" not in advertised.children + assert advertised.get_child("single.in_london") is benefit_cap.single.in_london + assert ( + advertised.get_child("non_single.outside_london") + is benefit_cap.non_single.outside_london + )