Skip to content

Commit

Permalink
Merge pull request #2152 from UKHSA-Internal/task/add-rest-of-uk-to-p…
Browse files Browse the repository at this point in the history
…ossible-geographies/CDD-1083

Task/add rest of uk to possible geographies/cdd 1083
  • Loading branch information
A-Ashiq authored Feb 7, 2025
2 parents 17245df + 70327a7 commit f365bae
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 26 deletions.
1 change: 1 addition & 0 deletions ingestion/data_transfer_models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ def validate_geography_code(self) -> Self:
validation.validate_geography_code(
geography_code=self.geography_code,
geography_type=self.geography_type,
geography=self.geography,
)
return self

Expand Down
49 changes: 42 additions & 7 deletions ingestion/data_transfer_models/validation/geography_code.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
from ingestion.utils import enums

NATION_GEOGRAPHY_CODE_PREFIX = "E92"
UNITED_KINGDOM_GEOGRAPHY_CODE = "K02000001"
NATION_GEOGRAPHY_CODES = {
"England": "E92000001",
"Scotland": "S92000003",
"Wales": "W92000004",
"Northern Ireland": "N92000002",
}

LOWER_TIER_LOCAL_AUTHORITY_GEOGRAPHY_CODE_PREFIXES = ("E06", "E07", "E08", "E09")
UPPER_TIER_LOCAL_AUTHORITY_GEOGRAPHY_CODE_PREFIXES = ("E06", "E07", "E08", "E09", "E10")
NHS_REGION_GEOGRAPHY_CODE_PREFIX = "E40"
Expand All @@ -9,13 +16,16 @@
UKHSA_SUPER_REGION_PREFIX = "X2500"


def validate_geography_code(*, geography_code: str, geography_type: str) -> str | None:
def validate_geography_code(
*, geography_code: str, geography_type: str, geography: str
) -> str | None:
"""Validates the `geography_code` value to check it conforms to the accepted format
Args:
geography_code: The associated geography code being validated
geography_type: The `geography_type` which was
included in the payload alongside the `geography_code`
geography: The name of the geography to be validated
Returns:
The input `geography_code` unchanged if
Expand All @@ -27,7 +37,10 @@ def validate_geography_code(*, geography_code: str, geography_type: str) -> str
"""
match geography_type:
case enums.GeographyType.NATION.value:
return _validate_nation_geography_code(geography_code=geography_code)
return _validate_nation_geography_code(
geography_code=geography_code,
geography=geography,
)
case enums.GeographyType.UPPER_TIER_LOCAL_AUTHORITY.value:
return _validate_upper_tier_local_authority_geography_code(
geography_code=geography_code
Expand Down Expand Up @@ -58,12 +71,24 @@ def validate_geography_code(*, geography_code: str, geography_type: str) -> str
return _validate_ukhsa_super_region_geography_code(
geography_code=geography_code
)
case enums.GeographyType.UNITED_KINGDOM.value:
return _validate_united_kingdom_geography_code(
geography_code=geography_code,
geography=geography,
)


def _validate_nation_geography_code(*, geography_code: str) -> str:
if geography_code.startswith(NATION_GEOGRAPHY_CODE_PREFIX):
return geography_code
raise ValueError
def _validate_nation_geography_code(*, geography_code: str, geography: str) -> str:
try:
extracted_geography_code: str = NATION_GEOGRAPHY_CODES[geography]
except KeyError as error:
error_message = f"Invalid `Nation` geography: {geography}"
raise ValueError(error_message) from error

if geography_code != extracted_geography_code:
raise ValueError

return geography_code


def _validate_lower_tier_local_authority_geography_code(*, geography_code: str) -> str:
Expand Down Expand Up @@ -168,3 +193,13 @@ def _validate_ukhsa_super_region_geography_code(*, geography_code: str) -> str:
raise ValueError

return geography_code


def _validate_united_kingdom_geography_code(*, geography: str, geography_code: str):
if geography_code != UNITED_KINGDOM_GEOGRAPHY_CODE:
raise ValueError

if geography != "United Kingdom":
raise ValueError

return geography_code
1 change: 1 addition & 0 deletions ingestion/utils/enums/geographies_enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


class GeographyType(Enum):
UNITED_KINGDOM = "United Kingdom"
NATION = "Nation"
LOWER_TIER_LOCAL_AUTHORITY = "Lower Tier Local Authority"
NHS_REGION = "NHS Region"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
from pydantic_core._pydantic_core import ValidationError

from ingestion.data_transfer_models.base import IncomingBaseDataModel
from ingestion.data_transfer_models.validation.geography_code import (
UNITED_KINGDOM_GEOGRAPHY_CODE,
)
from ingestion.utils import enums

VALID_NATION_CODE = "E92000001"
VALID_ENGLAND_NATION_CODE = "E92000001"
VALID_LOWER_TIER_LOCAL_AUTHORITY_CODE = "E06000059"
VALID_UPPER_TIER_LOCAL_AUTHORITY_CODE = "E10000024"
VALID_NHS_REGION_CODE = "E40000003"
Expand Down Expand Up @@ -56,7 +59,7 @@ def test_valid_geography_code_validates_successfully(
@pytest.mark.parametrize(
"geography_code",
(
VALID_NATION_CODE,
VALID_ENGLAND_NATION_CODE,
VALID_LOWER_TIER_LOCAL_AUTHORITY_CODE,
VALID_NHS_REGION_CODE,
VALID_UPPER_TIER_LOCAL_AUTHORITY_CODE,
Expand Down Expand Up @@ -168,7 +171,7 @@ def test_valid_geography_code_validates_successfully(
@pytest.mark.parametrize(
"geography_code",
(
VALID_NATION_CODE,
VALID_ENGLAND_NATION_CODE,
VALID_NHS_TRUST_CODE,
VALID_NHS_REGION_CODE,
VALID_UKHSA_REGION_CODE,
Expand Down Expand Up @@ -236,7 +239,7 @@ def test_valid_geography_code_validates_successfully(
@pytest.mark.parametrize(
"geography_code",
(
VALID_NATION_CODE,
VALID_ENGLAND_NATION_CODE,
VALID_NHS_TRUST_CODE,
VALID_NHS_REGION_CODE,
VALID_UKHSA_REGION_CODE,
Expand Down Expand Up @@ -302,7 +305,7 @@ def test_valid_geography_code_validates_successfully(
@pytest.mark.parametrize(
"geography_code",
(
VALID_NATION_CODE,
VALID_ENGLAND_NATION_CODE,
VALID_NHS_TRUST_CODE,
VALID_LOWER_TIER_LOCAL_AUTHORITY_CODE,
VALID_UPPER_TIER_LOCAL_AUTHORITY_CODE,
Expand Down Expand Up @@ -331,19 +334,32 @@ def test_invalid_geography_code_throws_error(


class TestIncomingBaseValidationForNationGeographyCode:
@pytest.mark.parametrize(
"geography, geography_code",
[
("England", "E92000001"),
("Scotland", "S92000003"),
("Wales", "W92000004"),
("Northern Ireland", "N92000002"),
],
)
def test_valid_geography_code_validates_successfully(
self, valid_payload_for_base_model: dict[str, str]
self,
geography: str,
geography_code: str,
valid_payload_for_base_model: dict[str, str],
):
"""
Given a payload containing a valid `geography_code` value
Given a payload containing a valid `geography_code` and `geography`
for a `geography_type` of "Nation"
When the `IncomingBaseDataModel` model is initialized
Then model is deemed valid
"""
# Given
payload = valid_payload_for_base_model
payload["geography_type"] = enums.GeographyType.NATION.value
payload["geography_code"] = "E92000001"
payload["geography"] = geography
payload["geography_code"] = geography_code

# When
incoming_base_validation = IncomingBaseDataModel(**payload)
Expand All @@ -354,6 +370,38 @@ def test_valid_geography_code_validates_successfully(
strict=True,
)

@pytest.mark.parametrize(
"geography, geography_code",
[
("England", "S92000003"), # Incorrect geography code
("scotland", "S92000003"), # Case sensitivity
("Welsh", "W92000004"), # Incorrectly referenced country
("Ireland", "N92000002"), # Incorrect geography code
("Fake Country", "E92000001"), # Invalid country
],
)
def test_invalid_geography_invalidates_as_expected(
self,
geography: str,
geography_code: str,
valid_payload_for_base_model: dict[str, str],
):
"""
Given a payload containing an invalid `geography_code` or `geography`
for a `geography_type` of "Nation"
When the `IncomingBaseDataModel` model is initialized
Then a `ValidationError` is raised
"""
# Given
payload = valid_payload_for_base_model
payload["geography_type"] = enums.GeographyType.NATION.value
payload["geography"] = geography
payload["geography_code"] = geography_code

# When / Then
with pytest.raises(ValidationError):
IncomingBaseDataModel(**payload)

@pytest.mark.parametrize(
"geography_code",
(
Expand Down Expand Up @@ -385,6 +433,93 @@ def test_invalid_geography_code_throws_error(
IncomingBaseDataModel(**payload)


class TestIncomingBaseValidationForUnitedKingdomGeographyCode:
def test_valid_geography_code_validates_successfully(
self,
valid_payload_for_base_model: dict[str, str],
):
"""
Given a payload containing
the only valid `geography_code` and `geography`
for a `geography_type` of "United Kingdom"
When the `IncomingBaseDataModel` model is initialized
Then model is deemed valid
"""
# Given
payload = valid_payload_for_base_model
payload["geography_type"] = enums.GeographyType.UNITED_KINGDOM.value
payload["geography"] = "United Kingdom"
payload["geography_code"] = UNITED_KINGDOM_GEOGRAPHY_CODE

# When
incoming_base_validation = IncomingBaseDataModel(**payload)

# Then
incoming_base_validation.model_validate(
incoming_base_validation,
strict=True,
)

@pytest.mark.parametrize(
"geography_code",
(
VALID_ENGLAND_NATION_CODE,
VALID_NHS_REGION_CODE,
VALID_NHS_TRUST_CODE,
VALID_LOWER_TIER_LOCAL_AUTHORITY_CODE,
VALID_UPPER_TIER_LOCAL_AUTHORITY_CODE,
VALID_UKHSA_REGION_CODE,
VALID_GOVERNMENT_OFFICE_REGION_CODE,
),
)
def test_invalid_geography_code_throws_error(
self, geography_code: str, valid_payload_for_base_model: dict[str, str]
):
"""
Given a payload containing a `geography_code`
which is not valid for
the "United Kingdom" `geography_type`
When the `IncomingBaseDataModel` model is initialized
Then a `ValidationError` is raised
"""
# Given
payload = valid_payload_for_base_model
payload["geography_type"] = enums.GeographyType.UNITED_KINGDOM.value
payload["geography_code"] = geography_code

# When / Then
with pytest.raises(ValidationError):
IncomingBaseDataModel(**payload)

@pytest.mark.parametrize(
"geography",
(
"united kingdom",
"UK",
"England",
"Great Britain",
),
)
def test_invalid_geography_name_throws_error(
self, geography: str, valid_payload_for_base_model: dict[str, str]
):
"""
Given a payload containing a `geography`
which is not valid for
the "United Kingdom" `geography_type`
When the `IncomingBaseDataModel` model is initialized
Then a `ValidationError` is raised
"""
# Given
payload = valid_payload_for_base_model
payload["geography_type"] = enums.GeographyType.UNITED_KINGDOM.value
payload["geography_code"] = UNITED_KINGDOM_GEOGRAPHY_CODE

# When / Then
with pytest.raises(ValidationError):
IncomingBaseDataModel(**payload)


class TestIncomingBaseValidationForGovernmentOfficeRegionGeographyCode:
def test_valid_geography_code_validates_successfully(
self, valid_payload_for_base_model: dict[str, str]
Expand Down Expand Up @@ -417,7 +552,7 @@ def test_valid_geography_code_validates_successfully(
VALID_LOWER_TIER_LOCAL_AUTHORITY_CODE,
VALID_UPPER_TIER_LOCAL_AUTHORITY_CODE,
VALID_UKHSA_REGION_CODE,
VALID_NATION_CODE,
VALID_ENGLAND_NATION_CODE,
),
)
def test_invalid_geography_code_throws_error(
Expand Down Expand Up @@ -481,7 +616,7 @@ def test_valid_geography_code_validates_successfully(
@pytest.mark.parametrize(
"geography_code",
(
VALID_NATION_CODE,
VALID_ENGLAND_NATION_CODE,
VALID_NHS_TRUST_CODE,
VALID_NHS_REGION_CODE,
VALID_LOWER_TIER_LOCAL_AUTHORITY_CODE,
Expand Down Expand Up @@ -545,7 +680,7 @@ def test_valid_geography_code_validates_successfully(
@pytest.mark.parametrize(
"geography_code",
(
VALID_NATION_CODE,
VALID_ENGLAND_NATION_CODE,
VALID_NHS_TRUST_CODE,
VALID_NHS_REGION_CODE,
VALID_UKHSA_REGION_CODE,
Expand Down Expand Up @@ -613,7 +748,7 @@ def test_valid_geography_code_validates_successfully(
@pytest.mark.parametrize(
"geography_code",
(
VALID_NATION_CODE,
VALID_ENGLAND_NATION_CODE,
VALID_LOWER_TIER_LOCAL_AUTHORITY_CODE,
VALID_NHS_REGION_CODE,
VALID_UPPER_TIER_LOCAL_AUTHORITY_CODE,
Expand Down Expand Up @@ -727,7 +862,7 @@ def test_valid_geography_code_validates_successfully(
@pytest.mark.parametrize(
"geography_code",
(
VALID_NATION_CODE,
VALID_ENGLAND_NATION_CODE,
VALID_LOWER_TIER_LOCAL_AUTHORITY_CODE,
VALID_NHS_REGION_CODE,
VALID_UPPER_TIER_LOCAL_AUTHORITY_CODE,
Expand Down
Loading

0 comments on commit f365bae

Please sign in to comment.