Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
463 changes: 264 additions & 199 deletions lambdas/redis_sync/poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions lambdas/redis_sync/src/constants.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
class RedisCacheKey:
PERMISSIONS_CONFIG_FILE_KEY = "permissions_config.json"
DISEASE_MAPPING_FILE_KEY = "disease_mapping.json"
VALIDATION_RULES_FILE_KEY = "validation_rules.json"
4 changes: 4 additions & 0 deletions lambdas/redis_sync/src/redis_cacher.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ def upload(bucket_name: str, file_key: str) -> dict:

# Transform
redis_mappings = transform_map(config_file_content, file_key)
if not redis_mappings:
msg = f"No valid Redis mappings found for file '{file_key}'. Nothing uploaded."
logger.warning(msg)
return {"status": "warning", "message": msg}

redis_client = get_redis_client()
for key, mapping in redis_mappings.items():
Expand Down
4 changes: 4 additions & 0 deletions lambdas/redis_sync/src/transform_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ def transform_supplier_permissions(mapping):
"supplier_permissions": supplier_permissions,
"ods_code_to_supplier": ods_code_to_supplier
}


def transform_validation_rules(data) -> dict:
return {"validation_rules": data}
9 changes: 7 additions & 2 deletions lambdas/redis_sync/src/transform_map.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
from constants import RedisCacheKey
from transform_configs import transform_vaccine_map, transform_supplier_permissions
from transform_configs import (
transform_vaccine_map, transform_supplier_permissions, transform_validation_rules
)
from common.clients import logger
'''
Transform config file to format required in REDIS cache.
'''


def transform_map(data, file_type):
def transform_map(data, file_type) -> dict:
# Transform the vaccine map data as needed
logger.info("Transforming data for file type: %s", file_type)
if file_type == RedisCacheKey.PERMISSIONS_CONFIG_FILE_KEY:
return transform_supplier_permissions(data)
if file_type == RedisCacheKey.DISEASE_MAPPING_FILE_KEY:
return transform_vaccine_map(data)
if file_type == RedisCacheKey.VALIDATION_RULES_FILE_KEY:
return transform_validation_rules(data)

logger.info("No specific transformation defined for file type: %s", file_type)
return data # Default case, return data as is if no transformation is defined
37 changes: 24 additions & 13 deletions lambdas/redis_sync/tests/test_redis_cacher.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,14 @@
class TestRedisCacher(unittest.TestCase):

def setUp(self):
# mock s3_reader and transform_map
self.s3_reader_patcher = patch("redis_cacher.S3Reader")
self.mock_s3_reader = self.s3_reader_patcher.start()
self.transform_map_patcher = patch("redis_cacher.transform_map")
self.mock_transform_map = self.transform_map_patcher.start()
self.redis_client_patcher = patch("common.redis_client.redis_client")
self.mock_redis_client = self.redis_client_patcher.start()
self.logger_info_patcher = patch("logging.Logger.info")
self.mock_logger_info = self.logger_info_patcher.start()
self.mock_s3_reader = patch("redis_cacher.S3Reader").start()
self.mock_transform_map = patch("redis_cacher.transform_map").start()
self.mock_redis_client = patch("common.redis_client.redis_client").start()
self.mock_logger_info = patch("logging.Logger.info").start()
self.mock_logger_warning = patch("logging.Logger.warning").start()

def tearDown(self):
self.s3_reader_patcher.stop()
self.transform_map_patcher.stop()
self.redis_client_patcher.stop()
self.logger_info_patcher.stop()
patch.stopall()

def test_upload(self):
mock_data = {"a": "b"}
Expand Down Expand Up @@ -75,3 +68,21 @@ def test_deletes_extra_fields(self):
})
self.mock_redis_client.hdel.assert_called_once_with("hash_name", "obsolete_key_1", "obsolete_key_2")
self.assertEqual(result, {"status": "success", "message": f"File {file_key} uploaded to Redis cache."})

def test_unrecognised_format(self):
mock_data = {"a": "b"}

self.mock_s3_reader.read = unittest.mock.Mock()
self.mock_s3_reader.read.return_value = mock_data
self.mock_transform_map.return_value = {}

bucket_name = "bucket"
file_key = "file-key.my_yaml"
result = RedisCacher.upload(bucket_name, file_key)

self.mock_s3_reader.read.assert_called_once_with(bucket_name, file_key)
self.assertEqual(result["status"], "warning")
self.assertEqual(result["message"], f"No valid Redis mappings found for file '{file_key}'. Nothing uploaded.")
self.mock_logger_warning.assert_called_once()
self.mock_redis_client.hmset.assert_not_called()
self.mock_redis_client.hdel.assert_not_called()
16 changes: 12 additions & 4 deletions lambdas/redis_sync/tests/test_transform_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
import unittest
import json
from unittest.mock import patch
from transform_configs import transform_vaccine_map, transform_supplier_permissions
from transform_configs import (
transform_vaccine_map, transform_supplier_permissions, transform_validation_rules
)


class TestTransformConfigs(unittest.TestCase):
def setUp(self):
self.logger_info_patcher = patch("transform_configs.logger.info")
self.mock_logger_info = self.logger_info_patcher.start()
self.mock_logger_info = patch("transform_configs.logger.info").start()
self.mock_logger_warning = patch("transform_configs.logger.warning").start()

with open("./tests/test_data/disease_mapping.json") as mapping_data:
self.sample_map = json.load(mapping_data)
Expand All @@ -17,7 +19,7 @@ def setUp(self):
self.supplier_data = json.load(permissions_data)

def tearDown(self):
self.logger_info_patcher.stop()
patch.stopall()

def test_disease_to_vacc(self):
with open("./tests/test_data/expected_disease_to_vacc.json") as f:
Expand All @@ -43,6 +45,12 @@ def test_ods_code_to_supplier(self):
result = transform_supplier_permissions(self.supplier_data)
self.assertEqual(result["ods_code_to_supplier"], expected)

def test_validation_rules(self):
# validation schema is simple json returned as is to key "validation_rules"
sample_schema = {"type": "object", "properties": {"name": {"type": "string"}}}
result = transform_validation_rules(sample_schema)
self.assertEqual(result, {"validation_rules": sample_schema})

def test_empty_input(self):
result = transform_supplier_permissions([])
self.assertEqual(result, {
Expand Down
44 changes: 44 additions & 0 deletions lambdas/redis_sync/tests/test_transform_map.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

import unittest
from unittest.mock import patch
from transform_map import transform_map
from constants import RedisCacheKey


class TestTransformMap(unittest.TestCase):
def setUp(self):
self.mock_logger_info = patch("transform_map.logger.info").start()
self.mock_logger_warning = patch("transform_map.logger.warning").start()
self.mock_supplier_permissions = patch("transform_map.transform_supplier_permissions",
return_value={"result": "supplier"}).start()
self.mock_vaccine_map = patch("transform_map.transform_vaccine_map", return_value={"result": "vaccine"}).start()
self.mock_validation_rules = patch("transform_map.transform_validation_rules").start()

def tearDown(self):
patch.stopall()

def test_permissions_config_file_key_calls_supplier_permissions(self):
data = {"some": "data"}
result = transform_map(data, RedisCacheKey.PERMISSIONS_CONFIG_FILE_KEY)
self.mock_supplier_permissions.assert_called_once_with(data)
self.assertEqual(result, {"result": "supplier"})
self.mock_logger_info.assert_any_call(
"Transforming data for file type: %s", RedisCacheKey.PERMISSIONS_CONFIG_FILE_KEY)

def test_disease_mapping_file_key_calls_vaccine_map(self):
data = {"other": "data"}
self.mock_validation_rules.return_value = {"validation_rules": data}
result = transform_map(data, RedisCacheKey.DISEASE_MAPPING_FILE_KEY)
self.mock_vaccine_map.assert_called_once_with(data)
self.assertEqual(result, {"result": "vaccine"})
self.mock_logger_info.assert_any_call(
"Transforming data for file type: %s", RedisCacheKey.DISEASE_MAPPING_FILE_KEY)

def test_validation_rules_file_key_calls_validation_rules(self):
data = {"validation": "schema"}
self.mock_validation_rules.return_value = {"validation_rules": data}
result = transform_map(data, RedisCacheKey.VALIDATION_RULES_FILE_KEY)
self.mock_validation_rules.assert_called_once_with(data)
self.assertEqual(result, {"validation_rules": data})
self.mock_logger_info.assert_any_call(
"Transforming data for file type: %s", RedisCacheKey.VALIDATION_RULES_FILE_KEY)
Loading