AI-Pricing-Agent/tests/test_invp_header_matches_co...

99 lines
3.8 KiB
Python

"""The Inventory Planning header must quote COSMOS's own figures, not ours re-derived.
The weekly cells always matched, because they come straight from the `invp-insight` dateMap.
The HEADER did not: it was recomputed from our sales-insight history, so one SKU read
56 / 62 / 65 here against 64 / 130 / 67 in COSMOS Inventory Planning -- same product, same
screen position, two different numbers.
Fixed by carrying COSMOS's fields through verbatim:
daily sale ours 7-day mean 56 -> COSMOS `averageSale` 64
middle cell ours 30-day mean 62 -> COSMOS `potentialDailySale` 130 (a DIFFERENT
quantity: a demand estimate, not a trailing mean)
third cell ours 90-day mean 65 -> COSMOS `averageSale6Months` 67
on hand first projected week 5,029 -> COSMOS `inventory` 3,999
inbound every arrival 1,770 -> the IMMEDIATE arrival 1,030
"""
from __future__ import annotations
import pathlib
SRC = pathlib.Path(__file__).resolve().parents[1] / "app.py"
TEXT = SRC.read_text(encoding="utf-8")
def _table_body() -> str:
return TEXT.split("def inventory_table_html")[1].split("\ndef ")[0]
def test_header_reads_cosmos_fields_not_history_means():
body = _table_body()
assert "invp_stats" in body, "header no longer reads COSMOS's own figures"
assert '_st.get("avg_sale")' in body
assert '_st.get("potential_daily_sale")' in body
assert '_st.get("avg_6m")' in body
def test_the_old_history_derived_cells_are_gone():
body = _table_body()
assert "{d30:,.0f}" not in body, "30-day history mean is back in the header"
assert "{d90:,.0f}" not in body, "90-day history mean is back in the header"
def test_on_hand_is_cosmos_inventory_not_the_first_projected_week():
"""5,029 is week one WITH its arrival folded in; 3,999 is the shelf."""
body = _table_body()
assert 'get("invp_stats") or {}).get("inventory")' in body
assert "on hand" in body
def test_inbound_is_the_immediate_arrival_with_later_ones_reported_separately():
body = _table_body()
assert 'total_inbound = float(proj[0]["warehouse_arrival"] or 0)' in body
assert "later_inbound" in body, "later arrivals must still be reported, not dropped"
# ---------------------------------------------------------------- encoding hygiene
# app.py and dashboard/live_data.py were once written back through a cp1252 round trip, so
# every em dash, middot and emoji in the UI rendered as garbage. It showed in the BROWSER, not
# just an editor, which makes it a user-visible defect rather than a tidiness one.
#
# The signatures are built with chr() rather than spelled out, so this file cannot match its
# own check.
_ROOT = pathlib.Path(__file__).resolve().parents[1]
_MOJIBAKE = (
chr(0xE2) + chr(0x20AC), # em/en dash, curly quotes, ellipsis
chr(0xC2) + chr(0xB7), # middot
chr(0xF0) + chr(0x178), # any 4-byte emoji
chr(0xC3) + chr(0xA2), # doubly encoded
)
_SKIP = {".venv", "__pycache__", "new_archtetcure_and frontend", ".mojibake_backup"}
def _py_sources():
for f in _ROOT.rglob("*.py"):
if not _SKIP.intersection(f.parts):
yield f
def test_no_source_file_is_mojibake():
bad = {}
for f in _py_sources():
text = f.read_bytes().decode("utf-8-sig")
hits = sum(text.count(m) for m in _MOJIBAKE)
if hits:
bad[str(f.relative_to(_ROOT))] = hits
assert not bad, f"mojibake in: {bad}"
def test_no_source_file_has_a_bom():
"""A BOM breaks `ast.parse` on a utf-8 read and shows as a stray char in some editors."""
bom = bytes([0xEF, 0xBB, 0xBF])
bad = [str(f.relative_to(_ROOT)) for f in _py_sources() if f.read_bytes()[:3] == bom]
assert not bad, f"UTF-8 BOM in: {bad}"
def test_every_source_file_is_valid_utf8():
for f in _py_sources():
f.read_bytes().decode("utf-8")