"""Tests for configuration loader module.""" import os from pathlib import Path import pytest from pydantic import ValidationError from gitea_mcp_remote.config import GiteaSettings, load_settings class TestGiteaSettings: """Test GiteaSettings configuration class.""" def test_required_fields(self): """Test that required fields are enforced.""" with pytest.raises(ValidationError) as exc_info: GiteaSettings() errors = exc_info.value.errors() # Note: gitea_repo is optional (for PMO mode) required_fields = {"gitea_url", "gitea_token", "gitea_owner"} error_fields = {error["loc"][0] for error in errors} assert required_fields.issubset(error_fields) def test_valid_configuration(self): """Test valid configuration creation.""" settings = GiteaSettings( gitea_url="https://gitea.example.com", gitea_token="test_token", gitea_owner="test_owner", gitea_repo="test_repo", ) assert settings.gitea_url == "https://gitea.example.com" assert settings.gitea_token == "test_token" assert settings.gitea_owner == "test_owner" assert settings.gitea_repo == "test_repo" assert settings.http_host == "127.0.0.1" assert settings.http_port == 8000 assert settings.auth_token is None def test_gitea_url_validation(self): """Test Gitea URL validation.""" # Valid URLs valid_urls = [ "http://gitea.local", "https://gitea.example.com", "http://192.168.1.1:3000", ] for url in valid_urls: settings = GiteaSettings( gitea_url=url, gitea_token="token", gitea_owner="owner", gitea_repo="repo", ) assert settings.gitea_url == url.rstrip("/") # Invalid URL (no protocol) with pytest.raises(ValidationError) as exc_info: GiteaSettings( gitea_url="gitea.example.com", gitea_token="token", gitea_owner="owner", gitea_repo="repo", ) assert "must start with http://" in str(exc_info.value) def test_gitea_url_trailing_slash_removed(self): """Test that trailing slashes are removed from Gitea URL.""" settings = GiteaSettings( gitea_url="https://gitea.example.com/", gitea_token="token", gitea_owner="owner", gitea_repo="repo", ) assert settings.gitea_url == "https://gitea.example.com" def test_http_port_validation(self): """Test HTTP port validation.""" # Valid port settings = GiteaSettings( gitea_url="https://gitea.example.com", gitea_token="token", gitea_owner="owner", gitea_repo="repo", http_port=9000, ) assert settings.http_port == 9000 # Invalid port (too high) with pytest.raises(ValidationError): GiteaSettings( gitea_url="https://gitea.example.com", gitea_token="token", gitea_owner="owner", gitea_repo="repo", http_port=70000, ) # Invalid port (too low) with pytest.raises(ValidationError): GiteaSettings( gitea_url="https://gitea.example.com", gitea_token="token", gitea_owner="owner", gitea_repo="repo", http_port=0, ) def test_enabled_tools_list_parsing(self): """Test enabled_tools string parsing to list.""" settings = GiteaSettings( gitea_url="https://gitea.example.com", gitea_token="token", gitea_owner="owner", gitea_repo="repo", enabled_tools="tool1,tool2,tool3", ) assert settings.enabled_tools_list == ["tool1", "tool2", "tool3"] # Test with spaces settings = GiteaSettings( gitea_url="https://gitea.example.com", gitea_token="token", gitea_owner="owner", gitea_repo="repo", enabled_tools="tool1, tool2 , tool3", ) assert settings.enabled_tools_list == ["tool1", "tool2", "tool3"] # Test empty string settings = GiteaSettings( gitea_url="https://gitea.example.com", gitea_token="token", gitea_owner="owner", gitea_repo="repo", enabled_tools="", ) assert settings.enabled_tools_list is None def test_disabled_tools_list_parsing(self): """Test disabled_tools string parsing to list.""" settings = GiteaSettings( gitea_url="https://gitea.example.com", gitea_token="token", gitea_owner="owner", gitea_repo="repo", disabled_tools="tool1,tool2", ) assert settings.disabled_tools_list == ["tool1", "tool2"] def test_get_gitea_mcp_env(self): """Test environment variable generation for wrapped MCP server.""" settings = GiteaSettings( gitea_url="https://gitea.example.com", gitea_token="test_token", gitea_owner="test_owner", gitea_repo="test_repo", ) env = settings.get_gitea_mcp_env() assert env["GITEA_BASE_URL"] == "https://gitea.example.com" assert env["GITEA_API_TOKEN"] == "test_token" assert env["GITEA_DEFAULT_OWNER"] == "test_owner" assert env["GITEA_DEFAULT_REPO"] == "test_repo" class TestLoadSettings: """Test load_settings factory function.""" def test_load_from_env_file(self, tmp_path): """Test loading settings from a .env file.""" env_file = tmp_path / ".env" env_file.write_text( """ GITEA_URL=https://gitea.test.com GITEA_TOKEN=test_token_123 GITEA_OWNER=test_owner GITEA_REPO=test_repo HTTP_PORT=9000 """ ) settings = load_settings(env_file) assert settings.gitea_url == "https://gitea.test.com" assert settings.gitea_token == "test_token_123" assert settings.gitea_owner == "test_owner" assert settings.gitea_repo == "test_repo" assert settings.http_port == 9000 def test_load_from_environment(self, monkeypatch): """Test loading settings from environment variables.""" monkeypatch.setenv("GITEA_URL", "https://env.gitea.com") monkeypatch.setenv("GITEA_TOKEN", "env_token") monkeypatch.setenv("GITEA_OWNER", "env_owner") monkeypatch.setenv("GITEA_REPO", "env_repo") monkeypatch.setenv("HTTP_PORT", "8080") # Mock _env_file to prevent loading actual .env settings = GiteaSettings() assert settings.gitea_url == "https://env.gitea.com" assert settings.gitea_token == "env_token" assert settings.gitea_owner == "env_owner" assert settings.gitea_repo == "env_repo" assert settings.http_port == 8080