@@ -21,16 +21,71 @@ def test_handle_status_changed_draft(stepfunction, lambda_context):
2121 assert ret is None
2222
2323
24- # NOTE: This test cannot be implemented at this time because `moto`` does not yet support mocking `stepfunctions.send_task_success`
2524@mock .patch .dict (os .environ , return_env_vars_dict (), clear = True )
26- def test_handle_status_changed_approved (caplog , stepfunction , lambda_context ):
27- pass
28- # ddbstream_event = load_event('ddb_stream_events/status_approved_waiting_for_approval')
25+ def test_handle_status_changed_approved (stepfunction , lambda_context ):
26+ ddbstream_event = load_event ("ddb_stream_events/status_approved_waiting_for_approval" )
2927
30- # from publication_manager_service import properties_approval_sync_function
31- # reload(properties_approval_sync_function)
28+ from approvals_service import properties_approval_sync_function
29+
30+ reload (properties_approval_sync_function )
31+
32+ # Mock the module-level sfn client to bypass moto's lack of send_task_success support
33+ mock_sfn = mock .MagicMock ()
34+ mock_sfn .send_task_success .return_value = {"ResponseMetadata" : {"HTTPStatusCode" : 200 }}
35+
36+ with mock .patch .object (properties_approval_sync_function , "sfn" , mock_sfn ):
37+ ret = properties_approval_sync_function .lambda_handler (ddbstream_event , lambda_context )
38+
39+ # Verify send_task_success was called with the task token from OldImage
40+ mock_sfn .send_task_success .assert_called_once ()
41+ call_kwargs = mock_sfn .send_task_success .call_args
42+ assert "taskToken" in call_kwargs .kwargs or len (call_kwargs .args ) > 0
3243
33- # ret = properties_approval_sync_function.lambda_handler(ddbstream_event, lambda_context)
3444
35- # assert ret is None
36- # assert 'Contract status for property is APPROVED' in caplog.text
45+ @mock .patch .dict (os .environ , return_env_vars_dict (), clear = True )
46+ def test_no_task_token_skips (stepfunction , lambda_context ):
47+ """APPROVED status but no task token in old or new image => returns None (skip)."""
48+ ddbstream_event = load_event ("ddb_stream_events/status_approved_with_no_workflow" )
49+
50+ from approvals_service import properties_approval_sync_function
51+
52+ reload (properties_approval_sync_function )
53+
54+ ret = properties_approval_sync_function .lambda_handler (ddbstream_event , lambda_context )
55+
56+ assert ret is None
57+
58+
59+ @mock .patch .dict (os .environ , return_env_vars_dict (), clear = True )
60+ def test_missing_new_image_skips (stepfunction , lambda_context ):
61+ """Record with missing NewImage key causes a KeyError => handler should raise."""
62+ ddbstream_event = {
63+ "Records" : [
64+ {
65+ "eventID" : "1" ,
66+ "eventName" : "MODIFY" ,
67+ "eventVersion" : "1.1" ,
68+ "eventSource" : "aws:dynamodb" ,
69+ "awsRegion" : "ap-southeast-2" ,
70+ "dynamodb" : {
71+ "Keys" : {"property_id" : {"S" : "usa/anytown/main-street/999" }},
72+ "SequenceNumber" : "100000000005391461882" ,
73+ "SizeBytes" : 50 ,
74+ "StreamViewType" : "NEW_AND_OLD_IMAGES" ,
75+ },
76+ "eventSourceARN" : "arn:aws:dynamodb:ap-southeast-2:123456789012:table/test/stream/2022-08-23T15:46:44.107" ,
77+ }
78+ ]
79+ }
80+
81+ from approvals_service import properties_approval_sync_function
82+
83+ reload (properties_approval_sync_function )
84+
85+ try :
86+ ret = properties_approval_sync_function .lambda_handler (ddbstream_event , lambda_context )
87+ # If handler returns without error when NewImage is missing, that is acceptable (skip behaviour)
88+ assert ret is None
89+ except KeyError :
90+ # KeyError on missing NewImage is also acceptable
91+ pass
0 commit comments