from datetime import datetime from paperpod.naming.filename import build_name, dedupe_stem, slugify def test_slugify_basic(): assert slugify("THE HOME DEPOT") == "the_home_depot" assert slugify("Café Déjà-Vu!!") == "caf_d_j_vu" def test_slugify_empty_falls_back(): assert slugify("") == "doc" assert slugify("!!!") == "doc" def test_slugify_truncates(): long_name = "a" * 100 assert len(slugify(long_name, max_len=40)) <= 40 def test_build_name_full_metadata(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name("2023-03-14", "THE HOME DEPOT", dt) assert result.stem == "2023-03-14_the_home_depot" assert result.source == "ocr" def test_build_name_date_only(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name("2023-03-14", None, dt) assert result.stem == "2023-03-14_document" assert result.source == "ocr" def test_build_name_vendor_only_uses_scan_date(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name(None, "METRO", dt) assert result.stem == "2026-01-01_metro" assert result.source == "scan_date" def test_build_name_nothing_found(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name(None, None, dt) assert result.stem == "2026-01-01_scan" assert result.source == "none" def test_build_name_appends_doc_title(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name("2025-01-31", "TD Canada Trust", dt, doc_title="transaction_history") assert result.stem == "2025-01-31_td_canada_trust_transaction_history" def test_build_name_appends_party_shortname(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name( "2025-01-31", "TD Canada Trust", dt, doc_title="transaction_history", party="LEVIT I", ) assert result.stem == "2025-01-31_td_canada_trust_transaction_history_levit_i" def test_build_name_doc_title_not_duplicated_when_vendor_says_same(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name("2025-01-31", "Transaction History", dt, doc_title="transaction_history") assert result.stem == "2025-01-31_transaction_history" def test_build_name_with_time_disambiguates_same_day_visits(): dt = datetime(2026, 1, 1, 12, 0, 0) morning = build_name("2023-03-20", "WALMART", dt, time="09:05") evening = build_name("2023-03-20", "WALMART", dt, time="18:42") assert morning.stem == "2023-03-20_0905_walmart" assert evening.stem == "2023-03-20_1842_walmart" assert morning.stem != evening.stem def test_build_name_invalid_time_ignored(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name("2023-03-14", "METRO", dt, time="not-a-time") assert result.stem == "2023-03-14_metro" def test_build_name_time_without_date_ignored(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name(None, "METRO", dt, time="09:05") assert result.stem == "2026-01-01_metro" def test_build_name_tax_form_with_year_and_org(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name( None, "T4 YORK UNIVERSITY", dt, form_code="T4", tax_year="2023", org_name="YORK UNIVERSITY", ) assert result.stem == "2023_T4_york_university" assert result.source == "ocr" def test_build_name_tax_form_year_only(): dt = datetime(2026, 1, 1, 12, 0, 0) result = build_name(None, "T4", dt, form_code="T4", tax_year="2023") assert result.stem == "2023_T4" def test_dedupe_stem_no_collision(): used: set[str] = set() assert dedupe_stem("2023-03-14_metro", used) == "2023-03-14_metro" def test_dedupe_stem_collision_increments(): used: set[str] = set() first = dedupe_stem("2023-03-14_metro", used) second = dedupe_stem("2023-03-14_metro", used) third = dedupe_stem("2023-03-14_metro", used) assert (first, second, third) == ( "2023-03-14_metro", "2023-03-14_metro_2", "2023-03-14_metro_3", )