8
8
9
9
TEST_COMPACT = 'aslp'
10
10
TEST_AUD_LICENSE_TYPE_ABBR = 'aud'
11
- MOCK_START_TIME = '2024-01-01T00:00:00Z'
12
- MOCK_END_TIME = '2024-01-02T00:00:00Z'
13
- MOCK_TRANSACTION_LIMIT = 500
14
11
15
12
# Test transaction data
16
13
MOCK_TRANSACTION_ID = '12345'
28
25
MOCK_CURRENT_BATCH_ID = 'mock_current_batch_id'
29
26
MOCK_PROCESSED_BATCH_IDS = ['mock_processed_batch_id' ]
30
27
28
+ MOCK_SCHEDULED_TIME = '2024-01-01T01:00:00Z'
29
+
31
30
32
31
def _generate_mock_transaction (
33
32
transaction_id = MOCK_TRANSACTION_ID ,
@@ -139,6 +138,7 @@ def _add_mock_privilege_update_to_database(
139
138
def _when_testing_non_paginated_event (self , test_compact = TEST_COMPACT ):
140
139
return {
141
140
'compact' : test_compact ,
141
+ 'scheduledTime' : MOCK_SCHEDULED_TIME , # Mock EventBridge scheduled time
142
142
'lastProcessedTransactionId' : None ,
143
143
'currentBatchId' : None ,
144
144
'processedBatchIds' : None ,
@@ -147,6 +147,7 @@ def _when_testing_non_paginated_event(self, test_compact=TEST_COMPACT):
147
147
def _when_testing_paginated_event (self , test_compact = TEST_COMPACT ):
148
148
return {
149
149
'compact' : test_compact ,
150
+ 'scheduledTime' : MOCK_SCHEDULED_TIME , # Mock EventBridge scheduled time
150
151
'lastProcessedTransactionId' : MOCK_LAST_PROCESSED_TRANSACTION_ID ,
151
152
'currentBatchId' : MOCK_CURRENT_BATCH_ID ,
152
153
'processedBatchIds' : MOCK_PROCESSED_BATCH_IDS ,
@@ -196,7 +197,15 @@ def test_process_settled_transactions_returns_complete_status(self, mock_purchas
196
197
event = self ._when_testing_non_paginated_event ()
197
198
resp = process_settled_transactions (event , self .mock_context )
198
199
199
- self .assertEqual ({'compact' : 'aslp' , 'processedBatchIds' : [MOCK_BATCH_ID ], 'status' : 'COMPLETE' }, resp )
200
+ self .assertEqual (
201
+ {
202
+ 'compact' : 'aslp' ,
203
+ 'scheduledTime' : MOCK_SCHEDULED_TIME ,
204
+ 'processedBatchIds' : [MOCK_BATCH_ID ],
205
+ 'status' : 'COMPLETE' ,
206
+ },
207
+ resp ,
208
+ )
200
209
201
210
@patch ('handlers.transaction_history.PurchaseClient' )
202
211
def test_process_settled_transactions_passes_pagination_values_into_purchase_client (
@@ -287,6 +296,42 @@ def test_process_settled_transactions_stores_transactions_in_dynamodb(self, mock
287
296
stored_transactions ['Items' ],
288
297
)
289
298
299
+ @patch ('handlers.transaction_history.PurchaseClient' )
300
+ def test_process_settled_transactions_does_not_duplicate_identical_transaction_records (
301
+ self , mock_purchase_client_constructor
302
+ ):
303
+ """Test that transactions are stored in DynamoDB."""
304
+ from handlers .transaction_history import process_settled_transactions
305
+
306
+ # in this test, there is one transaction, and one privilege. These should map together using the default
307
+ # transaction id and privilege id
308
+ self ._when_purchase_client_returns_transactions (mock_purchase_client_constructor )
309
+ self ._add_mock_privilege_to_database ()
310
+
311
+ event = self ._when_testing_non_paginated_event ()
312
+
313
+ process_settled_transactions (event , self .mock_context )
314
+
315
+ # Verify transactions were stored in DynamoDB
316
+ stored_transactions = self .config .transaction_history_table .query (
317
+ KeyConditionExpression = 'pk = :pk' ,
318
+ ExpressionAttributeValues = {':pk' : f'COMPACT#{ TEST_COMPACT } #TRANSACTIONS#MONTH#2024-01' },
319
+ )
320
+
321
+ self .assertEqual (1 , len (stored_transactions ['Items' ]))
322
+
323
+ # now run the lambda again with the same payload, the duplicate transaction record should overwrite the
324
+ # existing one
325
+ process_settled_transactions (event , self .mock_context )
326
+
327
+ # Verify transactions were stored in DynamoDB
328
+ stored_transactions = self .config .transaction_history_table .query (
329
+ KeyConditionExpression = 'pk = :pk' ,
330
+ ExpressionAttributeValues = {':pk' : f'COMPACT#{ TEST_COMPACT } #TRANSACTIONS#MONTH#2024-01' },
331
+ )
332
+
333
+ self .assertEqual (1 , len (stored_transactions ['Items' ]))
334
+
290
335
@patch ('handlers.transaction_history.PurchaseClient' )
291
336
def test_process_settled_transactions_returns_in_progress_status_with_pagination_values (
292
337
self , mock_purchase_client_constructor
@@ -302,6 +347,7 @@ def test_process_settled_transactions_returns_in_progress_status_with_pagination
302
347
self .assertEqual (
303
348
{
304
349
'compact' : TEST_COMPACT ,
350
+ 'scheduledTime' : MOCK_SCHEDULED_TIME ,
305
351
'status' : 'IN_PROGRESS' ,
306
352
'lastProcessedTransactionId' : MOCK_LAST_PROCESSED_TRANSACTION_ID ,
307
353
'currentBatchId' : MOCK_CURRENT_BATCH_ID ,
@@ -369,6 +415,7 @@ def test_process_settled_transactions_returns_batch_failure_status_after_process
369
415
{
370
416
'status' : 'IN_PROGRESS' ,
371
417
'compact' : TEST_COMPACT ,
418
+ 'scheduledTime' : MOCK_SCHEDULED_TIME ,
372
419
'currentBatchId' : MOCK_BATCH_ID ,
373
420
'lastProcessedTransactionId' : mock_first_iteration_failed_transaction_id ,
374
421
'processedBatchIds' : [],
@@ -391,6 +438,7 @@ def test_process_settled_transactions_returns_batch_failure_status_after_process
391
438
{
392
439
'status' : 'BATCH_FAILURE' ,
393
440
'compact' : TEST_COMPACT ,
441
+ 'scheduledTime' : MOCK_SCHEDULED_TIME ,
394
442
'processedBatchIds' : [MOCK_BATCH_ID ],
395
443
'batchFailureErrorMessage' : json .dumps (
396
444
{
0 commit comments