Spaces:
Sleeping
Sleeping
| """Endpoint robustness tests (CLAUDE.md §3, §9). | |
| Health is always 200; /chat degrades to a valid fallback on timeout or error and | |
| never violates the contract. The agent is stubbed so these are fast and offline. | |
| """ | |
| from __future__ import annotations | |
| import time | |
| import app.main as main | |
| from app.schemas import ChatResponse | |
| from fastapi.testclient import TestClient | |
| BODY = {"messages": [{"role": "user", "content": "Hiring a Java dev"}]} | |
| def test_health_always_ok(): | |
| client = TestClient(main.app) | |
| r = client.get("/health") | |
| assert r.status_code == 200 and r.json() == {"status": "ok"} | |
| def test_chat_ok_path(monkeypatch): | |
| monkeypatch.setattr( | |
| main, "handle", | |
| lambda msgs: ChatResponse(reply="ok", recommendations=[], end_of_conversation=False), | |
| ) | |
| r = TestClient(main.app).post("/chat", json=BODY) | |
| assert r.status_code == 200 | |
| assert set(r.json()) == {"reply", "recommendations", "end_of_conversation"} | |
| def test_chat_timeout_returns_fallback(monkeypatch): | |
| def slow(msgs): | |
| time.sleep(2) | |
| return ChatResponse(reply="late", recommendations=[]) | |
| monkeypatch.setattr(main, "handle", slow) | |
| monkeypatch.setattr(main, "_TIMEOUT_S", 0.2) # force the guard to trip fast | |
| r = TestClient(main.app).post("/chat", json=BODY) | |
| assert r.status_code == 200 | |
| body = r.json() | |
| assert body["recommendations"] == [] # SAFE_FALLBACK | |
| assert body["reply"].strip() | |
| def test_chat_exception_returns_fallback(monkeypatch): | |
| def boom(msgs): | |
| raise RuntimeError("kaboom") | |
| monkeypatch.setattr(main, "handle", boom) | |
| r = TestClient(main.app).post("/chat", json=BODY) | |
| assert r.status_code == 200 | |
| assert r.json()["recommendations"] == [] | |
| def test_chat_rejects_malformed_body(): | |
| client = TestClient(main.app) | |
| assert client.post("/chat", json={"messages": []}).status_code == 422 | |
| assert client.post("/chat", json={"nope": 1}).status_code == 422 | |
| def test_warmup_callable_is_safe(): | |
| # Should never raise even if artifacts are odd; sets ready flag on success. | |
| main._warm["ready"] = False | |
| main._warmup() | |
| # Either it warmed (ready True) or it logged and moved on; never raises. | |
| assert main._warm["ready"] in (True, False) | |