import unittest from scripts.match_payments import reconcile class TestReconcileWithExceptions(unittest.TestCase): def test_reconcile_applies_exceptions(self): # 1. Setup mock data # Member: Alice, Tier A, expected 750 (attendance-based) members = [ ('Alice', 'A', {'2026-01': (750, 4)}) ] sorted_months = ['2026-01'] # Exception: Alice should only pay 400 in 2026-01 (normalized keys, no accents) exceptions = { ('alice', '2026-01'): {'amount': 400, 'note': 'Test exception'} } # Transaction: Alice paid 400 transactions = [{ 'date': '2026-01-05', 'amount': 400, 'person': 'Alice', 'purpose': '2026-01', 'inferred_amount': 400, 'sender': 'Alice Sender', 'message': 'fee' }] # 2. Reconcile result = reconcile(members, sorted_months, transactions, exceptions) # 3. Assertions alice_data = result['members']['Alice'] jan_data = alice_data['months']['2026-01'] self.assertEqual(jan_data['expected'], 400, "Expected amount should be overridden by exception") self.assertEqual(jan_data['paid'], 400, "Paid amount should be 400") self.assertEqual(alice_data['total_balance'], 0, "Balance should be 0 because 400/400") def test_reconcile_fallback_to_attendance(self): # Alice has attendance-based fee 750, NO exception members = [ ('Alice', 'A', {'2026-01': (750, 4)}) ] sorted_months = ['2026-01'] exceptions = {} # No exceptions transactions = [] result = reconcile(members, sorted_months, transactions, exceptions) alice_data = result['members']['Alice'] self.assertEqual(alice_data['months']['2026-01']['expected'], 750, "Should fallback to attendance fee") if __name__ == '__main__': unittest.main()