@@ -1148,3 +1148,49 @@ def collect_payment(payment: Payment):
1148
1148
1149
1149
# THEN idempotency key assertion happens at MockPersistenceLayer
1150
1150
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