🔥 remove html chat routes tests
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
dab4aac8ba
commit
46e2211f8c
3 changed files with 34 additions and 87 deletions
|
|
@ -138,74 +138,6 @@ def test_autocomplete_invalid_kind_400(client: TestClient) -> None:
|
|||
assert r.status_code == 422 # FastAPI pattern-match → 422
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# HTML routes (HTMX)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_html_chat_orchestrator_renders(client: TestClient) -> None:
|
||||
r = client.get("/chat")
|
||||
assert r.status_code == 200
|
||||
assert "clare" in r.text
|
||||
# The hidden cursor input is on the page even with no messages.
|
||||
assert 'id="chat-after-rowid"' in r.text
|
||||
|
||||
|
||||
def test_html_chat_project_renders_after_creation(client: TestClient) -> None:
|
||||
client.post("/api/v1/projects", json={"name": "alpha"})
|
||||
r = client.get("/chat/project/alpha")
|
||||
assert r.status_code == 200
|
||||
assert "alpha" in r.text
|
||||
|
||||
|
||||
def test_html_chat_project_missing_404(client: TestClient) -> None:
|
||||
client.post("/api/v1/projects", json={"name": "alpha"}) # need at least one
|
||||
r = client.get("/chat/project/nope")
|
||||
assert r.status_code == 404
|
||||
|
||||
|
||||
def test_html_chat_post_returns_partial(client: TestClient) -> None:
|
||||
r = client.post(
|
||||
"/chat/post",
|
||||
data={"scope": "orchestrator", "scope_ref": "", "body": "/help"},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert "chat-msg-user" in r.text
|
||||
assert "chat-msg-clare" in r.text
|
||||
# OOB hidden input present so the next poll resumes from the new rowid.
|
||||
assert 'hx-swap-oob="true"' in r.text
|
||||
|
||||
|
||||
def test_html_chat_post_nl_unavailable_for_bare_text_in_project_scope(
|
||||
client: TestClient, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
# NL fallback fires in project/session scopes only — orchestrator scope
|
||||
# talks to the managed Claude session instead.
|
||||
monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False)
|
||||
client.post("/api/v1/projects", json={"name": "alpha"})
|
||||
r = client.post(
|
||||
"/chat/post",
|
||||
data={"scope": "project", "scope_ref": "alpha", "body": "what is happening"},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert "Natural-language parsing unavailable" in r.text
|
||||
|
||||
|
||||
def test_html_chat_log_poll_returns_only_new(client: TestClient) -> None:
|
||||
# Post two messages.
|
||||
r1 = client.post(
|
||||
"/api/v1/chat",
|
||||
json={"scope": "orchestrator", "scope_ref": None, "body": "/status"},
|
||||
)
|
||||
last = r1.json()["replies"][-1]["rowid"]
|
||||
r2 = client.post(
|
||||
"/api/v1/chat",
|
||||
json={"scope": "orchestrator", "scope_ref": None, "body": "/status"},
|
||||
)
|
||||
poll = client.get(
|
||||
"/chat/log",
|
||||
params={"scope": "orchestrator", "scope_ref": "", "after_rowid": last},
|
||||
)
|
||||
assert poll.status_code == 200
|
||||
# /status posts user + reply → 2 new bubbles since `last`.
|
||||
assert poll.text.count("chat-msg ") >= 2
|
||||
# HTML routes were deleted in R6 — the React SPA owns all browser-facing
|
||||
# views. JSON API + SSE are the only server-rendered surfaces; everything
|
||||
# else goes through the catch-all that serves dist/index.html.
|
||||
|
|
|
|||
|
|
@ -179,9 +179,11 @@ def test_json_api_posts_preview_for_bare_text(
|
|||
assert "project(s)" in payload["replies"][1]["body"]
|
||||
|
||||
|
||||
def test_html_route_dispatches_after_preview(
|
||||
def test_json_route_dispatches_after_preview(
|
||||
client: TestClient, monkeypatch: pytest.MonkeyPatch
|
||||
) -> None:
|
||||
# The old HTMX /chat/post route was deleted in R6. JSON API covers the
|
||||
# same flow: NL preview at replies[0], auto-dispatched result at replies[1].
|
||||
def fake_interpret(text: str, ctx: ScopeCtx, *, client=None) -> nl.ProposedAction:
|
||||
return nl.ProposedAction(
|
||||
slash="/status", explanation="fleet check", confidence=1.0,
|
||||
|
|
@ -190,10 +192,11 @@ def test_html_route_dispatches_after_preview(
|
|||
monkeypatch.setattr("clare.web.chat.nl.interpret", fake_interpret)
|
||||
client.post("/api/v1/projects", json={"name": "alpha"})
|
||||
r = client.post(
|
||||
"/chat/post",
|
||||
data={"scope": "project", "scope_ref": "alpha", "body": "any news?"},
|
||||
"/api/v1/chat",
|
||||
json={"scope": "project", "scope_ref": "alpha", "body": "any news?"},
|
||||
)
|
||||
assert r.status_code == 200
|
||||
assert "Interpreted as" in r.text
|
||||
assert "project(s)" in r.text
|
||||
assert "session(s)" in r.text
|
||||
assert r.status_code == 201
|
||||
payload = r.json()
|
||||
assert payload["replies"][0]["meta"]["kind"] == "nl_preview"
|
||||
assert "project(s)" in payload["replies"][1]["body"]
|
||||
assert "session(s)" in payload["replies"][1]["body"]
|
||||
|
|
|
|||
|
|
@ -87,11 +87,18 @@ def _collect_until(resp, marker: str, timeout: float = 3.0) -> str:
|
|||
|
||||
|
||||
def test_stream_yields_existing_backlog(client: TestClient) -> None:
|
||||
"""Initial flush: messages already past after_rowid arrive immediately."""
|
||||
client.post(
|
||||
"""Initial flush: rowids already past after_rowid arrive immediately.
|
||||
|
||||
Post-R6 the SSE payload is `{"new_rowids": [...]}` JSON, not HTML.
|
||||
The React client uses the event as a wake-up signal and refetches via
|
||||
`GET /api/v1/chat`.
|
||||
"""
|
||||
r = client.post(
|
||||
"/api/v1/chat",
|
||||
json={"scope": "orchestrator", "scope_ref": None, "body": "hello-backlog"},
|
||||
)
|
||||
user_rowid = r.json()["user_message"]["rowid"]
|
||||
marker = f"{user_rowid}"
|
||||
with client.stream(
|
||||
"GET",
|
||||
"/chat/stream",
|
||||
|
|
@ -101,9 +108,10 @@ def test_stream_yields_existing_backlog(client: TestClient) -> None:
|
|||
},
|
||||
) as resp:
|
||||
assert resp.status_code == 200
|
||||
text = _collect_until(resp, "hello-backlog", timeout=2.0)
|
||||
text = _collect_until(resp, marker, timeout=2.0)
|
||||
assert "event: chat" in text
|
||||
assert "hello-backlog" in text
|
||||
assert "new_rowids" in text
|
||||
assert marker in text
|
||||
|
||||
|
||||
def test_stream_pushes_new_message(client: TestClient) -> None:
|
||||
|
|
@ -115,16 +123,18 @@ def test_stream_pushes_new_message(client: TestClient) -> None:
|
|||
)
|
||||
baseline = r0.json()["user_message"]["rowid"]
|
||||
|
||||
# Background poster: fires a message a moment after we start streaming.
|
||||
target_rowid: list[int] = []
|
||||
|
||||
def post_later() -> None:
|
||||
time.sleep(0.3)
|
||||
client.post(
|
||||
r = client.post(
|
||||
"/api/v1/chat",
|
||||
json={
|
||||
"scope": "orchestrator", "scope_ref": None,
|
||||
"body": "live-update-marker",
|
||||
},
|
||||
)
|
||||
target_rowid.append(r.json()["user_message"]["rowid"])
|
||||
|
||||
poster = threading.Thread(target=post_later, daemon=True)
|
||||
poster.start()
|
||||
|
|
@ -138,8 +148,10 @@ def test_stream_pushes_new_message(client: TestClient) -> None:
|
|||
},
|
||||
) as resp:
|
||||
assert resp.status_code == 200
|
||||
text = _collect_until(resp, "live-update-marker", timeout=4.0)
|
||||
poster.join(timeout=2.0)
|
||||
assert target_rowid, "background poster failed to deliver"
|
||||
text = _collect_until(resp, str(target_rowid[0]), timeout=4.0)
|
||||
|
||||
poster.join(timeout=1.0)
|
||||
assert "live-update-marker" in text
|
||||
assert "event: chat" in text
|
||||
assert "new_rowids" in text
|
||||
assert str(target_rowid[0]) in text
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue