@@ -1148,3 +1148,49 @@ def collect_payment(payment: Payment):
11481148
11491149 # THEN idempotency key assertion happens at MockPersistenceLayer
11501150 assert result == payment .transaction_id
1151+
1152+
1153+ @pytest .mark .parametrize ("idempotency_config" , [{"use_local_cache" : False }], indirect = True )
1154+ def test_idempotent_lambda_compound_already_completed (
1155+ idempotency_config : IdempotencyConfig ,
1156+ persistence_store_compound : DynamoDBPersistenceLayer ,
1157+ lambda_apigw_event ,
1158+ timestamp_future ,
1159+ hashed_idempotency_key ,
1160+ serialized_lambda_response ,
1161+ deserialized_lambda_response ,
1162+ lambda_context ,
1163+ ):
1164+ """
1165+ Test idempotent decorator having a DynamoDBPersistenceLayer with a compound key
1166+ """
1167+
1168+ stubber = stub .Stubber (persistence_store_compound .table .meta .client )
1169+ stubber .add_client_error ("put_item" , "ConditionalCheckFailedException" )
1170+ ddb_response = {
1171+ "Item" : {
1172+ "id" : {"S" : "idempotency#" },
1173+ "sk" : {"S" : hashed_idempotency_key },
1174+ "expiration" : {"N" : timestamp_future },
1175+ "data" : {"S" : serialized_lambda_response },
1176+ "status" : {"S" : "COMPLETED" },
1177+ }
1178+ }
1179+ expected_params = {
1180+ "TableName" : TABLE_NAME ,
1181+ "Key" : {"id" : "idempotency#" , "sk" : hashed_idempotency_key },
1182+ "ConsistentRead" : True ,
1183+ }
1184+ stubber .add_response ("get_item" , ddb_response , expected_params )
1185+
1186+ stubber .activate ()
1187+
1188+ @idempotent (config = idempotency_config , persistence_store = persistence_store_compound )
1189+ def lambda_handler (event , context ):
1190+ raise ValueError
1191+
1192+ lambda_resp = lambda_handler (lambda_apigw_event , lambda_context )
1193+ assert lambda_resp == deserialized_lambda_response
1194+
1195+ stubber .assert_no_pending_responses ()
1196+ stubber .deactivate ()
0 commit comments