"""Tests for tools/compat_auth.py, the signed-in drift check, with no network. Its log is public, so besides the exit codes these pin down what it must never print: the credentials, and anything that reveals the account's state. """ from __future__ import annotations import importlib.util import re import urllib.error import urllib.parse from pathlib import Path import pytest ROOT = Path(__file__).parent.parent WORKFLOW = ROOT / ".github" / "workflows" / "compat-auth.yml" SCRIPT = ROOT / "tools" / "compat_auth.py" _spec = importlib.util.spec_from_file_location("compat_auth", SCRIPT) compat_auth = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(compat_auth) EMAIL = "account-under-test" PASSWORD = "correct horse battery staple" ENV = {"FH_EMAIL": EMAIL, "FH_PASSWORD": PASSWORD} HEALTHY = { "/s/popup/login": ( "" "" ), "/p/dashboard/details": ( "Your deliveries are Tuesdays. Next Arriving: Tue, Aug 4" "
None scheduled
" ), "/p/dashboard/manage-orders": ( 'openPopup("pause-delivery", "a") openPopup("donate-delivery", "b")' ), "/p/shop/basket-types/georgia-grown-baskets": ( "Invalid login
")) assert code == 10 assert "[FAIL] credentials accepted" in out assert "Sign-in failed" in out def test_login_form_without_tokens_is_drift(capsys): portal = FakePortal(pages={"/s/popup/login": ""}) code, out, _ = run(capsys, portal) assert code == 10 assert "[FAIL] login form mints both anti-replay tokens" in out assert portal.posts == [] @pytest.mark.parametrize( "error", [ urllib.error.URLError("Name or service not known"), urllib.error.HTTPError(compat_auth.BASE, 503, "Service Unavailable", None, None), TimeoutError("timed out"), ConnectionResetError("reset by peer"), ], ) def test_unreachable_portal_exit_1(capsys, error): portal = FakePortal(raise_on={"/p/dashboard/details": error}) code, out, _ = run(capsys, portal) assert code == compat_auth.CANNOT_RUN == 1 assert "could not reach the portal" in out def test_network_error_text_is_redacted(capsys): error = OSError(f"refused for {EMAIL}") code, out, _ = run(capsys, FakePortal(raise_on={"/s/popup/login": error})) assert code == 1 assert "***" in out def test_unexpected_error_exit_1_names_only_the_type(capsys): error = ValueError(f"state dump {EMAIL} {PASSWORD}") code, out, _ = run(capsys, FakePortal(raise_on={"/p/dashboard/details": error})) assert code == 1 assert "ValueError" in out assert "state dump" not in out def test_exit_code_ignores_checks_with_nothing_to_assert(): assert compat_auth.exit_code([("a", True, ""), ("b", compat_auth.SKIP, "")]) == 5 assert compat_auth.exit_code([("a", True, ""), ("b", False, "x")]) == 10 # --- what a public log may reveal --------------------------------------------- def test_a_scheduled_hold_is_indistinguishable_from_none(capsys): none = run(capsys)[1] hold = run(capsys, FakePortal(pages={"/p/dashboard/pause-deliveries": ( "" "Tuesday, Sep 8 - Tuesday, Sep 15
" )}))[1] assert none == hold assert "n/a" not in none and "not applicable" not in none def test_iso_hold_dates_are_drift(capsys): code, out, _ = run(capsys, FakePortal(pages={"/p/dashboard/pause-deliveries": ( "Tuesday, Sep 8 - Tuesday, Sep 15 (2026-09-08)
" )})) assert code == 10 assert "[FAIL] hold ranges are day-name + abbreviated month, not ISO" in out def test_portal_posts_urlencoded_to_the_site(): sent = [] class StubResponse: def __enter__(self): return self def __exit__(self, *exc): return False def read(self): return b"Sign Out" class StubOpener: def open(self, req, timeout): sent.append((req, timeout)) return StubResponse() portal = compat_auth.Portal() portal._opener = StubOpener() assert portal.post("/s/submit/login", {"LoginEmail": EMAIL}) == "Sign Out" req, timeout = sent[0] assert req.full_url == "https://freshharvest.com/s/submit/login" assert urllib.parse.parse_qs(req.data.decode()) == {"LoginEmail": [EMAIL]} assert timeout == compat_auth.TIMEOUT # --- the workflow ------------------------------------------------------------- def test_workflow_lives_where_gitea_reads_it(): # Gitea reads only the FIRST of .gitea/workflows and .github/workflows that # exists; creating .gitea/workflows would silently stop every workflow here. assert WORKFLOW.is_file() assert not (ROOT / ".gitea" / "workflows").exists() def test_workflow_shape(): yaml = pytest.importorskip("yaml") doc = yaml.safe_load(WORKFLOW.read_text(encoding="utf-8")) triggers = doc.get("on", doc.get(True)) # YAML 1.1 reads a bare `on` as True assert set(triggers) == {"schedule", "workflow_dispatch"} assert triggers["schedule"] == [{"cron": "41 11 * * *"}] assert doc["permissions"] == {"contents": "read"} [job] = doc["jobs"].values() assert job["timeout-minutes"] == 10 assert "github.server_url" in job["if"] def test_workflow_and_script_keep_private_details_out(): text = WORKFLOW.read_text(encoding="utf-8") code = "\n".join( line for line in text.splitlines() if not line.lstrip().startswith("#") ) assert "set -x" not in code and "xtrace" not in code assert set(re.findall(r"secrets\.(\w+)", text)) == { "FRESHHARVEST_EMAIL", "FRESHHARVEST_PASSWORD", "NTFY_URL", "NTFY_TOKEN", } for source in (text, SCRIPT.read_text(encoding="utf-8")): assert not re.search(r"[\w.+-]+@[\w-]+\.[\w.-]+", source), "an email address" assert not re.search(r"\b\d{1,3}(?:\.\d{1,3}){3}\b", source), "an IP address" hosts = set(re.findall(r"https?://([^/\s'\"]+)", source)) assert hosts <= {"freshharvest.com", "github.com"}, hosts