fix(frontend): Weekly view must always send an explicit date to /grade
All checks were successful
PR build (required check) / changes (pull_request) Successful in 7s
secrets-guard / encrypted (pull_request) Successful in 5s
PR build (required check) / build-backend (pull_request) Has been skipped
shell-lint / shellcheck (pull_request) Successful in 8s
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Successful in 43s
PR build (required check) / gate (pull_request) Successful in 2s
All checks were successful
PR build (required check) / changes (pull_request) Successful in 7s
secrets-guard / encrypted (pull_request) Successful in 5s
PR build (required check) / build-backend (pull_request) Has been skipped
shell-lint / shellcheck (pull_request) Successful in 8s
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / build-frontend (pull_request) Successful in 43s
PR build (required check) / gate (pull_request) Successful in 2s
This commit is contained in:
parent
1a7f92be66
commit
44b02d985a
1 changed files with 57 additions and 0 deletions
57
frontend/tests/unit/test_app_js_grade_date.py
Normal file
57
frontend/tests/unit/test_app_js_grade_date.py
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
"""Regression guard for the grade-URL "today" date bug: runGrade() in app.js used
|
||||||
|
to omit `date` from the /api/v2/grade request whenever the selected date equaled
|
||||||
|
the viewer's local today, so the backend fell back to ITS OWN UTC today
|
||||||
|
(api_grade's `date` param default in backend/web/app.py) -- a day behind local
|
||||||
|
midnight for any viewer east of UTC. Reported from Kaunas (UTC+3): asking for
|
||||||
|
the Weekly tab on 7/26 rendered 7/25.
|
||||||
|
|
||||||
|
There is no JS/DOM test harness in this repo to drive app.js and assert on the
|
||||||
|
real fetch() URL it builds: static/package.json declares zero dependencies (no
|
||||||
|
jest/playwright/node test runner), no such runner is wired into scripts/test.sh
|
||||||
|
or any workflow, and server/**/*_test.go (the Go suite CI actually gates on)
|
||||||
|
covers the Go SSR layer only, never static/*.js's runtime behavior. So this
|
||||||
|
can't be a behavioral test. What it CAN do, hermetically, through the same
|
||||||
|
served-asset route test_pages.py already exercises (`GET {B}/app.js`), is treat
|
||||||
|
the real shipped source as data and assert the structural property the fix
|
||||||
|
guarantees: runGrade() builds exactly one grade URL and always includes an
|
||||||
|
explicit `date=`, rather than branching on whether the selected date is "today"
|
||||||
|
and omitting it in that case.
|
||||||
|
|
||||||
|
This fails against the pre-fix source and passes against the fixed source --
|
||||||
|
a source guard, not a substitute for a real behavioral test.
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
|
||||||
|
B = "/thermograph" # matches THERMOGRAPH_BASE set in tests/conftest.py
|
||||||
|
|
||||||
|
|
||||||
|
def _run_grade_body(client) -> str:
|
||||||
|
r = client.get(f"{B}/app.js")
|
||||||
|
assert r.status_code == 200
|
||||||
|
src = r.text
|
||||||
|
m = re.search(r"async function runGrade\(\) \{\n(.*?)\n\}\n", src, re.DOTALL)
|
||||||
|
assert m, "runGrade() not found in app.js -- update this test if it moved/was renamed"
|
||||||
|
return m.group(1)
|
||||||
|
|
||||||
|
|
||||||
|
def test_run_grade_always_sends_explicit_date(client):
|
||||||
|
"""The historical bug: `dateInput.value === todayISO() ? grade?q : grade?q&date=...`
|
||||||
|
omitted `date` for "today", so the backend's own UTC-today fallback rendered the
|
||||||
|
previous day for any UTC+ viewer between their local midnight and UTC midnight."""
|
||||||
|
body = _run_grade_body(client)
|
||||||
|
assert not re.search(r"dateInput\.value\s*===\s*todayISO\(\)", body), \
|
||||||
|
"runGrade() still branches on today to decide whether to send date="
|
||||||
|
assert body.count("grade?") == 1, \
|
||||||
|
"runGrade() should build exactly one grade URL, not two divergent branches"
|
||||||
|
assert re.search(r"date=\$\{[^}]+\}", body), \
|
||||||
|
"runGrade() must always build the URL with an explicit date= param"
|
||||||
|
|
||||||
|
|
||||||
|
def test_run_grade_never_sends_an_empty_date(client):
|
||||||
|
"""A cleared native date field reports dateInput.value === "" (day.js guards the
|
||||||
|
same input for the same reason). An empty date= hits the identical server-UTC
|
||||||
|
fallback this fix exists to avoid, so runGrade() must fall back to the viewer's
|
||||||
|
own local today rather than ever send the param empty."""
|
||||||
|
body = _run_grade_body(client)
|
||||||
|
assert re.search(r"dateInput\.value\s*\|\|\s*todayISO\(\)", body), \
|
||||||
|
"runGrade() should fall back to todayISO() when dateInput.value is empty"
|
||||||
Loading…
Reference in a new issue