"""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"]