107 lines
3.9 KiB
Python
107 lines
3.9 KiB
Python
"""Contract tests for native Claude subscription model discovery."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
SCRIPTS = Path(__file__).parents[2] / "services/hermes/scripts"
|
|
sys.path.insert(0, str(SCRIPTS))
|
|
discovery = importlib.import_module("claude_model_discovery")
|
|
|
|
|
|
def _initialize_event(*, provider: str = "firstParty") -> str:
|
|
"""Build representative non-secret CLI initialization output."""
|
|
return json.dumps(
|
|
{
|
|
"type": "control_response",
|
|
"response": {
|
|
"subtype": "success",
|
|
"request_id": "catalog",
|
|
"response": {
|
|
"account": {
|
|
"apiProvider": provider,
|
|
"email": "discard-me@example.test",
|
|
},
|
|
"models": [
|
|
{
|
|
"value": "opus",
|
|
"resolvedModel": "claude-opus-5",
|
|
"displayName": "Opus",
|
|
"description": "Most capable",
|
|
"supportsEffort": True,
|
|
"supportedEffortLevels": [
|
|
"low",
|
|
"high",
|
|
"xhigh",
|
|
"unknown",
|
|
],
|
|
"supportsAdaptiveThinking": True,
|
|
},
|
|
{
|
|
"value": "haiku",
|
|
"resolvedModel": "claude-haiku-4-5-20251001",
|
|
"displayName": "Haiku",
|
|
"description": "Fast",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
}
|
|
)
|
|
|
|
|
|
def test_initialize_parses_live_subscription_models_without_account_data():
|
|
"""Literal aliases and the CLI-advertised effort set survive discovery."""
|
|
result = discovery._parse_initialize_output(_initialize_event())
|
|
|
|
assert result.live is True
|
|
assert result.connected is True
|
|
assert result.error_code is None
|
|
assert [model.value for model in result.models] == ["opus", "haiku"]
|
|
assert result.models[0].resolved_model == "claude-opus-5"
|
|
assert result.models[0].supported_effort_levels == ("low", "high", "xhigh")
|
|
assert "email" not in result.models[0].as_dict()
|
|
rendered_models = json.dumps([model.as_dict() for model in result.models])
|
|
assert "discard-me@example.test" not in rendered_models
|
|
|
|
|
|
def test_initialize_rejects_non_subscription_catalogs():
|
|
"""An API-key or third-party account cannot become a subscription route."""
|
|
result = discovery._parse_initialize_output(_initialize_event(provider="apiKey"))
|
|
|
|
assert result.live is False
|
|
assert result.connected is False
|
|
assert result.error_code == "not-first-party"
|
|
|
|
|
|
def test_discovery_never_uses_api_key_environment(monkeypatch):
|
|
"""The native call inherits OAuth config but strips metered API-key variables."""
|
|
observed: dict[str, object] = {}
|
|
|
|
def fake_run(command, environment, timeout_seconds):
|
|
observed["command"] = command
|
|
observed["environment"] = environment
|
|
observed["timeout"] = timeout_seconds
|
|
return _initialize_event(), None
|
|
|
|
monkeypatch.setattr(discovery, "_run_initialize", fake_run)
|
|
result = discovery.discover_claude_subscription_models(
|
|
claude_bin="/native/claude",
|
|
timeout_seconds=7,
|
|
environment={
|
|
"CLAUDE_CONFIG_DIR": "/mounted/claude",
|
|
"ANTHROPIC_API_KEY": "secret",
|
|
"CLAUDE_API_KEY": "secret",
|
|
},
|
|
)
|
|
|
|
assert result.live is True
|
|
assert observed["environment"] == {"CLAUDE_CONFIG_DIR": "/mounted/claude"}
|
|
assert observed["command"][:2] == ["/native/claude", "--input-format"]
|
|
assert "--safe-mode" in observed["command"]
|
|
assert "" in observed["command"]
|