unity-mcp/Server/tests/integration/test_auth_config_startup.py

115 lines
4.0 KiB
Python

"""Tests for auth configuration validation and startup routes."""
import json
import sys
from unittest.mock import MagicMock
import pytest
from core.config import config
from starlette.requests import Request
from starlette.responses import JSONResponse
@pytest.fixture(autouse=True)
def _restore_config(monkeypatch):
"""Prevent main() side effects on the global config from leaking to other tests."""
monkeypatch.setattr(config, "http_remote_hosted", config.http_remote_hosted)
monkeypatch.setattr(config, "api_key_validation_url", config.api_key_validation_url)
monkeypatch.setattr(config, "api_key_login_url", config.api_key_login_url)
monkeypatch.setattr(config, "api_key_cache_ttl", config.api_key_cache_ttl)
monkeypatch.setattr(config, "api_key_service_token_header", config.api_key_service_token_header)
monkeypatch.setattr(config, "api_key_service_token", config.api_key_service_token)
class TestStartupConfigValidation:
def test_remote_hosted_flag_without_validation_url_exits(self, monkeypatch):
"""--http-remote-hosted without --api-key-validation-url should SystemExit(1)."""
monkeypatch.setattr(
sys,
"argv",
[
"main",
"--transport", "http",
"--http-remote-hosted",
# Deliberately omit --api-key-validation-url
],
)
monkeypatch.delenv("UNITY_MCP_API_KEY_VALIDATION_URL", raising=False)
monkeypatch.delenv("UNITY_MCP_HTTP_REMOTE_HOSTED", raising=False)
from main import main
with pytest.raises(SystemExit) as exc_info:
main()
assert exc_info.value.code == 1
def test_remote_hosted_env_var_without_validation_url_exits(self, monkeypatch):
"""UNITY_MCP_HTTP_REMOTE_HOSTED=true without validation URL should SystemExit(1)."""
monkeypatch.setattr(
sys,
"argv",
[
"main",
"--transport", "http",
# No --http-remote-hosted flag
],
)
monkeypatch.setenv("UNITY_MCP_HTTP_REMOTE_HOSTED", "true")
monkeypatch.delenv("UNITY_MCP_API_KEY_VALIDATION_URL", raising=False)
from main import main
with pytest.raises(SystemExit) as exc_info:
main()
assert exc_info.value.code == 1
class TestLoginUrlEndpoint:
"""Test the /api/auth/login-url route handler logic.
These tests replicate the handler inline to avoid full MCP server construction.
The logic mirrors main.py's auth_login_url route exactly.
"""
@staticmethod
async def _auth_login_url(_request):
"""Replicate the route handler from main.py."""
if not config.api_key_login_url:
return JSONResponse(
{
"success": False,
"error": "API key management not configured. Contact your server administrator.",
},
status_code=404,
)
return JSONResponse({
"success": True,
"login_url": config.api_key_login_url,
})
@pytest.mark.asyncio
async def test_login_url_returns_url_when_configured(self, monkeypatch):
monkeypatch.setattr(config, "api_key_login_url",
"https://app.example.com/keys")
response = await self._auth_login_url(MagicMock(spec=Request))
assert response.status_code == 200
body = json.loads(response.body.decode())
assert body["success"] is True
assert body["login_url"] == "https://app.example.com/keys"
@pytest.mark.asyncio
async def test_login_url_returns_404_when_not_configured(self, monkeypatch):
monkeypatch.setattr(config, "api_key_login_url", None)
response = await self._auth_login_url(MagicMock(spec=Request))
assert response.status_code == 404
body = json.loads(response.body.decode())
assert body["success"] is False
assert "not configured" in body["error"]