From abb951746952137fbe09e9872d7bd0de9d288d78 Mon Sep 17 00:00:00 2001 From: Ben Webb Date: Sun, 24 Sep 2023 15:15:57 +0000 Subject: [PATCH] test defns: Budget alignment: check transactions inside sectors https://github.com/pwyf/2024-Index-indicator-definitions/issues/14 --- .../finance/13_budget_alignment.feature | 6 +- test_definitions/step_definitions.py | 21 +++++++ tests/finance/test_budget_alignment.py | 63 +++++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/test_definitions/finance/13_budget_alignment.feature b/test_definitions/finance/13_budget_alignment.feature index 763b71c..5fe8124 100644 --- a/test_definitions/finance/13_budget_alignment.feature +++ b/test_definitions/finance/13_budget_alignment.feature @@ -15,6 +15,6 @@ Feature: Budget Alignment And `activity-status/@code` is one of 2, 3 or 4 And `default-aid-type/@code` is not any of A01, A02 or G01 And `transaction/aid-type/@code` is not any of A01 or A02 - Then `sector/@code` should be present - And at least one `sector[not(@vocabulary) or @vocabulary="1"]/@code | transaction/sector[@vocabulary="1" or not(@vocabulary)]/@code` should be on the Sector codelist - And `sector/@code` is not any of 43010, 43050, 43081, 43082, 52010, 99810, 15110, 15111, 15112, 15114, 15130, 16010, 16061, 21010, 21020, 22010, 23110, 43030 or 43040 + Then `sector/@code` should be present, or `sector/@code` should be present for every `transaction` + And at least one `sector[not(@vocabulary) or @vocabulary="1"]/@code`, or at least one `sector[not(@vocabulary) or @vocabulary="1"]/@code` for every `transaction`, should be on the Sector codelist + And `sector[not(@vocabulary) or @vocabulary="1"]/@code | transaction/sector[not(@vocabulary) or @vocabulary="1"]/@code` is not any of 43010, 43050, 43081, 43082, 52010, 99810, 15110, 15111, 15112, 15114, 15130, 16010, 16061, 21010, 21020, 22010, 23110, 43030 or 43040 diff --git a/test_definitions/step_definitions.py b/test_definitions/step_definitions.py index 9b75503..5f4fd6e 100644 --- a/test_definitions/step_definitions.py +++ b/test_definitions/step_definitions.py @@ -64,6 +64,16 @@ def then_is_present_and_nonzero(xml, xpath_expression, **kwargs): raise StepException(msg) +@then(r'`([^`]+)` should be present, or `([^`]+)` should be present for every `([^`]+)`') +def then_is_present_or_for_every(xml, xpath_expression, for_every_xpath_expression, for_every_elements, **kwargs): + try: + then_is_present(xml, xpath_expression, **kwargs) + except StepException: + for element in xml.xpath(for_every_elements): + then_is_present(element, for_every_xpath_expression, **kwargs) + return xml + + @then(r'every `([^`]+)` should be on the ([^ ]+) codelist') def then_every_on_codelist(xml, xpath_expression, codelist, **kwargs): vals = xml.xpath(xpath_expression) @@ -116,6 +126,17 @@ def then_at_least_one_on_codelist(xml, xpath_expression, codelist, **kwargs): raise StepException(msg) +@then(r'at least one `([^`]+)`, or at least one `([^`]+)` for every `([^`]+)`, should be on the ([^ ]+) codelist') +def then_at_least_one_on_codelist_or_for_every(xml, xpath_expression, for_every_xpath_expression, for_every_elements, codelist, **kwargs): + try: + then_at_least_one_on_codelist(xml, xpath_expression, codelist, **kwargs) + except StepException: + for element in xml.xpath(for_every_elements): + then_at_least_one_on_codelist(element, for_every_xpath_expression, codelist, **kwargs) + + return xml + + @given(r'the activity is current') def given_activity_is_current(xml, **kwargs): try: diff --git a/tests/finance/test_budget_alignment.py b/tests/finance/test_budget_alignment.py index a740ec5..a0dd089 100644 --- a/tests/finance/test_budget_alignment.py +++ b/tests/finance/test_budget_alignment.py @@ -122,6 +122,69 @@ def test_sector_code(self): assert result is True + def test_sector_code_in_transaction(self): + xml = ''' + + + + + + + + + + + + + + ''' + + activity = etree.fromstring(xml) + result = self.test(activity, codelists=self.codelists) + + assert result is True + + def test_sector_code_not_in_every_transaction(self): + xml = ''' + + + + + + + + + + + + ''' + + activity = etree.fromstring(xml) + result = self.test(activity, codelists=self.codelists) + + assert result is False + + def test_sector_code_not_on_list_in_every_transaction(self): + xml = ''' + + + + + + + + + + + + + ''' + + activity = etree.fromstring(xml) + result = self.test(activity, codelists=self.codelists) + + assert result is False + def test_bad_sector_code(self): xml = '''