Skip to content

Commit b228930

Browse files
Add test for monthly edge case
1 parent eb93262 commit b228930

File tree

1 file changed

+100
-2
lines changed

1 file changed

+100
-2
lines changed

backend/compact-connect/lambdas/python/purchases/tests/function/test_handlers/test_transaction_reporting.py

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
NEBRASKA_JURISDICTION = {'postalAbbreviation': 'ne', 'jurisdictionName': 'nebraska', 'sk': 'aslp#JURISDICTION#ne'}
3030

3131

32-
def generate_mock_event():
33-
return {'compact': TEST_COMPACT, 'reportingCycle': 'weekly'}
32+
def generate_mock_event(reporting_cycle: str = 'weekly'):
33+
return {'compact': TEST_COMPACT, 'reportingCycle': reporting_cycle}
3434

3535

3636
def _generate_mock_transaction(
@@ -806,3 +806,101 @@ def test_generate_report_handles_unknown_jurisdiction(self, mock_lambda_client):
806806
jurisdiction_report_payloads = [json.loads(call[1]['Payload']) for call in jurisdiction_calls]
807807
reported_jurisdictions = {payload['jurisdiction'] for payload in jurisdiction_report_payloads}
808808
self.assertEqual({'oh', 'ky'}, reported_jurisdictions) # Verify only OH and KY got reports
809+
810+
# event bridge triggers the monthly report at the first day of the month 5 mins after midnight UTC
811+
@patch('cc_common.config._Config.current_standard_datetime', datetime.fromisoformat('2024-03-01T00:05:00+00:00'))
812+
@patch('handlers.transaction_reporting.config.lambda_client')
813+
def test_generate_monthly_report_includes_expected_settled_transactions_for_full_month_range(self, mock_lambda_client):
814+
"""Test processing monthly report with full month range for Feb 2024 (leap year)."""
815+
from handlers.transaction_reporting import generate_transaction_reports
816+
817+
_set_default_lambda_client_behavior(mock_lambda_client)
818+
819+
self._add_compact_configuration_data(
820+
jurisdictions=[OHIO_JURISDICTION, KENTUCKY_JURISDICTION]
821+
)
822+
823+
mock_user = self._add_mock_provider_to_db('12345', 'John', 'Doe')
824+
# Create a transaction with a privilege which is settled the first day of the month at midnight UTC
825+
self._add_mock_transaction_to_db(
826+
jurisdictions=['oh'],
827+
licensee_id=mock_user['providerId'],
828+
month_iso_string='2024-02',
829+
transaction_settlement_time_utc=datetime.fromisoformat('2024-02-01T00:00:00+00:00'),
830+
)
831+
832+
# Create a transaction with a priviliege which is settled at the end of the month
833+
# This transaction should be included in the monthly report
834+
self._add_mock_transaction_to_db(
835+
jurisdictions=['ky'],
836+
licensee_id=mock_user['providerId'],
837+
month_iso_string='2024-02',
838+
# NOTE: the moto mock does not correctly mock the behavior of the BETWEEN condition, which according to AWS is inclusive
839+
# so for the purposes of this test we use a time that is just before midnight UTC
840+
transaction_settlement_time_utc=datetime.fromisoformat('2024-02-29T23:59:58+00:00'),
841+
)
842+
843+
# Create a transaction with a privilege which is settled the last day of the month at midnight UTC
844+
# This transaction should NOT be included in the monthly report
845+
self._add_mock_transaction_to_db(
846+
jurisdictions=['oh'],
847+
licensee_id=mock_user['providerId'],
848+
month_iso_string='2024-03',
849+
transaction_settlement_time_utc=datetime.fromisoformat('2024-03-01T00:00:00+00:00'),
850+
)
851+
852+
# Calculate expected date range
853+
# the end time should be the last day of the month
854+
end_time = datetime.fromisoformat('2024-02-29T23:59:59:9999+00:00')
855+
# the start time should be the first day of the month
856+
start_time = datetime.fromisoformat('2024-02-01T00:00:00+00:00')
857+
date_range = f"{start_time.strftime('%Y-%m-%d')}--{end_time.strftime('%Y-%m-%d')}"
858+
859+
generate_transaction_reports(generate_mock_event(reporting_cycle='monthly'), self.mock_context)
860+
861+
# Verify email notifications
862+
calls_args = mock_lambda_client.invoke.call_args_list
863+
864+
# Check compact report email
865+
compact_call = calls_args[0][1]
866+
self.assertEqual(self.config.email_notification_service_lambda_name, compact_call['FunctionName'])
867+
self.assertEqual('RequestResponse', compact_call['InvocationType'])
868+
869+
expected_compact_path = (
870+
f"compact/{TEST_COMPACT}/reports/compact-transactions/reporting-cycle/monthly/"
871+
f"{end_time.strftime('%Y/%m/%d')}/"
872+
f"{TEST_COMPACT}-{date_range}-report.zip"
873+
)
874+
compact_payload = json.loads(compact_call['Payload'])
875+
self.assertEqual(
876+
{
877+
'compact': TEST_COMPACT,
878+
'recipientType': 'COMPACT_SUMMARY_REPORT',
879+
'template': 'CompactTransactionReporting',
880+
'templateVariables': {
881+
'reportS3Path': expected_compact_path,
882+
'reportingCycle': 'monthly',
883+
'startDate': start_time.strftime('%Y-%m-%d'),
884+
'endDate': end_time.strftime('%Y-%m-%d'),
885+
},
886+
},
887+
compact_payload,
888+
)
889+
890+
# Verify S3 stored files
891+
# Check compact reports
892+
compact_zip_obj = self.config.s3_client.get_object(
893+
Bucket=self.config.transaction_reports_bucket_name, Key=expected_compact_path
894+
)
895+
896+
with ZipFile(BytesIO(compact_zip_obj['Body'].read())) as zip_file:
897+
# Check financial summary
898+
with zip_file.open(f'{TEST_COMPACT}-financial-summary-{date_range}.csv') as f:
899+
summary_content = f.read().decode('utf-8')
900+
self.assertEqual(
901+
'Total Transactions,2\n'
902+
'Total Compact Fees,$21.00\n' # $10.50 x 2 privileges
903+
'State Fees (Kentucky),$100.00\n'
904+
'State Fees (Ohio),$100.00\n',
905+
summary_content,
906+
)

0 commit comments

Comments
 (0)