"""The page and the agents are released together (X6): these fail in the PR that would break the page, not in the operator's browser.""" import threading from pathlib import Path import httpx import pytest from ui_fixtures import recorded, store_at from nisse_core.models import calls from nisse_core.state.store import StateStore as CoreStore from nisse_dev.state import StateStore as DevStore from nisse_review.state import StateStore as ReviewStore from nisse_ui import main as ui_main from nisse_ui.app import App from nisse_ui.sources import KNOWN_SCHEMAS, discover @pytest.mark.parametrize("store", [CoreStore, DevStore, ReviewStore]) def test_every_agents_schema_is_one_the_page_knows(store: type[CoreStore]) -> None: # An agent that moves its schema on must teach the page too. assert store.SCHEMA_VERSION in KNOWN_SCHEMAS @pytest.mark.parametrize("store_class", [DevStore, ReviewStore]) def test_each_agents_own_store_opens( tmp_path: Path, store_class: type[CoreStore] ) -> None: store = store_at(tmp_path, store_class) store.open_work_item("i1", title="Agent item", position="NEW", cause="t") store.close() app = App(discover([("a", tmp_path / "state.db")], [])) assert app.handle("/s/a/").status == 200 assert "Agent item" in app.handle("/s/a/item/i1").body.decode() def test_runs_the_benchmark_kept_are_sources(tmp_path: Path) -> None: # As bench --keep-runs leaves them: /-/state.db + record. for name in ("fix-bug-1a2b3c4d", "trace-bug-5e6f7a8b"): _, store = recorded(tmp_path / "kept" / name) store.close() (tmp_path / "kept" / "not-a-run").mkdir() sources = discover([], [tmp_path / "kept"]) assert sorted(s.name for s in sources) == [ "kept.fix-bug-1a2b3c4d", "kept.trace-bug-5e6f7a8b", ] assert all(s.kind == "run" and s.calls_db.is_file() for s in sources) assert sources[0].calls_db == calls.path_for(sources[0].state_db) def test_source_names_are_safe_and_unique(tmp_path: Path) -> None: sources = discover( [("dev agent/1", tmp_path / "a"), ("dev agent/1", tmp_path / "b")], [] ) assert [s.name for s in sources] == ["dev-agent-1", "dev-agent-1-2"] def test_the_server_listens_on_this_machine_and_sends_the_headers( tmp_path: Path, ) -> None: source, store = recorded(tmp_path / "a") store.close() server = ui_main.ThreadingHTTPServer( ("127.0.0.1", 0), ui_main.handler_for(App([source])) ) thread = threading.Thread(target=server.serve_forever, daemon=True) thread.start() try: port = server.server_address[1] response = httpx.get(f"http://127.0.0.1:{port}/s/agent/item/w1") assert response.status_code == 200 assert "Fix the parser" in response.text assert "default-src 'none'" in response.headers["content-security-policy"] assert response.headers["x-content-type-options"] == "nosniff" assert response.headers["server"].startswith("nisse-ui") finally: server.shutdown() server.server_close() def test_the_command_line_defaults_to_this_machine_only( monkeypatch: pytest.MonkeyPatch, ) -> None: assert ui_main._source("dev=/var/lib/nisse-dev/state.db") == ( "dev", Path("/var/lib/nisse-dev/state.db"), ) with pytest.raises(Exception, match="NAME=STATE_DB"): ui_main._source("no-equals") class Bound(Exception): pass def server(address: tuple[str, int], handler: object) -> None: raise Bound(address) monkeypatch.setattr(ui_main, "ThreadingHTTPServer", server) with pytest.raises(Bound) as bound: ui_main.main([]) assert bound.value.args[0] == ("127.0.0.1", 8765)