mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-10-10 15:03:20 +02:00
102 lines
3.3 KiB
Python
102 lines
3.3 KiB
Python
"""Regression tests for GH-5317: CLI config files are UTF-8 regardless of locale."""
|
|
|
|
import builtins
|
|
import io
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from fastmcp.cli.client import _resolve_json_spec
|
|
from fastmcp.cli.install.claude_desktop import install_claude_desktop
|
|
from fastmcp.cli.install.shared import process_common_args
|
|
from fastmcp.cli.run import create_mcp_config_server
|
|
from fastmcp.utilities.cli import load_and_merge_config
|
|
|
|
ARABIC_PATH = "C:\\Users\\فاطمة\\notes.js"
|
|
GREETING = "Olá José"
|
|
|
|
|
|
@pytest.fixture
|
|
def cp1252_locale(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
"""Make text reads without an explicit encoding decode as cp1252, as they
|
|
do on Windows with a non-UTF-8 system code page."""
|
|
real_open = builtins.open
|
|
|
|
def locale_open(
|
|
file: Any,
|
|
mode: str = "r",
|
|
buffering: int = -1,
|
|
encoding: str | None = None,
|
|
*args: Any,
|
|
**kwargs: Any,
|
|
) -> Any:
|
|
if "b" not in mode and encoding in (None, "locale"):
|
|
encoding = "cp1252"
|
|
return real_open(file, mode, buffering, encoding, *args, **kwargs)
|
|
|
|
def text_encoding(encoding: str | None, stacklevel: int = 2) -> str:
|
|
return encoding or "cp1252"
|
|
|
|
monkeypatch.setattr(builtins, "open", locale_open)
|
|
monkeypatch.setattr(io, "text_encoding", text_encoding)
|
|
|
|
|
|
def _write_utf8_json(path: Path, data: dict[str, Any]) -> None:
|
|
path.write_bytes(json.dumps(data, ensure_ascii=False).encode("utf-8"))
|
|
|
|
|
|
def _mcp_config() -> dict[str, Any]:
|
|
return {
|
|
"mcpServers": {
|
|
"demo": {
|
|
"command": "node",
|
|
"args": [ARABIC_PATH],
|
|
"env": {"GREETING": GREETING},
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.mark.usefixtures("cp1252_locale")
|
|
class TestConfigFilesReadAsUtf8:
|
|
def test_client_resolves_mcp_config(self, tmp_path: Path):
|
|
path = tmp_path / "mcp.json"
|
|
_write_utf8_json(path, _mcp_config())
|
|
|
|
assert _resolve_json_spec(path) == _mcp_config()
|
|
|
|
def test_run_creates_mcp_config_server(self, tmp_path: Path):
|
|
path = tmp_path / "mcp.json"
|
|
_write_utf8_json(path, _mcp_config())
|
|
|
|
create_mcp_config_server(path)
|
|
|
|
def test_load_and_merge_fastmcp_json(self, tmp_path: Path):
|
|
path = tmp_path / "fastmcp.json"
|
|
_write_utf8_json(path, {"source": {"path": ARABIC_PATH}})
|
|
|
|
config, _ = load_and_merge_config(str(path))
|
|
|
|
assert config.source.path == ARABIC_PATH
|
|
|
|
async def test_install_reads_fastmcp_json(self, tmp_path: Path):
|
|
path = tmp_path / "fastmcp.json"
|
|
(tmp_path / "فاطمة.py").write_text("", encoding="utf-8")
|
|
_write_utf8_json(path, {"source": {"path": "فاطمة.py"}})
|
|
|
|
file, *_ = await process_common_args(str(path), None, None, None, None)
|
|
|
|
assert file == tmp_path / "فاطمة.py"
|
|
|
|
def test_install_claude_desktop_merges_existing_config(self, tmp_path: Path):
|
|
config_file = tmp_path / "claude_desktop_config.json"
|
|
_write_utf8_json(config_file, _mcp_config())
|
|
|
|
assert install_claude_desktop(
|
|
tmp_path / "server.py", None, "demo", config_path=tmp_path
|
|
)
|
|
|
|
config = json.loads(config_file.read_bytes().decode("utf-8"))
|
|
assert config["mcpServers"]["demo"]["env"] == {"GREETING": GREETING}
|