Spaces:
Running
Running
| """Smoke tests for the BugLens backend endpoints.""" | |
| import base64 | |
| from fastapi.testclient import TestClient | |
| from app import server | |
| from buglens import backend | |
| client = TestClient(server) | |
| _PNG_B64 = base64.b64encode(b"fake-png-bytes").decode("ascii") | |
| def test_index_serves_custom_frontend() -> None: | |
| resp = client.get("/") | |
| assert resp.status_code == 200 | |
| assert "text/html" in resp.headers["content-type"] | |
| assert "BugLens" in resp.text | |
| def test_examples_endpoint_lists_four() -> None: | |
| resp = client.get("/api/examples") | |
| assert resp.status_code == 200 | |
| assert len(resp.json()) == 4 | |
| def test_analyze_returns_frontend_payload() -> None: | |
| resp = client.get("/api/analyze", params={"id": "payment"}) | |
| assert resp.status_code == 200 | |
| body = resp.json() | |
| assert body["severityWhy"] | |
| assert body["missing"][0]["q"] | |
| assert body["tests"][0]["then"] | |
| assert body["edges"][0]["d"] | |
| def test_example_analyze_still_works_in_modal_mode(monkeypatch) -> None: | |
| monkeypatch.setenv("BUGLENS_BACKEND", "modal") | |
| monkeypatch.setenv("BUGLENS_MODAL_ENDPOINT", "https://x.modal.run") | |
| resp = client.get("/api/analyze", params={"id": "payment"}) | |
| assert resp.status_code == 200 | |
| assert resp.json()["title"] | |
| def test_analyze_unknown_and_missing_id_404() -> None: | |
| assert client.get("/api/analyze", params={"id": "nope"}).status_code == 404 | |
| assert client.get("/api/analyze").status_code == 404 | |
| def test_export_formats() -> None: | |
| csv_resp = client.get("/api/export/csv", params={"id": "payment"}) | |
| assert csv_resp.status_code == 200 | |
| assert csv_resp.json()["text"].startswith("id,title,given,when,then") | |
| assert client.get("/api/export/jira", params={"id": "payment"}).status_code == 200 | |
| assert client.get("/api/export/bogus", params={"id": "payment"}).status_code == 404 | |
| def test_upload_in_mock_mode_returns_501(monkeypatch) -> None: | |
| monkeypatch.delenv("BUGLENS_BACKEND", raising=False) # default is mock | |
| resp = client.post("/api/analyze", json={"image_b64": _PNG_B64, "note": "hi"}) | |
| assert resp.status_code == 501 | |
| def test_upload_in_modal_mode_forwards_to_backend(monkeypatch) -> None: | |
| monkeypatch.setenv("BUGLENS_BACKEND", "modal") | |
| monkeypatch.setenv("BUGLENS_MODAL_ENDPOINT", "https://x.modal.run") | |
| seen = {} | |
| def fake_analyze(endpoint, image_bytes, note): | |
| seen["endpoint"] = endpoint | |
| seen["bytes"] = image_bytes | |
| seen["note"] = note | |
| return {"title": "live report"} | |
| monkeypatch.setattr(backend, "analyze_via_modal", fake_analyze) | |
| resp = client.post("/api/analyze", json={"image_b64": _PNG_B64, "note": "broken"}) | |
| assert resp.status_code == 200 | |
| assert resp.json() == {"title": "live report"} | |
| assert seen["endpoint"] == "https://x.modal.run" | |
| assert seen["bytes"] == b"fake-png-bytes" | |
| assert seen["note"] == "broken" | |
| def test_upload_with_invalid_base64_returns_400(monkeypatch) -> None: | |
| monkeypatch.setenv("BUGLENS_BACKEND", "modal") | |
| monkeypatch.setenv("BUGLENS_MODAL_ENDPOINT", "https://x.modal.run") | |
| resp = client.post("/api/analyze", json={"image_b64": "!!!not base64!!!", "note": ""}) | |
| assert resp.status_code == 400 | |
| def test_upload_backend_error_returns_502(monkeypatch) -> None: | |
| monkeypatch.setenv("BUGLENS_BACKEND", "modal") | |
| monkeypatch.setenv("BUGLENS_MODAL_ENDPOINT", "https://x.modal.run") | |
| def boom(*a, **k): | |
| raise backend.BackendError("down") | |
| monkeypatch.setattr(backend, "analyze_via_modal", boom) | |
| resp = client.post("/api/analyze", json={"image_b64": _PNG_B64}) | |
| assert resp.status_code == 502 | |
| def test_static_assets_served() -> None: | |
| # The jsx modules referenced by the HTML must be reachable under /static. | |
| resp = client.get("/static/buglens-data.jsx") | |
| assert resp.status_code == 200 | |
| assert "text/babel" in resp.headers["content-type"] | |
| assert "EXAMPLES" in resp.text | |