56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
"""Unit + integration tests for the LLM-fallback CSV parser."""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
|
|
def test_csv_format_template_model_columns():
|
|
"""Model exposes every column the spec requires, with correct types."""
|
|
from sqlalchemy import inspect
|
|
|
|
from app.models import CsvFormatTemplate
|
|
|
|
cols = {c.name: c for c in inspect(CsvFormatTemplate).columns}
|
|
assert "fingerprint" in cols
|
|
assert "headers" in cols
|
|
assert "sample_row" in cols
|
|
assert "mapping" in cols
|
|
assert "preamble_rows" in cols
|
|
assert "delimiter" in cols
|
|
assert "broker_label" in cols
|
|
assert "first_seen_at" in cols
|
|
assert "use_count" in cols
|
|
assert "last_used_at" in cols
|
|
assert "llm_model" in cols
|
|
assert "llm_cost_usd" in cols
|
|
# Crucially, no user attribution.
|
|
assert "user_id" not in cols
|
|
assert "first_seen_user_id" not in cols
|
|
# Fingerprint is the cache key.
|
|
assert cols["fingerprint"].unique is True
|
|
assert cols["fingerprint"].nullable is False
|
|
|
|
|
|
def test_fingerprint_stable_across_case_and_whitespace():
|
|
from app.services.llm_csv_parser import _fingerprint
|
|
|
|
a = _fingerprint(["Symbol", "Quantity", "Avg Price"])
|
|
b = _fingerprint(["symbol", "quantity", "avg price"])
|
|
c = _fingerprint([" SYMBOL ", "Quantity", " AVG PRICE"])
|
|
assert a == b == c
|
|
|
|
|
|
def test_fingerprint_differs_for_different_columns():
|
|
from app.services.llm_csv_parser import _fingerprint
|
|
|
|
a = _fingerprint(["Symbol", "Quantity"])
|
|
b = _fingerprint(["Symbol", "Quantity", "Avg Price"])
|
|
assert a != b
|
|
|
|
|
|
def test_fingerprint_is_sha256_hex_64_chars():
|
|
from app.services.llm_csv_parser import _fingerprint
|
|
|
|
f = _fingerprint(["Symbol", "Quantity"])
|
|
assert len(f) == 64
|
|
assert all(c in "0123456789abcdef" for c in f)
|