"""Characterization of the BAC paste-import line parser.""" from datetime import datetime from app.api.v1.endpoints.import_transactions import ( make_reference_hash, parse_bac_line, ) from app.models.models import TransactionType class TestParseBacLine: def test_tab_separated_purchase(self): line = "15/04/2026\tWALMART\\SAN JOSE\\CR\t25,000.50 CRC" parsed = parse_bac_line(line) assert parsed is not None assert parsed["date"] == datetime(2026, 4, 15) assert parsed["merchant"] == "WALMART" assert parsed["city"] == "SAN JOSE" assert parsed["amount"] == 25000.50 assert parsed["currency"] == "CRC" assert parsed["transaction_type"] == TransactionType.COMPRA def test_multispace_separated_usd(self): line = "01/05/2026 AMAZON\\SEATTLE\\US 12.99 USD" parsed = parse_bac_line(line) assert parsed is not None assert parsed["amount"] == 12.99 assert parsed["currency"] == "USD" def test_negative_amount_is_refund(self): parsed = parse_bac_line("15/04/2026\tSTORE\\X\\CR\t-5,000.00 CRC") assert parsed is not None assert parsed["transaction_type"] == TransactionType.DEVOLUCION assert parsed["amount"] == 5000.0 # stored as absolute value def test_pago_recibido_is_refund(self): parsed = parse_bac_line("15/04/2026\tPAGO RECIBIDO\\\\\t100.00 CRC") assert parsed is not None assert parsed["transaction_type"] == TransactionType.DEVOLUCION def test_unparseable_lines_return_none(self): assert parse_bac_line("") is None assert parse_bac_line("not a transaction") is None assert parse_bac_line("99/99/2026\tX\\Y\\Z\t1.00 CRC") is None assert parse_bac_line("15/04/2026\tX\\Y\\Z\t1.00 GBP") is None class TestReferenceHash: def test_deterministic_and_merchant_normalized(self): a = make_reference_hash(datetime(2026, 4, 15), " walmart ", 100.0, "CRC") b = make_reference_hash(datetime(2026, 4, 15), "WALMART", 100.0, "CRC") assert a == b assert len(a) == 16 def test_different_inputs_differ(self): base = make_reference_hash(datetime(2026, 4, 15), "X", 100.0, "CRC") assert make_reference_hash(datetime(2026, 4, 16), "X", 100.0, "CRC") != base assert make_reference_hash(datetime(2026, 4, 15), "X", 100.1, "CRC") != base assert make_reference_hash(datetime(2026, 4, 15), "X", 100.0, "USD") != base