"""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")