from __future__ import annotations import base64 import types import pytest import ariadne.k8s.client as k8s_client class DummyResponse: def __init__(self, payload): self._payload = payload def raise_for_status(self): return None def json(self): return self._payload class DummyClient: def __init__(self, *args, **kwargs): self.calls = [] self.payload = {"ok": True} def request(self, method, url, json=None): self.calls.append((method, url, json)) return DummyResponse(self.payload) def __enter__(self): return self def __exit__(self, exc_type, exc, tb): return False def test_get_json_builds_url(monkeypatch) -> None: dummy_settings = types.SimpleNamespace(k8s_api_timeout_sec=5.0) monkeypatch.setattr(k8s_client, "settings", dummy_settings) monkeypatch.setattr(k8s_client, "_read_service_account", lambda: ("token", "/tmp/ca")) client = DummyClient() monkeypatch.setattr(k8s_client.httpx, "Client", lambda *args, **kwargs: client) result = k8s_client.get_json("/api/test") assert result == {"ok": True} assert client.calls[0][1].endswith("/api/test") def test_post_json_rejects_non_dict(monkeypatch) -> None: dummy_settings = types.SimpleNamespace(k8s_api_timeout_sec=5.0) monkeypatch.setattr(k8s_client, "settings", dummy_settings) monkeypatch.setattr(k8s_client, "_read_service_account", lambda: ("token", "/tmp/ca")) client = DummyClient() client.payload = ["bad"] monkeypatch.setattr(k8s_client.httpx, "Client", lambda *args, **kwargs: client) with pytest.raises(RuntimeError): k8s_client.post_json("/api/test", {"payload": "ok"}) def test_post_json_success(monkeypatch) -> None: dummy_settings = types.SimpleNamespace(k8s_api_timeout_sec=5.0) monkeypatch.setattr(k8s_client, "settings", dummy_settings) monkeypatch.setattr(k8s_client, "_read_service_account", lambda: ("token", "/tmp/ca")) client = DummyClient() monkeypatch.setattr(k8s_client.httpx, "Client", lambda *args, **kwargs: client) result = k8s_client.post_json("/api/test", {"payload": "ok"}) assert result == {"ok": True} def test_get_json_rejects_non_dict(monkeypatch) -> None: dummy_settings = types.SimpleNamespace(k8s_api_timeout_sec=5.0) monkeypatch.setattr(k8s_client, "settings", dummy_settings) monkeypatch.setattr(k8s_client, "_read_service_account", lambda: ("token", "/tmp/ca")) client = DummyClient() client.payload = ["bad"] monkeypatch.setattr(k8s_client.httpx, "Client", lambda *args, **kwargs: client) with pytest.raises(RuntimeError): k8s_client.get_json("/api/test") def test_delete_json_success(monkeypatch) -> None: dummy_settings = types.SimpleNamespace(k8s_api_timeout_sec=5.0) monkeypatch.setattr(k8s_client, "settings", dummy_settings) monkeypatch.setattr(k8s_client, "_read_service_account", lambda: ("token", "/tmp/ca")) client = DummyClient() monkeypatch.setattr(k8s_client.httpx, "Client", lambda *args, **kwargs: client) result = k8s_client.delete_json("/api/test") assert result == {"ok": True} def test_delete_json_rejects_non_dict(monkeypatch) -> None: dummy_settings = types.SimpleNamespace(k8s_api_timeout_sec=5.0) monkeypatch.setattr(k8s_client, "settings", dummy_settings) monkeypatch.setattr(k8s_client, "_read_service_account", lambda: ("token", "/tmp/ca")) client = DummyClient() client.payload = ["bad"] monkeypatch.setattr(k8s_client.httpx, "Client", lambda *args, **kwargs: client) with pytest.raises(RuntimeError): k8s_client.delete_json("/api/test") def test_read_service_account(monkeypatch, tmp_path) -> None: sa_dir = tmp_path / "sa" sa_dir.mkdir() (sa_dir / "token").write_text("token123") (sa_dir / "ca.crt").write_text("ca") monkeypatch.setattr(k8s_client, "_SA_PATH", sa_dir) token, ca_path = k8s_client._read_service_account() assert token == "token123" assert ca_path.endswith("ca.crt") def test_read_service_account_missing_files(monkeypatch, tmp_path) -> None: sa_dir = tmp_path / "sa" sa_dir.mkdir() monkeypatch.setattr(k8s_client, "_SA_PATH", sa_dir) with pytest.raises(RuntimeError): k8s_client._read_service_account() def test_read_service_account_empty_token(monkeypatch, tmp_path) -> None: sa_dir = tmp_path / "sa" sa_dir.mkdir() (sa_dir / "token").write_text("") (sa_dir / "ca.crt").write_text("ca") monkeypatch.setattr(k8s_client, "_SA_PATH", sa_dir) with pytest.raises(RuntimeError): k8s_client._read_service_account() def test_get_secret_value_decodes(monkeypatch) -> None: secret = base64.b64encode(b"secret").decode() monkeypatch.setattr(k8s_client, "get_json", lambda *args, **kwargs: {"data": {"key": secret}}) assert k8s_client.get_secret_value("ns", "name", "key") == "secret" def test_get_secret_value_missing(monkeypatch) -> None: monkeypatch.setattr(k8s_client, "get_json", lambda *args, **kwargs: {"data": {}}) with pytest.raises(RuntimeError): k8s_client.get_secret_value("ns", "name", "key") def test_get_secret_value_decode_error(monkeypatch) -> None: monkeypatch.setattr(k8s_client, "get_json", lambda *args, **kwargs: {"data": {"key": "bad"}}) monkeypatch.setattr(k8s_client.base64, "b64decode", lambda *_args, **_kwargs: (_ for _ in ()).throw(ValueError("bad"))) with pytest.raises(RuntimeError): k8s_client.get_secret_value("ns", "name", "key") def test_get_secret_value_empty_decoded(monkeypatch) -> None: raw = base64.b64encode(b" ").decode() monkeypatch.setattr(k8s_client, "get_json", lambda *args, **kwargs: {"data": {"key": raw}}) with pytest.raises(RuntimeError): k8s_client.get_secret_value("ns", "name", "key")