@@ -1054,3 +1054,129 @@ def test_fetch_latest_release_malformed_json_returns_none(monkeypatch):
|
||||
urllib.request, "urlopen", lambda req, timeout=None: _FakeHTTPResponse(b"not json")
|
||||
)
|
||||
assert c.fetch_latest_release() is None
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Server search / filter (#27)
|
||||
# --------------------------------------------------------------------------- #
|
||||
def test_filter_matches_name():
|
||||
e = c.ServerEntry("brave-search", {"command": "npx", "args": ["-y", "@x/brave"]}, True)
|
||||
assert c.server_matches_filter(e, "brave")
|
||||
|
||||
|
||||
def test_filter_matches_stdio_command():
|
||||
e = c.ServerEntry("filesystem", {"command": "uvx", "args": []}, True)
|
||||
assert c.server_matches_filter(e, "uvx")
|
||||
|
||||
|
||||
def test_filter_matches_remote_url():
|
||||
e = c.ServerEntry("hosted", {"url": "https://mcp.example.com/sse"}, True)
|
||||
assert c.server_matches_filter(e, "example.com")
|
||||
|
||||
|
||||
def test_filter_is_case_insensitive():
|
||||
e = c.ServerEntry("BraveSearch", {"command": "NPX", "args": []}, True)
|
||||
assert c.server_matches_filter(e, "bravesearch")
|
||||
assert c.server_matches_filter(e, "npx")
|
||||
|
||||
|
||||
def test_filter_empty_query_matches_everything():
|
||||
e = c.ServerEntry("anything", {"command": "node", "args": []}, True)
|
||||
assert c.server_matches_filter(e, "")
|
||||
assert c.server_matches_filter(e, " ")
|
||||
|
||||
|
||||
def test_filter_no_match_returns_false():
|
||||
e = c.ServerEntry("filesystem", {"command": "uvx", "args": []}, True)
|
||||
assert not c.server_matches_filter(e, "nonexistent")
|
||||
|
||||
|
||||
def test_filter_remote_query_does_not_match_stdio_command_field():
|
||||
e = c.ServerEntry("hosted", {"url": "https://mcp.example.com/sse"}, True)
|
||||
assert not c.server_matches_filter(e, "npx")
|
||||
|
||||
|
||||
def test_filter_servers_returns_only_matches():
|
||||
servers = [
|
||||
c.ServerEntry("brave-search", {"command": "npx", "args": []}, True),
|
||||
c.ServerEntry("filesystem", {"command": "uvx", "args": []}, True),
|
||||
c.ServerEntry("hosted", {"url": "https://mcp.example.com/sse"}, True),
|
||||
]
|
||||
assert [s.name for s in c.filter_servers(servers, "brave")] == ["brave-search"]
|
||||
assert [s.name for s in c.filter_servers(servers, "")] == [s.name for s in servers]
|
||||
assert c.filter_servers(servers, "zzz-nope") == []
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Health status mapping (#28)
|
||||
# --------------------------------------------------------------------------- #
|
||||
def test_health_from_spawn_result_ok():
|
||||
result = {
|
||||
"outcome": "ok",
|
||||
"returncode": None,
|
||||
"stderr": "",
|
||||
"detail": "still running after 3s — server started successfully",
|
||||
}
|
||||
status, summary = c.health_from_spawn_result(result)
|
||||
assert status == c.HealthStatus.OK
|
||||
assert "started" in summary
|
||||
|
||||
|
||||
def test_health_from_spawn_result_not_applicable_is_untested():
|
||||
result = {
|
||||
"outcome": "not_applicable",
|
||||
"returncode": None,
|
||||
"stderr": "",
|
||||
"detail": "remote server",
|
||||
}
|
||||
status, summary = c.health_from_spawn_result(result)
|
||||
assert status == c.HealthStatus.UNTESTED
|
||||
assert summary == "remote server"
|
||||
|
||||
|
||||
def test_health_from_spawn_result_crashed_is_failed():
|
||||
result = {
|
||||
"outcome": "crashed",
|
||||
"returncode": 1,
|
||||
"stderr": "Traceback: boom\nsecond line",
|
||||
"detail": "process exited with code 1",
|
||||
}
|
||||
status, summary = c.health_from_spawn_result(result)
|
||||
assert status == c.HealthStatus.FAILED
|
||||
assert "process exited with code 1" in summary
|
||||
assert "Traceback: boom" in summary
|
||||
|
||||
|
||||
def test_health_from_spawn_result_exited_is_failed():
|
||||
result = {
|
||||
"outcome": "exited",
|
||||
"returncode": 0,
|
||||
"stderr": "",
|
||||
"detail": "process exited cleanly (code 0) — unusual",
|
||||
}
|
||||
status, summary = c.health_from_spawn_result(result)
|
||||
assert status == c.HealthStatus.FAILED
|
||||
assert "exited cleanly" in summary
|
||||
|
||||
|
||||
def test_health_from_spawn_result_not_found_is_failed():
|
||||
result = {
|
||||
"outcome": "not_found",
|
||||
"returncode": None,
|
||||
"stderr": "",
|
||||
"detail": "command not found: totallybogus",
|
||||
}
|
||||
status, summary = c.health_from_spawn_result(result)
|
||||
assert status == c.HealthStatus.FAILED
|
||||
assert "not found" in summary
|
||||
|
||||
|
||||
def test_health_from_spawn_result_failed_without_stderr_has_no_dash():
|
||||
result = {
|
||||
"outcome": "not_found",
|
||||
"returncode": None,
|
||||
"stderr": "",
|
||||
"detail": "command not found: x",
|
||||
}
|
||||
_, summary = c.health_from_spawn_result(result)
|
||||
assert "—" not in summary
|
||||
|
||||
Reference in New Issue
Block a user