Files
WealthySmart/backend/tests/test_import_parse.py
Carlos Escalante c725c1487d Add pytest harness and 55-test suite for core backend logic
Covers: billing-cycle characterization (the BE-06 convention, boundary
instants, year wraps, deferred transactions), projection engine
(recurring schedules, no-double-count, cumulative balances, overrides,
fresh start), auth (JWT roundtrip/expiry, API tokens, constant-time
creds, rate-limit window), fail-fast settings, and the BAC paste
parser. SQLite in-memory fixtures, exchange rates pinned — no network.
Also doubles as the float-behavior baseline for the Phase 2 Decimal
migration (plan 1.5). config.py moves to SettingsConfigDict to clear
the pydantic deprecation warning from test output.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 19:46:54 -06:00

61 lines
2.4 KiB
Python

"""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