Spaces:
Paused
Paused
Download tests/test_api.py from Bit-Trading-Company/ASE-GLM: direct link, hf CLI and curl.
- Browser
- Download file 4.39 kB
-
https://huggingface.co/spaces/Bit-Trading-Company/ASE-GLM/resolve/main/tests/test_api.py
- Command line
-
hf download hf://spaces/Bit-Trading-Company/ASE-GLM/tests/test_api.py
-
curl -L -o test_api.py https://huggingface.co/spaces/Bit-Trading-Company/ASE-GLM/resolve/main/tests/test_api.py
4.39 kB
| """The HTTP surface, exercised with no network and no credentials.""" | |
| from __future__ import annotations | |
| import pytest | |
| from fastapi.testclient import TestClient | |
| from server import catalog | |
| from server.main import app | |
| def no_credentials(monkeypatch): | |
| for var in ("HF_TOKEN", "HUGGING_FACE_HUB_TOKEN", "SPACE_ID", | |
| "ASE_ALLOW_SPACE_CREDITS"): | |
| monkeypatch.delenv(var, raising=False) | |
| # The suite must never pick up the developer's real key.txt. | |
| monkeypatch.setenv("ASE_KEY_FILE", "/nonexistent/ase-glm-test-key") | |
| def client(): | |
| return TestClient(app) | |
| def test_health(client): | |
| assert client.get("/api/health").json()["ok"] is True | |
| def test_config_lists_the_models_and_the_billing_mode(client): | |
| body = client.get("/api/config").json() | |
| ids = [m["id"] for m in body["models"]] | |
| assert "zai-org/GLM-5.3" in ids | |
| assert body["defaultModel"] == catalog.DEFAULT_MODEL | |
| assert body["auth"]["billsViewer"] is False | |
| assert "token" not in body["auth"] | |
| def test_every_catalog_model_is_well_formed(): | |
| for m in catalog.MODELS: | |
| j = m.to_json() | |
| assert "/" in j["id"], "an id must be owner/name to route" | |
| assert j["label"] and j["vendor"] | |
| assert j["providers"], f"{j['id']} has no route" | |
| assert j["contextTokens"] is None or j["contextTokens"] > 0 | |
| def sse_events(response) -> list[tuple[str, str]]: | |
| out, name, data = [], "message", [] | |
| for line in response.text.split("\n"): | |
| if line.startswith("event:"): | |
| name = line[6:].strip() | |
| elif line.startswith("data:"): | |
| data.append(line[5:].lstrip(" ")) | |
| elif not line.strip() and data: | |
| out.append((name, "\n".join(data))) | |
| name, data = "message", [] | |
| if data: | |
| out.append((name, "\n".join(data))) | |
| return out | |
| def test_a_missing_credential_is_reported_in_the_stream_not_as_a_4xx(client): | |
| # The client renders errors into the transcript. A 4xx would show as a | |
| # transport failure somewhere the reader is not looking. | |
| r = client.post("/api/chat", json={ | |
| "model": "zai-org/GLM-5.3", | |
| "messages": [{"role": "user", "content": "hi"}], | |
| }) | |
| assert r.status_code == 200 | |
| events = sse_events(r) | |
| assert events[0][0] == "error" | |
| assert "credential" in events[0][1].lower() | |
| def test_an_unknown_model_is_refused_before_any_upstream_call(client): | |
| r = client.post("/api/chat", json={ | |
| "model": "../../etc/passwd", | |
| "messages": [{"role": "user", "content": "hi"}], | |
| }) | |
| assert sse_events(r)[0][0] == "error" | |
| assert "Unknown model" in sse_events(r)[0][1] | |
| def test_a_request_with_no_messages_is_refused(client, body): | |
| assert sse_events(client.post("/api/chat", json=body))[0][0] == "error" | |
| def test_model_insight_rejects_a_model_not_in_the_catalog(client): | |
| r = client.get("/api/model", params={"id": "evil/model"}) | |
| assert r.status_code == 400 | |
| def test_an_unknown_api_path_is_a_404_not_the_index_page(client): | |
| # The SPA catch-all matches anything the declared routes did not. If it | |
| # answers an /api path, a typo'd endpoint returns 200 full of HTML and the | |
| # client reports a JSON parse error a long way from the cause. | |
| r = client.get("/api/does-not-exist") | |
| assert r.status_code == 404 | |
| assert "<html" not in r.text.lower() | |
| def test_a_non_api_path_still_falls_through_to_the_app(client): | |
| # Only reachable once the bundle has been built; skip rather than fail in a | |
| # bare checkout, since CI builds it before the deploy either way. | |
| r = client.get("/some/client/route") | |
| assert r.status_code in (200, 404) | |
| def test_the_page_is_not_cached(client): | |
| """A cached index.html keeps pointing at the previous bundle. | |
| The assets are content-hashed and may cache forever; the page that names | |
| them may not, or a deploy is invisible until the browser feels like | |
| re-fetching — which reads as "the deploy did nothing". | |
| """ | |
| for path in ("/", "/anything"): | |
| r = client.get(path) | |
| if r.status_code != 200: | |
| continue | |
| assert "no-cache" in r.headers.get("cache-control", "") | |