Files
lda-wf/tests/wf_cli/test_config_migration.py
T
2026-06-15 22:37:59 +07:00

207 lines
5.3 KiB
Python

from __future__ import annotations
import json
from pathlib import Path
from typer.testing import CliRunner
from wf_cli.app import app
def test_wf_config_migrate_mcp_prints_neutral_config(tmp_path: Path) -> None:
legacy_path = tmp_path / "wf_mcp.config.json"
legacy_path.write_text(
"""
{
"store_root": ".wf_mcp_store",
"connections": [
{
"id": "everything.default",
"server": "everything",
"account": "default",
"metadata": {
"transport": "stdio",
"command": "uvx",
"args": ["mcp-server-everything"]
}
}
]
}
""",
encoding="utf-8",
)
result = CliRunner().invoke(app, ["config", "migrate-mcp", str(legacy_path)])
assert result.exit_code == 0, result.output
payload = json.loads(result.output)
assert payload["server"]["store"] == {
"kind": "filesystem",
"root": ".wf_mcp_store",
}
source = payload["server"]["sources"][0]
assert source["kind"] == "mcp"
assert source["id"] == "everything.default"
assert source["transport"]["kind"] == "stdio"
assert source["transport"]["command"] == "uvx"
def test_wf_config_migrate_mcp_writes_output_file(tmp_path: Path) -> None:
legacy_path = tmp_path / "wf_mcp.config.json"
output_path = tmp_path / "wf.json"
legacy_path.write_text(
"""
{
"store_root": "store",
"connections": [
{
"id": "context7.default",
"server": "context7",
"account": "default",
"metadata": {
"transport": "streamable_http",
"url": "http://127.0.0.1:3000/mcp"
}
}
]
}
""",
encoding="utf-8",
)
result = CliRunner().invoke(
app,
["config", "migrate-mcp", str(legacy_path), "--output", str(output_path)],
)
assert result.exit_code == 0, result.output
status = json.loads(result.output)
assert status["status"] == "written"
payload = json.loads(output_path.read_text(encoding="utf-8"))
assert payload["server"]["sources"][0]["transport"]["kind"] == "http"
def test_wf_config_validate_loads_python_source(tmp_path: Path) -> None:
source_root = tmp_path / "sources"
source_root.mkdir()
(source_root / "ops.py").write_text(
"""
from pydantic import BaseModel
from wf_authoring import node
class EchoInput(BaseModel):
text: str
class EchoOutput(BaseModel):
text: str
@node(name="echo")
def echo(input: EchoInput) -> EchoOutput:
return EchoOutput(text=input.text)
registry = [echo]
""",
encoding="utf-8",
)
config_path = tmp_path / "wf.config.json"
config_path.write_text(
json.dumps(
{
"version": 1,
"server": {
"store": {"kind": "filesystem", "root": "store"},
"sources": [
{
"kind": "python",
"id": "local.ops",
"path": "sources",
"module": "ops",
"registry": "registry",
}
],
},
}
),
encoding="utf-8",
)
result = CliRunner().invoke(app, ["config", "validate", str(config_path)])
assert result.exit_code == 0, result.output
payload = json.loads(result.output)
assert payload["valid"] is True
assert payload["sources"] == [
{
"id": "local.ops",
"kind": "python",
"status": "ok",
"capability_count": 1,
}
]
def test_wf_config_validate_uses_global_config_when_path_omitted(
tmp_path: Path,
) -> None:
config_path = tmp_path / "wf.config.json"
config_path.write_text(
json.dumps(
{
"version": 1,
"server": {
"store": {"kind": "filesystem", "root": "store"},
"sources": [{"kind": "stdlib", "id": "wf.std"}],
},
}
),
encoding="utf-8",
)
result = CliRunner().invoke(
app,
["--config", str(config_path), "config", "validate"],
)
assert result.exit_code == 0, result.output
payload = json.loads(result.output)
assert payload["valid"] is True
assert payload["path"] == str(config_path)
assert payload["sources"] == [{"id": "wf.std", "kind": "stdlib", "status": "ok"}]
def test_wf_config_validate_reports_python_source_import_failure(
tmp_path: Path,
) -> None:
config_path = tmp_path / "wf.config.json"
config_path.write_text(
json.dumps(
{
"version": 1,
"server": {
"store": {"kind": "filesystem", "root": "store"},
"sources": [
{
"kind": "python",
"id": "local.ops",
"path": ".",
"module": "missing_ops",
"registry": "registry",
}
],
},
}
),
encoding="utf-8",
)
result = CliRunner().invoke(app, ["config", "validate", str(config_path)])
assert result.exit_code != 0
assert "invalid workflow config" in result.output
assert "local.ops" in result.output
assert "missing_ops" in result.output