@@ -194,10 +194,50 @@ def _when_testing_get_compact_configuration_with_existing_compact_configuration(
194
194
event ['pathParameters' ]['compact' ] = compact_config ['compactAbbr' ]
195
195
return event , compact_config
196
196
197
+ def _when_testing_put_compact_configuration_with_existing_configuration (
198
+ self , set_payment_fields : bool = True , transaction_fee_zero : bool = False
199
+ ):
200
+ from cc_common .utils import ResponseEncoder
201
+
202
+ value_overrides = {}
203
+ if set_payment_fields :
204
+ value_overrides .update (
205
+ {'paymentProcessorPublicFields' : {'publicClientKey' : 'some-key' , 'apiLoginId' : 'some-login-id' }}
206
+ )
207
+ compact_config = self .test_data_generator .put_default_compact_configuration_in_configuration_table (
208
+ value_overrides = value_overrides
209
+ )
210
+
211
+ event = generate_test_event ('PUT' , COMPACT_CONFIGURATION_ENDPOINT_RESOURCE )
212
+ event ['pathParameters' ]['compact' ] = compact_config .compactAbbr
213
+ # add compact admin scope to the event
214
+ event ['requestContext' ]['authorizer' ]['claims' ]['scope' ] = f'{ compact_config .compactAbbr } /admin'
215
+ event ['requestContext' ]['authorizer' ]['claims' ]['sub' ] = 'some-admin-id'
216
+
217
+ # we only allow the following values in the body
218
+ event ['body' ] = json .dumps (
219
+ {
220
+ 'compactCommissionFee' : compact_config .compactCommissionFee ,
221
+ 'licenseeRegistrationEnabled' : compact_config .licenseeRegistrationEnabled ,
222
+ 'compactOperationsTeamEmails' : compact_config .compactOperationsTeamEmails ,
223
+ 'compactAdverseActionsNotificationEmails' : compact_config .compactAdverseActionsNotificationEmails ,
224
+ 'compactSummaryReportNotificationEmails' : compact_config .compactSummaryReportNotificationEmails ,
225
+ 'transactionFeeConfiguration' : compact_config .transactionFeeConfiguration
226
+ if not transaction_fee_zero
227
+ else {
228
+ 'licenseeCharges' : {'chargeAmount' : 0.00 , 'chargeType' : 'FLAT_FEE_PER_PRIVILEGE' , 'active' : True }
229
+ },
230
+ },
231
+ cls = ResponseEncoder ,
232
+ )
233
+ return event , compact_config
234
+
197
235
def _when_testing_put_compact_configuration (self , transaction_fee_zero : bool = False ):
198
236
from cc_common .utils import ResponseEncoder
199
237
200
- compact_config = self .test_data_generator .generate_default_compact_configuration ()
238
+ compact_config = self .test_data_generator .generate_default_compact_configuration (
239
+ value_overrides = {'licenseeRegistrationEnabled' : False }
240
+ )
201
241
event = generate_test_event ('PUT' , COMPACT_CONFIGURATION_ENDPOINT_RESOURCE )
202
242
event ['pathParameters' ]['compact' ] = compact_config .compactAbbr
203
243
# add compact admin scope to the event
@@ -302,7 +342,7 @@ def test_put_compact_configuration_rejects_state_admin_with_auth_error(self):
302
342
self .assertEqual (403 , response ['statusCode' ])
303
343
self .assertIn ('Access denied' , json .loads (response ['body' ])['message' ])
304
344
305
- def test_put_compact_configuration_stores_compact_configuration (self ):
345
+ def test_put_compact_configuration_stores_new_compact_configuration (self ):
306
346
"""Test putting a compact configuration stores the compact configuration."""
307
347
from cc_common .data_model .schema .compact import CompactConfigurationData
308
348
from handlers .compact_configuration import compact_configuration_api_handler
@@ -322,6 +362,27 @@ def test_put_compact_configuration_stores_compact_configuration(self):
322
362
323
363
self .assertEqual (compact_config .to_dict (), stored_compact_data .to_dict ())
324
364
365
+ def test_put_compact_configuration_preserves_payment_processor_fields_when_updating_compact_configuration (self ):
366
+ """Test putting a compact configuration preserves existing fields not set by the request body."""
367
+ from cc_common .data_model .schema .compact import CompactConfigurationData
368
+ from handlers .compact_configuration import compact_configuration_api_handler
369
+
370
+ event , compact_config = self ._when_testing_put_compact_configuration_with_existing_configuration ()
371
+
372
+ response = compact_configuration_api_handler (event , self .mock_context )
373
+ self .assertEqual (200 , response ['statusCode' ], msg = json .loads (response ['body' ]))
374
+
375
+ # load the record from the configuration table
376
+ serialized_compact_config = compact_config .serialize_to_database_record ()
377
+ response = self .config .compact_configuration_table .get_item (
378
+ Key = {'pk' : serialized_compact_config ['pk' ], 'sk' : serialized_compact_config ['sk' ]}
379
+ )
380
+
381
+ stored_compact_data = CompactConfigurationData .from_database_record (response ['Item' ])
382
+ # the compact_config variable has the 'paymentProcessorPublicFields' field, which we expect to also be
383
+ # present in the stored_compact_data
384
+ self .assertEqual (compact_config .to_dict (), stored_compact_data .to_dict ())
385
+
325
386
def test_put_compact_configuration_removes_transaction_fee_when_zero (self ):
326
387
"""Test that when a transaction fee of 0 is provided, the transaction fee configuration is removed."""
327
388
from cc_common .data_model .schema .compact import CompactConfigurationData
@@ -348,26 +409,60 @@ def test_put_compact_configuration_rejects_disabling_licensee_registration(self)
348
409
from handlers .compact_configuration import compact_configuration_api_handler
349
410
350
411
# First, create a compact configuration with licenseeRegistrationEnabled=True
351
- event , original_config = self ._when_testing_put_compact_configuration ()
352
- # Set licenseeRegistrationEnabled to True in the request body
412
+ event , _ = self ._when_testing_put_compact_configuration_with_existing_configuration ()
413
+
414
+ # Now attempt to update with licenseeRegistrationEnabled=False
353
415
body = json .loads (event ['body' ])
354
- body ['licenseeRegistrationEnabled' ] = True
416
+ body ['licenseeRegistrationEnabled' ] = False
355
417
event ['body' ] = json .dumps (body )
356
418
357
- # Submit the configuration
358
- compact_configuration_api_handler (event , self .mock_context )
419
+ # Should be rejected with a 400 error
420
+ response = compact_configuration_api_handler (event , self .mock_context )
421
+ self .assertEqual (400 , response ['statusCode' ])
422
+ response_body = json .loads (response ['body' ])
423
+ self .assertIn ('Once licensee registration has been enabled, it cannot be disabled' , response_body ['message' ])
359
424
360
- # Now attempt to update with licenseeRegistrationEnabled=False
425
+ def test_put_compact_configuration_rejects_enabling_licensee_registration_without_payment_credentials (self ):
426
+ """Test that a compact configuration update is rejected if trying to enable licensee registration without payment processor credentials."""
427
+ from handlers .compact_configuration import compact_configuration_api_handler
428
+
429
+ # Attempt to enable licensee registration without any existing configuration (no payment credentials)
361
430
event , _ = self ._when_testing_put_compact_configuration ()
362
431
body = json .loads (event ['body' ])
363
- body ['licenseeRegistrationEnabled' ] = False
432
+ body ['licenseeRegistrationEnabled' ] = True
364
433
event ['body' ] = json .dumps (body )
365
434
366
435
# Should be rejected with a 400 error
367
436
response = compact_configuration_api_handler (event , self .mock_context )
368
437
self .assertEqual (400 , response ['statusCode' ])
369
438
response_body = json .loads (response ['body' ])
370
- self .assertIn ('Once licensee registration has been enabled, it cannot be disabled' , response_body ['message' ])
439
+ self .assertIn (
440
+ 'Authorize.net credentials need to be uploaded before the compact can be marked as live.' ,
441
+ response_body ['message' ],
442
+ )
443
+
444
+ def test_put_compact_configuration_rejects_enabling_licensee_registration_with_existing_config_without_payment_credentials (
445
+ self ,
446
+ ):
447
+ """Test that a compact configuration update is rejected if trying to enable licensee registration when existing config has no payment credentials."""
448
+ from handlers .compact_configuration import compact_configuration_api_handler
449
+
450
+ # First, create a basic compact configuration without payment credentials
451
+ event , _ = self ._when_testing_put_compact_configuration_with_existing_configuration (set_payment_fields = False )
452
+
453
+ # Now attempt to enable licensee registration without payment credentials
454
+ body = json .loads (event ['body' ])
455
+ body ['licenseeRegistrationEnabled' ] = True
456
+ event ['body' ] = json .dumps (body )
457
+
458
+ # Should be rejected with a 400 error
459
+ response = compact_configuration_api_handler (event , self .mock_context )
460
+ self .assertEqual (400 , response ['statusCode' ])
461
+ response_body = json .loads (response ['body' ])
462
+ self .assertIn (
463
+ 'Authorize.net credentials not configured for compact. Please upload valid Authorize.net credentials.' ,
464
+ response_body ['message' ],
465
+ )
371
466
372
467
373
468
TEST_MILITARY_RATE = Decimal ('40.00' )
0 commit comments