"""Tests for the Intervals.icu credential validator (mocked HTTP).""" import httpx import pytest from intervalsicu_mcp_ui import intervals BASE = "https://intervals.icu/api/v1" def _mock(monkeypatch, handler): transport = httpx.MockTransport(handler) real_init = httpx.AsyncClient.__init__ def patched_init(self, *args, **kwargs): kwargs["transport"] = transport real_init(self, *args, **kwargs) monkeypatch.setattr(httpx.AsyncClient, "__init__", patched_init) async def test_valid_credentials(monkeypatch): _mock(monkeypatch, lambda req: httpx.Response(200, json={"name": "Chris"})) ok, msg = await intervals.validate_credentials(BASE, "i123", "key") assert ok is True and "Chris" in msg async def test_bad_key(monkeypatch): _mock(monkeypatch, lambda req: httpx.Response(401)) ok, msg = await intervals.validate_credentials(BASE, "i123", "key") assert ok is False and "Invalid API key" in msg async def test_not_found(monkeypatch): _mock(monkeypatch, lambda req: httpx.Response(404)) ok, msg = await intervals.validate_credentials(BASE, "i999", "key") assert ok is False and "not found" in msg async def test_other_status(monkeypatch): _mock(monkeypatch, lambda req: httpx.Response(500)) ok, msg = await intervals.validate_credentials(BASE, "i123", "key") assert ok is False and "500" in msg async def test_network_error(monkeypatch): def boom(req): raise httpx.ConnectError("refused") _mock(monkeypatch, boom) ok, msg = await intervals.validate_credentials(BASE, "i123", "key") assert ok is False and "Could not reach" in msg @pytest.mark.parametrize("aid,key", [("", "k"), ("i1", ""), (" ", "k")]) async def test_missing_inputs(aid, key): ok, msg = await intervals.validate_credentials(BASE, aid, key) assert ok is False and "required" in msg