From 85c6056c877354a0adf97bcc1ca3d848cf9112eb Mon Sep 17 00:00:00 2001 From: Wes Huber Date: Mon, 8 Jun 2026 15:07:29 -0700 Subject: [PATCH] test(models): add regression coverage for Z.AI coding endpoint probing (#2244) Add focused tests for the z.ai/api/coding path override: - _match_provider_curated: 5 tests verifying coding vs base key - _probe_endpoint: 3 tests verifying model preservation, curated append on partial response, and base-zai exclusion Rebased onto dev per reviewer request. Fixes #2230 Co-authored-by: Claude Opus 4.6 (1M context) Co-authored-by: Alexandre Teixeira <111787685+alteixeira20@users.noreply.github.com> --- tests/test_model_routes.py | 81 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/tests/test_model_routes.py b/tests/test_model_routes.py index f0f36ee7f..02f2ea071 100644 --- a/tests/test_model_routes.py +++ b/tests/test_model_routes.py @@ -193,6 +193,87 @@ class TestMatchProviderCurated: def test_none_url_safe(self): assert _match_provider_curated(None, "openai") == "openai" + # ── Z.AI coding plan path override (#2230) ── + + def test_zai_coding_path_returns_coding_curated(self): + """z.ai/api/coding must return 'zai-coding', not the base 'zai' list.""" + assert _match_provider_curated("https://z.ai/api/coding", "openai") == "zai-coding" + + def test_zai_coding_path_differs_from_base_zai(self): + """The coding plan and the base plan must resolve to different curated keys.""" + base = _match_provider_curated("https://z.ai/v1", "openai") + coding = _match_provider_curated("https://z.ai/api/coding", "openai") + assert base == "zai" + assert coding == "zai-coding" + assert base != coding + + def test_zai_coding_with_trailing_slash(self): + assert _match_provider_curated("https://z.ai/api/coding/", "openai") == "zai-coding" + + def test_zai_base_does_not_match_coding(self): + """z.ai without the /api/coding path must NOT return 'zai-coding'.""" + assert _match_provider_curated("https://z.ai/v1", "openai") != "zai-coding" + + def test_zai_coding_none_provider(self): + """Path-based override fires even when provider is None.""" + assert _match_provider_curated("https://z.ai/api/coding", None) == "zai-coding" + + +# ── _probe_endpoint: Z.AI coding plan (#2230) ── + +class TestProbeZaiCoding: + """Regression coverage for the Z.AI coding endpoint probing path.""" + + def _patch(self, monkeypatch): + monkeypatch.setattr(endpoint_resolver, "resolve_url", lambda url: url, raising=False) + monkeypatch.setattr(model_routes, "_normalize_base", lambda url: url.rstrip("/")) + + def test_probe_preserves_models_from_server(self, monkeypatch): + """Models returned by /models are kept in the result.""" + self._patch(monkeypatch) + server_models = [{"id": "glm-5.1"}, {"id": "custom-finetune"}] + + def fake_get(url, headers=None, timeout=None, verify=None, **kwargs): + return httpx.Response(200, json={"data": server_models}, + request=httpx.Request("GET", url)) + + monkeypatch.setattr(model_routes.httpx, "get", fake_get) + result = _probe_endpoint("https://z.ai/api/coding", "key") + assert "glm-5.1" in result + assert "custom-finetune" in result + + def test_probe_appends_curated_on_partial_response(self, monkeypatch): + """When /models returns a partial list, curated-only models are appended.""" + self._patch(monkeypatch) + # Server only returns one model; the curated list has more + server_models = [{"id": "glm-5.1"}] + + def fake_get(url, headers=None, timeout=None, verify=None, **kwargs): + return httpx.Response(200, json={"data": server_models}, + request=httpx.Request("GET", url)) + + monkeypatch.setattr(model_routes.httpx, "get", fake_get) + result = _probe_endpoint("https://z.ai/api/coding", "key") + assert "glm-5.1" in result + # At least one curated model should be appended + coding_curated = _PROVIDER_CURATED.get("zai-coding", []) + appended = [m for m in coding_curated if m in result and m != "glm-5.1"] + assert len(appended) > 0, "curated-only models should be appended" + + def test_probe_does_not_use_base_zai_curated(self, monkeypatch): + """The coding endpoint must use zai-coding, NOT the base zai list.""" + self._patch(monkeypatch) + + def fake_get(url, headers=None, timeout=None, verify=None, **kwargs): + return httpx.Response(200, json={"data": [{"id": "glm-5.1"}]}, + request=httpx.Request("GET", url)) + + monkeypatch.setattr(model_routes.httpx, "get", fake_get) + result = _probe_endpoint("https://z.ai/api/coding", "key") + base_only = set(_PROVIDER_CURATED.get("zai", [])) - set(_PROVIDER_CURATED.get("zai-coding", [])) + for model in base_only: + assert model not in result, f"base-zai-only model {model} should not appear for coding endpoint" + # ── _curate_models ──