Consecutive captures whose printed PAGE X OF Y markers advance under the same total are grouped into one multi-page PDF, with duplicate pages keeping the better read. Naming gains doc-title/party components and a scan-date fallback so nothing lands in UNSORTED. Vision LLM default switches to minicpm-v (faster, fewer false blanks on dense mono pages).
122 lines
3.8 KiB
Python
122 lines
3.8 KiB
Python
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",
|
|
)
|