Skip to content

Commit 558e353

Browse files
committed
Add tests
1 parent 6af8551 commit 558e353

File tree

3 files changed

+539
-0
lines changed

3 files changed

+539
-0
lines changed

tests/test_remove.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
from unittest.mock import Mock, patch
2+
3+
from click.testing import CliRunner
4+
5+
from mcpm.clients.client_registry import ClientRegistry
6+
from mcpm.commands.remove import remove
7+
8+
9+
def test_remove_server_success(windsurf_manager, monkeypatch):
10+
"""Test successful server removal"""
11+
# Setup mocks
12+
monkeypatch.setattr(ClientRegistry, "get_active_client", Mock(return_value="windsurf"))
13+
monkeypatch.setattr(ClientRegistry, "get_active_client_manager", Mock(return_value=windsurf_manager))
14+
monkeypatch.setattr(ClientRegistry, "get_client_info", Mock(return_value={"name": "windsurf"}))
15+
16+
# Mock server info
17+
mock_server = Mock()
18+
mock_server.command = "npx"
19+
mock_server.args = ["-y", "@modelcontextprotocol/server-test"]
20+
mock_server.env = {"API_KEY": "test-key"}
21+
windsurf_manager.get_server = Mock(return_value=mock_server)
22+
windsurf_manager.remove_server = Mock(return_value=True)
23+
24+
# Run the command with force flag to skip confirmation
25+
runner = CliRunner()
26+
result = runner.invoke(remove, ["server-test", "--force"])
27+
28+
assert result.exit_code == 0
29+
assert "Successfully removed server: server-test" in result.output
30+
windsurf_manager.remove_server.assert_called_once_with("server-test")
31+
32+
33+
def test_remove_server_not_found(windsurf_manager, monkeypatch):
34+
"""Test removal of non-existent server"""
35+
monkeypatch.setattr(ClientRegistry, "get_active_client", Mock(return_value="windsurf"))
36+
monkeypatch.setattr(ClientRegistry, "get_active_client_manager", Mock(return_value=windsurf_manager))
37+
monkeypatch.setattr(ClientRegistry, "get_client_info", Mock(return_value={"name": "windsurf"}))
38+
39+
# Mock server not found
40+
windsurf_manager.get_server = Mock(return_value=None)
41+
42+
runner = CliRunner()
43+
result = runner.invoke(remove, ["non-existent-server"])
44+
45+
assert result.exit_code == 0 # Command exits successfully but with error message
46+
assert "Server 'non-existent-server' not found in windsurf" in result.output
47+
48+
49+
def test_remove_server_unsupported_client(monkeypatch):
50+
"""Test removal with unsupported client"""
51+
monkeypatch.setattr(ClientRegistry, "get_active_client_manager", Mock(return_value=None))
52+
monkeypatch.setattr(ClientRegistry, "get_active_client", Mock(return_value="unsupported"))
53+
54+
runner = CliRunner()
55+
result = runner.invoke(remove, ["server-test"])
56+
57+
assert result.exit_code == 0 # Command exits successfully but with error message
58+
assert "Unsupported active client" in result.output
59+
60+
61+
def test_remove_server_cancelled(windsurf_manager, monkeypatch):
62+
"""Test removal when user cancels the confirmation"""
63+
monkeypatch.setattr(ClientRegistry, "get_active_client", Mock(return_value="windsurf"))
64+
monkeypatch.setattr(ClientRegistry, "get_active_client_manager", Mock(return_value=windsurf_manager))
65+
monkeypatch.setattr(ClientRegistry, "get_client_info", Mock(return_value={"name": "windsurf"}))
66+
67+
# Mock server info
68+
mock_server = Mock()
69+
mock_server.command = "npx"
70+
mock_server.args = ["-y", "@modelcontextprotocol/server-test"]
71+
mock_server.env = {"API_KEY": "test-key"}
72+
windsurf_manager.get_server = Mock(return_value=mock_server)
73+
windsurf_manager.remove_server = Mock(return_value=True)
74+
75+
# Run the command without force flag and simulate user cancellation
76+
runner = CliRunner()
77+
with patch("rich.prompt.Confirm.ask", return_value=False):
78+
result = runner.invoke(remove, ["server-test"])
79+
80+
assert result.exit_code == 0
81+
assert "Removal cancelled" in result.output
82+
windsurf_manager.remove_server.assert_not_called()
83+
84+
85+
def test_remove_server_failure(windsurf_manager, monkeypatch):
86+
"""Test removal when the removal operation fails"""
87+
monkeypatch.setattr(ClientRegistry, "get_active_client", Mock(return_value="windsurf"))
88+
monkeypatch.setattr(ClientRegistry, "get_active_client_manager", Mock(return_value=windsurf_manager))
89+
monkeypatch.setattr(ClientRegistry, "get_client_info", Mock(return_value={"name": "windsurf"}))
90+
91+
# Mock server info
92+
mock_server = Mock()
93+
mock_server.command = "npx"
94+
mock_server.args = ["-y", "@modelcontextprotocol/server-test"]
95+
mock_server.env = {"API_KEY": "test-key"}
96+
windsurf_manager.get_server = Mock(return_value=mock_server)
97+
windsurf_manager.remove_server = Mock(return_value=False)
98+
99+
# Run the command with force flag
100+
runner = CliRunner()
101+
result = runner.invoke(remove, ["server-test", "--force"])
102+
103+
assert result.exit_code == 0 # Command exits successfully but with error message
104+
assert "Failed to remove server 'server-test'" in result.output
105+
windsurf_manager.remove_server.assert_called_once_with("server-test")

tests/test_search.py

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
from unittest.mock import Mock
2+
3+
from click.testing import CliRunner
4+
5+
from mcpm.commands.search import search
6+
7+
8+
def test_search_all_servers(monkeypatch):
9+
"""Test searching for all servers without a query"""
10+
# Mock repository manager
11+
mock_repo_manager = Mock()
12+
mock_repo_manager.search_servers = Mock(
13+
return_value=[
14+
{
15+
"name": "server1",
16+
"display_name": "Server One",
17+
"description": "First test server",
18+
"categories": ["category1"],
19+
"tags": ["tag1", "tag2"],
20+
},
21+
{
22+
"name": "server2",
23+
"display_name": "Server Two",
24+
"description": "Second test server",
25+
"categories": ["category2"],
26+
"tags": ["tag3"],
27+
},
28+
]
29+
)
30+
monkeypatch.setattr("mcpm.commands.search.repo_manager", mock_repo_manager)
31+
32+
# Run the command
33+
runner = CliRunner()
34+
result = runner.invoke(search, [])
35+
36+
assert result.exit_code == 0
37+
assert "Listing all available MCP servers" in result.output
38+
assert "Server One" in result.output
39+
assert "Server Two" in result.output
40+
assert "Found 2 server(s) matching search criteria" in result.output
41+
mock_repo_manager.search_servers.assert_called_once_with(None)
42+
43+
44+
def test_search_with_query(monkeypatch):
45+
"""Test searching with a specific query"""
46+
# Mock repository manager
47+
mock_repo_manager = Mock()
48+
mock_repo_manager.search_servers = Mock(
49+
return_value=[
50+
{
51+
"name": "github-server",
52+
"display_name": "GitHub Server",
53+
"description": "GitHub integration server",
54+
"categories": ["integration"],
55+
"tags": ["github", "api"],
56+
}
57+
]
58+
)
59+
monkeypatch.setattr("mcpm.commands.search.repo_manager", mock_repo_manager)
60+
61+
# Run the command
62+
runner = CliRunner()
63+
result = runner.invoke(search, ["github"])
64+
65+
assert result.exit_code == 0
66+
assert "Searching for MCP servers matching 'github'" in result.output
67+
assert "GitHub Server" in result.output
68+
assert "Found 1 server(s) matching search criteria" in result.output
69+
mock_repo_manager.search_servers.assert_called_once_with("github")
70+
71+
72+
def test_search_no_results(monkeypatch):
73+
"""Test searching with no results"""
74+
# Mock repository manager
75+
mock_repo_manager = Mock()
76+
mock_repo_manager.search_servers = Mock(return_value=[])
77+
monkeypatch.setattr("mcpm.commands.search.repo_manager", mock_repo_manager)
78+
79+
# Run the command
80+
runner = CliRunner()
81+
result = runner.invoke(search, ["nonexistent"])
82+
83+
assert result.exit_code == 0
84+
assert "Searching for MCP servers matching 'nonexistent'" in result.output
85+
assert "No matching MCP servers found" in result.output
86+
mock_repo_manager.search_servers.assert_called_once_with("nonexistent")
87+
88+
89+
def test_search_detailed_view(monkeypatch):
90+
"""Test searching with detailed view"""
91+
# Mock repository manager
92+
mock_repo_manager = Mock()
93+
mock_repo_manager.search_servers = Mock(
94+
return_value=[
95+
{
96+
"name": "test-server",
97+
"display_name": "Test Server",
98+
"description": "A test server",
99+
"categories": ["test"],
100+
"tags": ["example"],
101+
"license": "MIT",
102+
"author": {"name": "Test Author", "email": "[email protected]"},
103+
"installation": {"package": "test-package"},
104+
"installations": {
105+
"npm": {
106+
"type": "npm",
107+
"description": "NPM installation",
108+
"recommended": True,
109+
"command": "npx",
110+
"args": ["-y", "test-package"],
111+
"dependencies": ["dependency1"],
112+
"env": {"API_KEY": "${API_KEY}"},
113+
}
114+
},
115+
"examples": [{"title": "Example Usage", "description": "How to use this server"}],
116+
}
117+
]
118+
)
119+
monkeypatch.setattr("mcpm.commands.search.repo_manager", mock_repo_manager)
120+
121+
# Run the command with detailed flag
122+
runner = CliRunner()
123+
result = runner.invoke(search, ["--detailed"])
124+
125+
assert result.exit_code == 0
126+
assert "Test Server" in result.output
127+
assert "A test server" in result.output
128+
assert "Server Information:" in result.output
129+
assert "Installation Details:" in result.output
130+
assert "Example:" in result.output
131+
assert "Found 1 server(s) matching search criteria" in result.output
132+
mock_repo_manager.search_servers.assert_called_once_with(None)
133+
134+
135+
def test_search_error_handling(monkeypatch):
136+
"""Test error handling during search"""
137+
# Mock repository manager to raise an exception
138+
mock_repo_manager = Mock()
139+
mock_repo_manager.search_servers = Mock(side_effect=Exception("Test error"))
140+
monkeypatch.setattr("mcpm.commands.search.repo_manager", mock_repo_manager)
141+
142+
# Run the command
143+
runner = CliRunner()
144+
result = runner.invoke(search, [])
145+
146+
assert result.exit_code == 0
147+
assert "Error searching for servers: Test error" in result.output
148+
mock_repo_manager.search_servers.assert_called_once_with(None)
149+
150+
151+
def test_search_with_query_and_detailed(monkeypatch):
152+
"""Test searching with both a query and detailed view"""
153+
# Mock repository manager
154+
mock_repo_manager = Mock()
155+
mock_repo_manager.search_servers = Mock(
156+
return_value=[
157+
{
158+
"name": "test-server",
159+
"display_name": "Test Server",
160+
"description": "A test server",
161+
"categories": ["test"],
162+
"tags": ["example"],
163+
"license": "MIT",
164+
"author": {"name": "Test Author", "email": "[email protected]"},
165+
"installation": {"package": "test-package"},
166+
"installations": {
167+
"npm": {
168+
"type": "npm",
169+
"description": "NPM installation",
170+
"recommended": True,
171+
"command": "npx",
172+
"args": ["-y", "test-package"],
173+
"dependencies": ["dependency1"],
174+
"env": {"API_KEY": "${API_KEY}"},
175+
}
176+
},
177+
"examples": [{"title": "Example Usage", "description": "How to use this server"}],
178+
}
179+
]
180+
)
181+
monkeypatch.setattr("mcpm.commands.search.repo_manager", mock_repo_manager)
182+
183+
# Run the command with both query and detailed flag
184+
runner = CliRunner()
185+
result = runner.invoke(search, ["test", "--detailed"])
186+
187+
assert result.exit_code == 0
188+
assert "Searching for MCP servers matching 'test'" in result.output
189+
assert "Test Server" in result.output
190+
assert "Server Information:" in result.output
191+
assert "Installation Details:" in result.output
192+
assert "Example:" in result.output
193+
assert "Found 1 server(s) matching search criteria" in result.output
194+
mock_repo_manager.search_servers.assert_called_once_with("test")

0 commit comments

Comments
 (0)