Skip to content

Commit 98fa5a7

Browse files
authored
Merge branch 'master' into VED-489-add-covid19
2 parents e89b03b + c93de64 commit 98fa5a7

37 files changed

+525
-232
lines changed

config/dev/permissions_config.json

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"FLU.CRUDS",
77
"MMR.CRUDS",
88
"RSV.CRUDS"
9-
]
9+
],
10+
"ods_codes": ["DPSFULL"]
1011
},
1112
{
1213
"supplier": "DPSREDUCED",
@@ -15,7 +16,8 @@
1516
"FLU.CRUD",
1617
"MMR.CRUD",
1718
"RSV.CRUD"
18-
]
19+
],
20+
"ods_codes": ["DPSREDUCED"]
1921
},
2022
{
2123
"supplier": "MAVIS",
@@ -25,26 +27,30 @@
2527
"MENACWY.CRUDS",
2628
"MMR.CRUDS",
2729
"FLU.CRUDS"
28-
]
30+
],
31+
"ods_codes": ["V0V8L"]
2932
},
3033
{
3134
"supplier": "SONAR",
3235
"permissions": [
3336
"FLU.CD"
34-
]
37+
],
38+
"ods_codes": ["8HK48"]
3539
},
3640
{
3741
"supplier": "EVA",
3842
"permissions": [
3943
"COVID19.CUD"
40-
]
44+
],
45+
"ods_codes": ["8HA94"]
4146
},
4247
{
4348
"supplier": "RAVS",
4449
"permissions": [
4550
"RSV.CRUDS",
4651
"MMR.CRUDS"
47-
]
52+
],
53+
"ods_codes": ["X8E5B"]
4854
},
4955
{
5056
"supplier": "AGEM-RAVS-Integration",
@@ -61,7 +67,8 @@
6167
"HPV.CRUDS",
6268
"3IN1.CRUDS",
6369
"MENACWY.CRUDS"
64-
]
70+
],
71+
"ods_codes": ["YGM41", "YGJ"]
6572
},
6673
{
6774
"supplier": "TPP",
@@ -71,7 +78,8 @@
7178
"HPV.CRUDS",
7279
"3IN1.CRUDS",
7380
"MENACWY.CRUDS"
74-
]
81+
],
82+
"ods_codes": ["YGA"]
7583
},
7684
{
7785
"supplier": "MEDICUS",
@@ -81,7 +89,8 @@
8189
"HPV.CRUDS",
8290
"3IN1.CRUDS",
8391
"MENACWY.CRUDS"
84-
]
92+
],
93+
"ods_codes": ["YGMYW"]
8594
},
8695
{
8796
"supplier": "Test_App",

config/preprod/permissions_config.json

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"FLU.CRUDS",
77
"MMR.CRUDS",
88
"RSV.CRUDS"
9-
]
9+
],
10+
"ods_codes": ["DPSFULL"]
1011
},
1112
{
1213
"supplier": "DPSREDUCED",
@@ -15,7 +16,8 @@
1516
"FLU.CRUDS",
1617
"MMR.CRUDS",
1718
"RSV.CRUDS"
18-
]
19+
],
20+
"ods_codes": ["DPSREDUCED"]
1921
},
2022
{
2123
"supplier": "MAVIS",
@@ -25,14 +27,16 @@
2527
"MENACWY.CRUDS",
2628
"MMR.CRUDS",
2729
"FLU.CRUDS"
28-
]
30+
],
31+
"ods_codes": ["V0V8L"]
2932
},
3033
{
3134
"supplier": "RAVS",
3235
"permissions": [
3336
"RSV.CRUDS",
3437
"MMR.CRUDS"
35-
]
38+
],
39+
"ods_codes": ["X8E5B"]
3640
},
3741
{
3842
"supplier": "AGEM-RAVS-Integration",
@@ -49,7 +53,8 @@
4953
"HPV.CRUDS",
5054
"3IN1.CRUDS",
5155
"MENACWY.CRUDS"
52-
]
56+
],
57+
"ods_codes": ["YGM41", "YGJ"]
5358
},
5459
{
5560
"supplier": "TPP",
@@ -59,7 +64,8 @@
5964
"HPV.CRUDS",
6065
"3IN1.CRUDS",
6166
"MENACWY.CRUDS"
62-
]
67+
],
68+
"ods_codes": ["YGA"]
6369
},
6470
{
6571
"supplier": "MEDICUS",
@@ -69,7 +75,8 @@
6975
"HPV.CRUDS",
7076
"3IN1.CRUDS",
7177
"MENACWY.CRUDS"
72-
]
78+
],
79+
"ods_codes": ["YGMYW"]
7380
},
7481
{
7582
"supplier": "Test_App",

config/prod/permissions_config.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@
33
"supplier": "DPSFULL",
44
"permissions": [
55
"RSV.CRUDS"
6-
]
6+
],
7+
"ods_codes": ["DPSFULL"]
78
},
89
{
910
"supplier": "DPSREDUCED",
1011
"permissions": [
1112
"RSV.CRUDS"
12-
]
13+
],
14+
"ods_codes": ["DPSREDUCED"]
1315
},
1416
{
1517
"supplier": "RAVS",
1618
"permissions": [
1719
"RSV.RS"
18-
]
20+
],
21+
"ods_codes": ["X8E5B"]
1922
}
2023
]

filenameprocessor/src/constants.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
SUPPLIER_PERMISSIONS_HASH_KEY = "supplier_permissions"
2020
VACCINE_TYPE_TO_DISEASES_HASH_KEY = "vacc_to_diseases"
21+
ODS_CODE_TO_SUPPLIER_SYSTEM_HASH_KEY = "ods_code_to_supplier"
2122

2223
ERROR_TYPE_TO_STATUS_CODE_MAP = {
2324
VaccineTypePermissionsError: 403,
@@ -52,27 +53,3 @@ class AuditTableKeys:
5253
class Constants:
5354
"""Constants for the filenameprocessor lambda"""
5455
VALID_VERSIONS = ["V5"]
55-
56-
# Mappings from ODS code to supplier name.
57-
# NOTE: Any ODS code not found in this dictionary's keys is invalid for this service
58-
ODS_TO_SUPPLIER_MAPPINGS = {
59-
"YGM41": "EMIS",
60-
"8J1100001": "PINNACLE",
61-
"8HK48": "SONAR",
62-
"YGA": "TPP",
63-
"V0V8L": "MAVIS",
64-
"X8E5B": "RAVS",
65-
"0DE": "AGEM-NIVS",
66-
"0DF": "NIMS",
67-
"8HA94": "EVA",
68-
"YGMYH": "MEDICAL_DIRECTOR",
69-
"W00": "WELSH_DA_1",
70-
"W000": "WELSH_DA_2",
71-
"ZT001": "NORTHERN_IRELAND_DA",
72-
"YA7": "SCOTLAND_DA",
73-
"N2N9I": "COVID19_VACCINE_RESOLUTION_SERVICEDESK",
74-
"YGJ": "EMIS",
75-
"YGMYW": "MEDICUS",
76-
"DPSREDUCED": "DPSREDUCED",
77-
"DPSFULL": "DPSFULL",
78-
}

filenameprocessor/src/elasticache.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import json
22
from clients import redis_client
3-
from constants import VACCINE_TYPE_TO_DISEASES_HASH_KEY, SUPPLIER_PERMISSIONS_HASH_KEY
3+
from constants import (
4+
VACCINE_TYPE_TO_DISEASES_HASH_KEY,
5+
SUPPLIER_PERMISSIONS_HASH_KEY,
6+
ODS_CODE_TO_SUPPLIER_SYSTEM_HASH_KEY
7+
)
48

59

610
def get_supplier_permissions_from_cache(supplier_system: str) -> list[str]:
@@ -11,3 +15,7 @@ def get_supplier_permissions_from_cache(supplier_system: str) -> list[str]:
1115

1216
def get_valid_vaccine_types_from_cache() -> list[str]:
1317
return redis_client.hkeys(VACCINE_TYPE_TO_DISEASES_HASH_KEY)
18+
19+
20+
def get_supplier_system_from_cache(ods_code: str) -> str:
21+
return redis_client.hget(ODS_CODE_TO_SUPPLIER_SYSTEM_HASH_KEY, ods_code)

filenameprocessor/src/file_key_validation.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
from re import match
44
from datetime import datetime
55
from constants import Constants
6-
from elasticache import get_valid_vaccine_types_from_cache
7-
from utils_for_filenameprocessor import identify_supplier
6+
from elasticache import get_valid_vaccine_types_from_cache, get_supplier_system_from_cache
87
from errors import InvalidFileKeyError
98

109

@@ -46,7 +45,7 @@ def validate_file_key(file_key: str) -> tuple[str, str]:
4645
ods_code = file_key_parts_without_extension[3]
4746
timestamp = file_key_parts_without_extension[4]
4847
extension = file_key.split(".")[1]
49-
supplier = identify_supplier(ods_code)
48+
supplier = get_supplier_system_from_cache(ods_code)
5049

5150
valid_vaccine_types = get_valid_vaccine_types_from_cache()
5251

filenameprocessor/src/utils_for_filenameprocessor.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Utils for filenameprocessor lambda"""
22

33
import json
4-
from constants import Constants, SOURCE_BUCKET_NAME, FILE_NAME_PROC_LAMBDA_NAME
4+
from constants import SOURCE_BUCKET_NAME, FILE_NAME_PROC_LAMBDA_NAME
55
from clients import s3_client, logger, lambda_client
66

77

@@ -11,14 +11,6 @@ def get_created_at_formatted_string(bucket_name: str, file_key: str) -> str:
1111
return response["LastModified"].strftime("%Y%m%dT%H%M%S00")
1212

1313

14-
def identify_supplier(ods_code: str) -> str:
15-
"""
16-
Identifies the supplier from the ods code using the mapping.
17-
Defaults to empty string if ODS code isn't found in the mappings.
18-
"""
19-
return Constants.ODS_TO_SUPPLIER_MAPPINGS.get(ods_code, "")
20-
21-
2214
def move_file(bucket_name: str, source_file_key: str, destination_file_key: str) -> None:
2315
"""Moves a file from one location to another within a single S3 bucket by copying and then deleting the file."""
2416
s3_client.copy_object(

filenameprocessor/tests/test_elasticache.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77

88
from tests.utils_for_tests.mock_environment_variables import MOCK_ENVIRONMENT_DICT
99
from tests.utils_for_tests.generic_setup_and_teardown import GenericSetUp, GenericTearDown
10+
from tests.utils_for_tests.utils_for_filenameprocessor_tests import create_mock_hget
1011

1112
# Ensure environment variables are mocked before importing from src files
1213
with patch.dict("os.environ", MOCK_ENVIRONMENT_DICT):
13-
from elasticache import get_supplier_permissions_from_cache, get_valid_vaccine_types_from_cache
14+
from elasticache import (
15+
get_supplier_permissions_from_cache,
16+
get_valid_vaccine_types_from_cache,
17+
get_supplier_system_from_cache
18+
)
1419
from clients import REGION_NAME
1520

1621
s3_client = boto3_client("s3", region_name=REGION_NAME)
@@ -29,13 +34,25 @@ def tearDown(self):
2934
"""Tear down the S3 buckets"""
3035
GenericTearDown(s3_client)
3136

32-
@patch("elasticache.redis_client.hget", return_value=json.dumps(["COVID19.CRUDS", "RSV.CRUDS"]))
37+
@patch("elasticache.redis_client.hget", side_effect=create_mock_hget(
38+
{"TEST_ODS_CODE": "TEST_SUPPLIER"},
39+
{}
40+
))
41+
def test_get_supplier_system_from_cache(self, mock_hget):
42+
result = get_supplier_system_from_cache("TEST_ODS_CODE")
43+
self.assertEqual(result, "TEST_SUPPLIER")
44+
mock_hget.assert_called_once_with("ods_code_to_supplier", "TEST_ODS_CODE")
45+
46+
@patch("elasticache.redis_client.hget", side_effect=create_mock_hget(
47+
{},
48+
{"TEST_SUPPLIER": json.dumps(["COVID19.CRUDS", "RSV.CRUDS"])}
49+
))
3350
def test_get_supplier_permissions_from_cache(self, mock_hget):
3451
result = get_supplier_permissions_from_cache("TEST_SUPPLIER")
3552
self.assertEqual(result, ["COVID19.CRUDS", "RSV.CRUDS"])
3653
mock_hget.assert_called_once_with("supplier_permissions", "TEST_SUPPLIER")
3754

38-
@patch("elasticache.redis_client.hget", return_value=None)
55+
@patch("elasticache.redis_client.hget", side_effect=create_mock_hget({}, {}))
3956
def test_get_supplier_permissions_from_cache_not_found(self, mock_hget):
4057
result = get_supplier_permissions_from_cache("TEST_SUPPLIER")
4158
self.assertEqual(result, [])

filenameprocessor/tests/test_file_key_validation.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from tests.utils_for_tests.values_for_tests import MockFileDetails
77
from tests.utils_for_tests.mock_environment_variables import MOCK_ENVIRONMENT_DICT
8+
from tests.utils_for_tests.utils_for_filenameprocessor_tests import MOCK_ODS_CODE_TO_SUPPLIER, create_mock_hget
89

910
# Ensure environment variables are mocked before importing from src files
1011
with patch.dict("os.environ", MOCK_ENVIRONMENT_DICT):
@@ -38,25 +39,27 @@ def test_is_valid_datetime(self):
3839
with self.subTest():
3940
self.assertEqual(is_valid_datetime(date_time_string), expected_result)
4041

42+
@patch("elasticache.redis_client.hget", side_effect=create_mock_hget(MOCK_ODS_CODE_TO_SUPPLIER, {}))
4143
@patch("elasticache.redis_client.hkeys", return_value=["FLU", "RSV"])
42-
def test_validate_file_key(self, _mock_hkeys):
44+
def test_validate_file_key(self, mock_hkeys, mock_hget):
4345
"""Tests that file_key_validation returns True if all elements pass validation, and False otherwise"""
4446
# Test case tuples are structured as (file_key, expected_result)
4547
test_cases_for_success_scenarios = [
4648
# Valid FLU/ EMIS file key (mixed case)
47-
(VALID_FLU_EMIS_FILE_KEY, ("FLU", "EMIS")),
49+
(VALID_FLU_EMIS_FILE_KEY, "YGM41", ("FLU", "EMIS")),
4850
# Valid FLU/ EMIS (all lowercase)
49-
(VALID_FLU_EMIS_FILE_KEY.lower(), ("FLU", "EMIS")),
51+
(VALID_FLU_EMIS_FILE_KEY.lower(), "YGM41", ("FLU", "EMIS")),
5052
# Valid FLU/ EMIS (all uppercase)
51-
(VALID_FLU_EMIS_FILE_KEY.upper(), ("FLU", "EMIS")),
53+
(VALID_FLU_EMIS_FILE_KEY.upper(), "YGM41", ("FLU", "EMIS")),
5254
# Valid RSV/ RAVS file key
53-
(VALID_RSV_RAVS_FILE_KEY, ("RSV", "RAVS")),
55+
(VALID_RSV_RAVS_FILE_KEY, "X8E5B", ("RSV", "RAVS")),
5456
]
5557

56-
for file_key, expected_result in test_cases_for_success_scenarios:
58+
for file_key, ods_code, expected_result in test_cases_for_success_scenarios:
5759
with self.subTest(f"SubTest for file key: {file_key}"):
5860
self.assertEqual(validate_file_key(file_key), expected_result)
59-
_mock_hkeys.assert_called_with("vacc_to_diseases")
61+
mock_hkeys.assert_called_with("vacc_to_diseases")
62+
mock_hget.assert_called_with("ods_code_to_supplier", ods_code)
6063

6164
key_format_error_message = "Initial file validation failed: invalid file key format"
6265
invalid_file_key_error_message = "Initial file validation failed: invalid file key"
@@ -102,4 +105,4 @@ def test_validate_file_key(self, _mock_hkeys):
102105
with self.assertRaises(InvalidFileKeyError) as context:
103106
validate_file_key(file_key)
104107
self.assertEqual(str(context.exception), expected_result)
105-
_mock_hkeys.assert_called_with("vacc_to_diseases")
108+
mock_hkeys.assert_called_with("vacc_to_diseases")

0 commit comments

Comments
 (0)