"""Regression tests for the recon package — type round-trips, join_path, and column_to_tables index.""" from api.recon.types import Recon, Relationship, Table, Column, Metric def _sample_recon() -> Recon: cols_account = [ Column("account_id", "BIGINT", False), Column("district_id", "BIGINT", True), ] cols_district = [ Column("district_id", "BIGINT", False), Column("A2", "TEXT", True), Column("A11", "BIGINT", True), ] cols_loan = [ Column("loan_id", "BIGINT", False), Column("account_id", "BIGINT", True), Column("amount", "BIGINT", True), Column("status", "TEXT", True), ] rels = [ Relationship("account", "district_id", "district", "district_id"), Relationship("loan", "account_id", "account", "account_id"), ] c2t = { "account_id": sorted(["account", "loan"]), "district_id": sorted(["account", "district"]), "A2": ["district"], "A11": ["district"], "loan_id": ["loan"], "amount": ["loan"], "status": ["loan"], } return Recon( schema="financial", tables={ "account": Table("account", "Accounts", cols_account), "district": Table("district", "Districts", cols_district), "loan": Table("loan", "Loans", cols_loan), }, metrics={ "loan_volume": Metric("loan_volume", "Total CZK lent", "SUM(amount)", "loan", None, "CZK"), }, column_to_tables=c2t, relationships=rels, ) def test_owning_tables(): r = _sample_recon() assert r.owning_tables("A2") == ["district"] assert r.owning_tables("amount") == ["loan"] assert r.owning_tables("account_id") == ["account", "loan"] assert r.owning_tables("nonsense") == [] def test_join_path_direct(): r = _sample_recon() assert r.join_path("loan", "account") == ["loan", "account"] assert r.join_path("account", "district") == ["account", "district"] def test_join_path_multi_hop(): r = _sample_recon() assert r.join_path("loan", "district") == ["loan", "account", "district"] def test_join_path_same(): r = _sample_recon() assert r.join_path("loan", "loan") == ["loan"] def test_join_path_unknown_returns_none(): r = _sample_recon() assert r.join_path("loan", "does_not_exist") is None def test_recon_to_dict_from_dict_roundtrip(): r = _sample_recon() d = r.to_dict() r2 = Recon.from_dict(d) assert r2.schema == r.schema assert sorted(r2.tables) == sorted(r.tables) assert sorted(r2.metrics) == sorted(r.metrics) assert r2.column_to_tables == r.column_to_tables assert len(r2.relationships) == len(r.relationships) assert r2.join_path("loan", "district") == ["loan", "account", "district"] def test_relationship_parse_dotted(): r = Relationship.parse({"from": "loan.account_id", "to": "account.account_id"}) assert r.from_table == "loan" assert r.from_column == "account_id" assert r.to_table == "account" assert r.to_column == "account_id" def test_relationship_parse_explicit(): r = Relationship.parse({ "from_table": "loan", "from_column": "account_id", "to_table": "account", "to_column": "account_id", }) assert r.from_table == "loan"