From 24e6cf5ca897254c68f0ee29be0353b26ed9005e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 14 Aug 2026 19:04:39 +0000 Subject: [PATCH] Skip UI-serving tests when the web export is absent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Next.js export is a generated artifact and deliberately untracked (82183d9 stopped tracking it; the Docker image builds it in its own node stage), but three tests still asserted its presence — failing on every fresh clone. They now skip with a clear reason when src/handler/api/static/ was never built, and keep guarding any environment that has it. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01731mKtVzsfeT4Vi3TvkR48 --- CHANGELOG.md | 4 ++++ tests/test_api_ui.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a98a5b..ddcdf5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ the image workflows publish (plus `latest` from every push to `main`). placements (schedule firings, mise-init) keep the old fast-forward behavior for their shared tree. 2 end-to-end regression tests (bare remote, parked root, out-of-band push). +- **UI-serving tests skip when the web export is absent** instead of failing every + fresh clone: the export is a generated, deliberately untracked artifact (built in + the Docker image's node stage), so the three `test_api_ui` checks now guard any + environment that has it and skip with a clear reason where it was never built. ### Fixed diff --git a/tests/test_api_ui.py b/tests/test_api_ui.py index 5232792..bdd7952 100644 --- a/tests/test_api_ui.py +++ b/tests/test_api_ui.py @@ -9,10 +9,21 @@ from __future__ import annotations import re from pathlib import Path +import pytest from fastapi.testclient import TestClient _STATIC_DIR = Path(__file__).resolve().parents[1] / "src" / "handler" / "api" / "static" +# The export is a generated artifact and deliberately untracked (it caused guaranteed +# merge conflicts — see .gitignore): the Docker image builds it in its own node stage, +# and a source checkout only has it after `npm run export`. The serving tests still +# guard any environment that *has* the export; a fresh clone just skips them. +_needs_export = pytest.mark.skipif( + not (_STATIC_DIR / "index.html").is_file(), + reason="web UI export not built (frontend: npm run export); " + "generated artifact, untracked by design", +) + def _reset_caches() -> None: from handler import config @@ -36,6 +47,7 @@ def _fresh_client(monkeypatch, **overrides) -> TestClient: # --- shell + assets are served, unauthenticated ------------------------------------- +@_needs_export def test_index_served_unauthenticated(client): res = client.get("/") # no Authorization header assert res.status_code == 200 @@ -45,6 +57,7 @@ def test_index_served_unauthenticated(client): assert "Bearer" not in res.text +@_needs_export def test_next_assets_served_unauthenticated(client): # The export references its hashed bundles under /_next/. Discover one from the shell # and confirm it's served same-origin without auth (filenames are content-hashed, so @@ -57,6 +70,7 @@ def test_next_assets_served_unauthenticated(client): assert res.headers["content-type"].startswith(("application/javascript", "text/javascript")) +@_needs_export def test_static_export_is_bundled(): # The built export ships inside the package tree so `pip install .` bundles it. assert (_STATIC_DIR / "index.html").is_file()