11import unittest
22import os
3+ from typing import Optional
34from unittest import TestCase
4- from unittest .mock import patch , MagicMock
5+ from unittest .mock import patch , MagicMock , call , ANY
56from boto3 import resource as boto3_resource
67from moto import mock_aws
78from models .errors import (
1920from utils .test_utils_for_batch import ForwarderValues , MockFhirImmsResources
2021
2122with patch .dict ("os.environ" , ForwarderValues .MOCK_ENVIRONMENT_DICT ):
22- from forwarding_batch_lambda import forward_lambda_handler , create_diagnostics_dictionary , forward_request_to_dynamo
23+ from forwarding_batch_lambda import forward_lambda_handler , create_diagnostics_dictionary , forward_request_to_dynamo , \
24+ QUEUE_URL
25+
26+
2327@mock_aws
2428@patch .dict (os .environ , ForwarderValues .MOCK_ENVIRONMENT_DICT )
2529class TestForwardLambdaHandler (TestCase ):
@@ -99,13 +103,14 @@ def generate_details_from_processing(
99103
100104 @staticmethod
101105 def generate_input (
102- row_id ,
103- identifier_value = None ,
104- file_key = "test_file_key" ,
105- created_at_formatted_string = "2025-01-24T12:00:00Z" ,
106- include_fhir_json = True ,
107- operation_requested = "create" ,
108- diagnostics = None ,
106+ row_id : int ,
107+ identifier_value : Optional [str ] = None ,
108+ file_key : str = "test_file_key" ,
109+ created_at_formatted_string : str = "2025-01-24T12:00:00Z" ,
110+ include_fhir_json : bool = True ,
111+ operation_requested : str = "create" ,
112+ diagnostics : dict = None ,
113+ supplier : str = "test_supplier"
109114 ):
110115 """Generates input rows for test_cases."""
111116 details_from_processing = TestForwardLambdaHandler .generate_details_from_processing (
@@ -118,7 +123,7 @@ def generate_input(
118123 "row_id" : f"row-{ row_id } " ,
119124 "file_key" : file_key ,
120125 "created_at_formatted_string" : created_at_formatted_string ,
121- "supplier" : "test_supplier" ,
126+ "supplier" : supplier ,
122127 "vax_type" : "RSV" ,
123128 ** details_from_processing ,
124129 }
@@ -403,13 +408,71 @@ def test_forward_lambda_handler_multiple_scenarios(self, mock_send_message):
403408 mock_send_message .reset_mock ()
404409 event = self .generate_event (test_cases )
405410
406-
407411 self .mock_redis_client .hget .return_value = "RSV"
408412 forward_lambda_handler (event , {})
409413
410414 self .assert_dynamo_item (table_item )
411415 self .assert_values_in_sqs_messages (mock_send_message , test_cases )
412416
417+ @patch ("forwarding_batch_lambda.sqs_client.send_message" )
418+ def test_forward_lambda_handler_groups_and_sends_events_by_filename (self , mock_send_message ):
419+ """VED-734 - each batch handled by the Lambda may have events relating to different parent CSV files. This
420+ test ensures events are grouped accordingly and sent with the correct SQS"""
421+ mock_records = [
422+ {
423+ "input" : self .generate_input (
424+ row_id = 1 ,
425+ identifier_value = "supplier_1_system/54321" ,
426+ operation_requested = "CREATE" ,
427+ file_key = "supplier_1_rsv_test_file" ,
428+ supplier = "supplier_1"
429+ )
430+ },
431+ {
432+ "input" : self .generate_input (
433+ row_id = 2 ,
434+ identifier_value = "supplier_2_system/12345" ,
435+ operation_requested = "CREATE" ,
436+ file_key = "supplier_2_rsv_test_file" ,
437+ supplier = "supplier_2"
438+ )
439+ }
440+ ]
441+ mock_kinesis_event = self .generate_event (mock_records )
442+ self .mock_redis_client .hget .return_value = "RSV"
443+
444+ forward_lambda_handler (mock_kinesis_event , {})
445+
446+ sqs_calls = mock_send_message .call_args_list
447+ _ , first_call_kwargs = sqs_calls [0 ]
448+ _ , second_call_kwargs = sqs_calls [1 ]
449+
450+ # Separate calls are made for each of the respective groups
451+ self .assertEqual (len (sqs_calls ), 2 )
452+ self .assertEqual (first_call_kwargs ["MessageGroupId" ], "supplier_1_rsv_test_file_2025-01-24T12:00:00Z" )
453+ self .assertEqual (second_call_kwargs ["MessageGroupId" ], "supplier_2_rsv_test_file_2025-01-24T12:00:00Z" )
454+
455+ self .assertDictEqual (json .loads (first_call_kwargs ["MessageBody" ])[0 ], {
456+ "created_at_formatted_string" : "2025-01-24T12:00:00Z" ,
457+ "file_key" : "supplier_1_rsv_test_file" ,
458+ "imms_id" : ANY ,
459+ "local_id" : "local-1" ,
460+ "operation_requested" : "CREATE" ,
461+ "row_id" : "row-1" ,
462+ "supplier" : "supplier_1" ,
463+ "vaccine_type" : "RSV"
464+ })
465+ self .assertDictEqual (json .loads (second_call_kwargs ["MessageBody" ])[0 ], {
466+ "created_at_formatted_string" : "2025-01-24T12:00:00Z" ,
467+ "file_key" : "supplier_2_rsv_test_file" ,
468+ "imms_id" : ANY ,
469+ "local_id" : "local-2" ,
470+ "operation_requested" : "CREATE" ,
471+ "row_id" : "row-2" ,
472+ "supplier" : "supplier_2" ,
473+ "vaccine_type" : "RSV"
474+ })
475+
413476 @patch ("forwarding_batch_lambda.sqs_client.send_message" )
414477 def test_forward_lambda_handler_update_scenarios (self , mock_send_message ):
415478 """Test forward lambda handler with multiple rows in the event with update and delete operations,
@@ -584,7 +647,7 @@ def test_create_diagnostics_dictionary(self):
584647 @patch ("forwarding_batch_lambda.forward_request_to_dynamo" )
585648 @patch ("forwarding_batch_lambda.create_table" )
586649 @patch ("forwarding_batch_lambda.make_batch_controller" )
587- def test_forward_request_to_dyanamo (
650+ def test_forward_request_to_dynamo (
588651 self , mock_make_controller , mock_create_table , mock_forward_request_to_dynamo , mock_send_message
589652 ):
590653 """Test forward lambda handler to assert dynamo db is called,
0 commit comments