Skip to content

Commit 0ebf783

Browse files
committed
VED-372: Query Redis for valid vaccine types.
1 parent ff323d8 commit 0ebf783

File tree

6 files changed

+45
-24
lines changed

6 files changed

+45
-24
lines changed

filenameprocessor/src/constants.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
AUDIT_TABLE_FILENAME_GSI = "filename_index"
1818

1919
PERMISSIONS_CONFIG_FILE_KEY = "permissions_config.json"
20+
VACCINE_TYPE_TO_DISEASES_HASH_KEY = "vacc_to_diseases"
2021

2122
ERROR_TYPE_TO_STATUS_CODE_MAP = {
2223
VaccineTypePermissionsError: 403,
@@ -50,9 +51,6 @@ class AuditTableKeys:
5051

5152
class Constants:
5253
"""Constants for the filenameprocessor lambda"""
53-
54-
VALID_VACCINE_TYPES = ["FLU", "COVID19", "MMR", "RSV"]
55-
5654
VALID_VERSIONS = ["V5"]
5755

5856
# Mappings from ODS code to supplier name.

filenameprocessor/src/elasticache.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import json
44
from clients import s3_client, redis_client
5-
from constants import PERMISSIONS_CONFIG_FILE_KEY
5+
from constants import PERMISSIONS_CONFIG_FILE_KEY, VACCINE_TYPE_TO_DISEASES_HASH_KEY
66

77

88
def upload_to_elasticache(file_key: str, bucket_name: str) -> None:
@@ -16,3 +16,7 @@ def upload_to_elasticache(file_key: str, bucket_name: str) -> None:
1616
def get_permissions_config_json_from_cache() -> dict:
1717
"""Gets and returns the permissions config file content from ElastiCache (Redis)."""
1818
return json.loads(redis_client.get(PERMISSIONS_CONFIG_FILE_KEY))
19+
20+
21+
def get_valid_vaccine_types_from_cache() -> list[str]:
22+
return redis_client.hkeys(VACCINE_TYPE_TO_DISEASES_HASH_KEY)

filenameprocessor/src/file_key_validation.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +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
67
from utils_for_filenameprocessor import identify_supplier
78
from errors import InvalidFileKeyError
89

@@ -47,9 +48,11 @@ def validate_file_key(file_key: str) -> tuple[str, str]:
4748
extension = file_key.split(".")[1]
4849
supplier = identify_supplier(ods_code)
4950

51+
valid_vaccine_types = get_valid_vaccine_types_from_cache()
52+
5053
# Validate each file key element
5154
if not (
52-
vaccine_type in Constants.VALID_VACCINE_TYPES
55+
vaccine_type in valid_vaccine_types
5356
and vaccination == "VACCINATIONS"
5457
and version in Constants.VALID_VERSIONS
5558
and supplier # Note that if supplier could be identified, this also implies that ODS code is valid

filenameprocessor/tests/test_file_key_validation.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
class TestFileKeyValidation(TestCase):
1919
"""Tests for file_key_validation functions"""
20+
def setUp(self):
21+
redis_patcher = patch("clients.redis_client.hkeys", return_value=["FLU", "COVID19", "MMR", "RSV"])
22+
self.addCleanup(redis_patcher.stop)
23+
redis_patcher.start()
2024

2125
def test_is_valid_datetime(self):
2226
"Tests that is_valid_datetime returns True for valid datetimes, and false otherwise"

filenameprocessor/tests/test_lambda_handler.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Tests for lambda_handler"""
2+
import json
23
import sys
34
from unittest.mock import patch
45
from unittest import TestCase
@@ -19,6 +20,10 @@
1920
from tests.utils_for_tests.mock_environment_variables import MOCK_ENVIRONMENT_DICT, BucketNames, Sqs
2021
from tests.utils_for_tests.values_for_tests import MOCK_CREATED_AT_FORMATTED_STRING, MockFileDetails
2122

23+
from constants import VACCINE_TYPE_TO_DISEASES_HASH_KEY
24+
25+
from elasticache import get_valid_vaccine_types_from_cache
26+
2227
# Ensure environment variables are mocked before importing from src files
2328
with patch.dict("os.environ", MOCK_ENVIRONMENT_DICT):
2429
from file_name_processor import lambda_handler, handle_record
@@ -67,6 +72,7 @@ def run(self, result=None):
6772
patch("elasticache.redis_client", new=fakeredis.FakeStrictRedis()),
6873
# Patch the permissions config to allow all suppliers full permissions for all vaccine types.
6974
patch("elasticache.redis_client.get", return_value=all_permissions_config_content),
75+
patch("elasticache.redis_client.hkeys", return_value=all_vaccine_types_in_this_test_file),
7076
]
7177

7278
with ExitStack() as stack:
@@ -457,12 +463,18 @@ class TestLambdaHandlerConfig(TestCase):
457463
"""Tests for lambda_handler when a config file is uploaded."""
458464

459465
config_event = {
460-
"Records": [{"s3": {"bucket": {"name": BucketNames.CONFIG}, "object": {"key": (PERMISSIONS_CONFIG_FILE_KEY)}}}]
466+
"Records": [{"s3": {"bucket": {"name": BucketNames.CONFIG}, "object": {"key": PERMISSIONS_CONFIG_FILE_KEY}}}]
461467
}
462468

463469
def setUp(self):
464470
GenericSetUp(s3_client, firehose_client, sqs_client, dynamodb_client)
465471

472+
self.fake_redis = fakeredis.FakeStrictRedis(decode_responses=True)
473+
self.fake_redis.hmset(VACCINE_TYPE_TO_DISEASES_HASH_KEY, {"RSV": "[]"})
474+
redis_patcher = patch("elasticache.redis_client", new=self.fake_redis)
475+
self.addCleanup(redis_patcher.stop)
476+
redis_patcher.start()
477+
466478
def tearDown(self):
467479
GenericTearDown(s3_client, firehose_client, sqs_client, dynamodb_client)
468480

@@ -475,8 +487,10 @@ def test_elasticcache_failure_handled(self):
475487
}
476488
}
477489

478-
with patch("file_name_processor.upload_to_elasticache", side_effect=Exception("Upload failed")), \
479-
patch("file_name_processor.logger") as mock_logger:
490+
with (
491+
patch("file_name_processor.upload_to_elasticache", side_effect=Exception("Upload failed")),
492+
patch("file_name_processor.logger") as mock_logger
493+
):
480494

481495
result = handle_record(event)
482496

@@ -491,8 +505,6 @@ def test_elasticcache_failure_handled(self):
491505

492506
def test_successful_processing_from_configs(self):
493507
"""Tests that the permissions config file content is uploaded to elasticache successfully"""
494-
fake_redis = fakeredis.FakeStrictRedis()
495-
496508
ravs_rsv_file_details_1 = MockFileDetails.ravs_rsv_1
497509
ravs_rsv_file_details_2 = MockFileDetails.ravs_rsv_2
498510
s3_client.put_object(Bucket=BucketNames.SOURCE, Key=ravs_rsv_file_details_1.file_key)
@@ -509,17 +521,13 @@ def test_successful_processing_from_configs(self):
509521
Key=PERMISSIONS_CONFIG_FILE_KEY,
510522
Body=generate_permissions_config_content(ravs_rsv_permissions),
511523
)
512-
with patch("elasticache.redis_client", new=fake_redis):
513-
lambda_handler(self.config_event, None)
524+
lambda_handler(self.config_event, None)
514525
self.assertEqual(
515-
json_loads(fake_redis.get(PERMISSIONS_CONFIG_FILE_KEY)), {"all_permissions": ravs_rsv_permissions}
526+
json_loads(self.fake_redis.get(PERMISSIONS_CONFIG_FILE_KEY)), {"all_permissions": ravs_rsv_permissions}
516527
)
517528

518529
# Check that a RAVS RSV file processes successfully (as RAVS has permissions for RSV)
519-
with (
520-
patch("file_name_processor.uuid4", return_value=ravs_rsv_file_details_1.message_id),
521-
patch("elasticache.redis_client", new=fake_redis),
522-
):
530+
with patch("file_name_processor.uuid4", return_value=ravs_rsv_file_details_1.message_id):
523531
result = handle_record(record_1)
524532
expected_result = {
525533
"statusCode": 200,
@@ -537,17 +545,13 @@ def test_successful_processing_from_configs(self):
537545
Key=PERMISSIONS_CONFIG_FILE_KEY,
538546
Body=generate_permissions_config_content(ravs_no_rsv_permissions),
539547
)
540-
with patch("elasticache.redis_client", new=fake_redis):
541-
lambda_handler(self.config_event, None)
548+
lambda_handler(self.config_event, None)
542549
self.assertEqual(
543-
json_loads(fake_redis.get(PERMISSIONS_CONFIG_FILE_KEY)), {"all_permissions": ravs_no_rsv_permissions}
550+
json_loads(self.fake_redis.get(PERMISSIONS_CONFIG_FILE_KEY)), {"all_permissions": ravs_no_rsv_permissions}
544551
)
545552

546553
# Check that a RAVS RSV file fails to process (as RAVS now does not have permissions for RSV)
547-
with (
548-
patch("file_name_processor.uuid4", return_value=ravs_rsv_file_details_2.message_id),
549-
patch("elasticache.redis_client", new=fake_redis),
550-
):
554+
with patch("file_name_processor.uuid4", return_value=ravs_rsv_file_details_2.message_id):
551555
result = handle_record(record_2)
552556
expected_result = {
553557
"statusCode": 403,
@@ -572,6 +576,10 @@ class TestUnexpectedBucket(TestCase):
572576
def setUp(self):
573577
GenericSetUp(s3_client, firehose_client, sqs_client, dynamodb_client)
574578

579+
redis_patcher = patch("elasticache.redis_client.hkeys", return_value=all_vaccine_types_in_this_test_file)
580+
self.addCleanup(redis_patcher.stop)
581+
redis_patcher.start()
582+
575583
def tearDown(self):
576584
GenericTearDown(s3_client, firehose_client, sqs_client, dynamodb_client)
577585

filenameprocessor/tests/test_logging_decorator.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ def setUp(self):
4848
GenericSetUp(s3_client, firehose_client, sqs_client, dynamodb_client)
4949
s3_client.put_object(Bucket=BucketNames.SOURCE, Key=FILE_DETAILS.file_key)
5050

51+
redis_patcher = patch("clients.redis_client.hkeys", return_value=["FLU", "COVID19", "MMR", "RSV"])
52+
self.addCleanup(redis_patcher.stop)
53+
redis_patcher.start()
54+
5155
def tearDown(self):
5256
"""Clean the mock AWS environment"""
5357
GenericTearDown(s3_client, firehose_client, sqs_client, dynamodb_client)

0 commit comments

Comments
 (0)