Skip to content

Commit 64cf74e

Browse files
test(cli): update for new cli architecture
test(cli): update test_mcp_cli_package_management mock paths for new architecture test(cli): update test_mcp_cli_discovery_listing mock paths for new architecture test(cli): update test_mcp_cli_direct_management for new architecture - Update import paths from hatch.cli_hatch to hatch.cli modules - Fix handler calls to use args: Namespace signature instead of individual parameters - Add env_manager attribute to test Namespace objects where required - Fix attribute names (host_name vs host) for remove host handlers - Update mock paths to new module locations - All 21 tests now passing test(cli): update test_mcp_cli_backup_management for new architecture M1.8.1: Update backup management tests for handler-based architecture Changes: - Update mock paths from hatch.cli_hatch to hatch.cli.cli_mcp - Update argument parsing tests to use assert_called_once() - Patch MCPHostConfigBackupManager at source module level - Patch request_confirmation at hatch.cli.cli_utils - Import MCPHostConfigBackupManager at module level for patching All 14 backup management tests now pass. test(cli): update remaining test files for handler-based architecture M1.8.1: Complete test updates for new CLI architecture Files updated: - tests/cli_test_utils.py: Enhanced helper functions for Namespace creation - tests/test_mcp_cli_host_config_integration.py: Updated mock paths and Namespace calls - tests/test_mcp_cli_partial_updates.py: Updated for new handler signatures - tests/test_mcp_cli_all_host_specific_args.py: Updated mock paths - tests/regression/test_mcp_kiro_cli_integration.py: Updated for cli_mcp module All 310 CLI tests now pass.
1 parent cf81671 commit 64cf74e

10 files changed

+888
-1152
lines changed

tests/cli_test_utils.py

Lines changed: 143 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
66
These utilities reduce boilerplate in test files and ensure consistent
77
test patterns across the CLI test suite.
8+
9+
IMPORTANT: The attribute names in create_mcp_configure_args MUST match
10+
the exact names expected by handle_mcp_configure in hatch/cli/cli_mcp.py.
811
"""
912

1013
import sys
@@ -20,98 +23,196 @@
2023
def create_mcp_configure_args(
2124
host: str = "claude-desktop",
2225
server_name: str = "test-server",
23-
command: Optional[str] = "python",
26+
server_command: Optional[str] = "python",
2427
args: Optional[List[str]] = None,
25-
env: Optional[List[str]] = None,
28+
env_var: Optional[List[str]] = None,
2629
url: Optional[str] = None,
2730
header: Optional[List[str]] = None,
28-
http_url: Optional[str] = None,
29-
disabled: bool = False,
3031
timeout: Optional[int] = None,
32+
trust: bool = False,
33+
cwd: Optional[str] = None,
34+
env_file: Optional[str] = None,
35+
http_url: Optional[str] = None,
3136
include_tools: Optional[List[str]] = None,
3237
exclude_tools: Optional[List[str]] = None,
33-
inputs: Optional[List[str]] = None,
38+
input: Optional[List[str]] = None,
39+
disabled: Optional[bool] = None,
3440
auto_approve_tools: Optional[List[str]] = None,
3541
disable_tools: Optional[List[str]] = None,
42+
env_vars: Optional[List[str]] = None,
43+
startup_timeout: Optional[int] = None,
44+
tool_timeout: Optional[int] = None,
3645
enabled: Optional[bool] = None,
37-
roots: Optional[List[str]] = None,
38-
transport: Optional[str] = None,
39-
transport_options: Optional[List[str]] = None,
40-
env_file: Optional[str] = None,
41-
working_dir: Optional[str] = None,
42-
shell: Optional[bool] = None,
43-
type_field: Optional[str] = None,
44-
scope: Optional[str] = None,
46+
bearer_token_env_var: Optional[str] = None,
47+
env_header: Optional[List[str]] = None,
4548
no_backup: bool = False,
4649
dry_run: bool = False,
4750
auto_approve: bool = False,
51+
_use_default_args: bool = True,
4852
) -> Namespace:
4953
"""Create a Namespace object for handle_mcp_configure testing.
5054
5155
This helper creates a properly structured Namespace object that matches
5256
the expected arguments for handle_mcp_configure, making tests more
5357
readable and maintainable.
5458
59+
IMPORTANT: Attribute names MUST match those in handle_mcp_configure:
60+
- server_command (not command)
61+
- env_var (not env)
62+
- input (not inputs)
63+
5564
Args:
5665
host: Target MCP host (e.g., 'claude-desktop', 'cursor', 'vscode')
5766
server_name: Name of the MCP server to configure
58-
command: Command to run for local servers
59-
args: Arguments for the command
60-
env: Environment variables in KEY=VALUE format
67+
server_command: Command to run for local servers
68+
args: Arguments for the command (defaults to ['server.py'] for local servers)
69+
env_var: Environment variables in KEY=VALUE format
6170
url: URL for SSE remote servers
6271
header: HTTP headers in KEY=VALUE format
63-
http_url: URL for HTTP remote servers (Gemini only)
64-
disabled: Whether the server should be disabled
6572
timeout: Server timeout in seconds
73+
trust: Trust the server (Cursor)
74+
cwd: Working directory
75+
env_file: Environment file path
76+
http_url: URL for HTTP remote servers (Gemini only)
6677
include_tools: Tools to include (Gemini)
6778
exclude_tools: Tools to exclude (Gemini)
68-
inputs: VSCode input configurations
79+
input: VSCode input configurations
80+
disabled: Whether the server should be disabled
6981
auto_approve_tools: Tools to auto-approve (Kiro)
7082
disable_tools: Tools to disable (Kiro)
71-
enabled: Whether server is enabled (Codex)
72-
roots: Root directories (Codex)
73-
transport: Transport type (Codex)
74-
transport_options: Transport options (Codex)
75-
env_file: Environment file path (Codex)
76-
working_dir: Working directory (Codex)
77-
shell: Use shell execution (Codex)
78-
type_field: Server type field
79-
scope: Configuration scope
83+
env_vars: Additional environment variables
84+
startup_timeout: Startup timeout
85+
tool_timeout: Tool execution timeout
86+
enabled: Whether server is enabled
87+
bearer_token_env_var: Bearer token environment variable
88+
env_header: Environment headers
8089
no_backup: Disable backup creation
8190
dry_run: Preview changes without applying
8291
auto_approve: Skip confirmation prompts
92+
_use_default_args: If True and args is None and server_command is set, use default args
8393
8494
Returns:
8595
Namespace object with all arguments set
8696
"""
87-
if args is None:
97+
# Only use default args for local servers (when command is set)
98+
if args is None and server_command is not None and _use_default_args:
8899
args = ["server.py"]
89100

90101
return Namespace(
91102
host=host,
92103
server_name=server_name,
93-
command=command,
104+
server_command=server_command,
94105
args=args,
95-
env=env,
106+
env_var=env_var,
96107
url=url,
97108
header=header,
98-
http_url=http_url,
99-
disabled=disabled,
100109
timeout=timeout,
110+
trust=trust,
111+
cwd=cwd,
112+
env_file=env_file,
113+
http_url=http_url,
101114
include_tools=include_tools,
102115
exclude_tools=exclude_tools,
103-
inputs=inputs,
116+
input=input,
117+
disabled=disabled,
104118
auto_approve_tools=auto_approve_tools,
105119
disable_tools=disable_tools,
120+
env_vars=env_vars,
121+
startup_timeout=startup_timeout,
122+
tool_timeout=tool_timeout,
106123
enabled=enabled,
107-
roots=roots,
108-
transport=transport,
109-
transport_options=transport_options,
110-
env_file=env_file,
111-
working_dir=working_dir,
112-
shell=shell,
113-
type_field=type_field,
114-
scope=scope,
124+
bearer_token_env_var=bearer_token_env_var,
125+
env_header=env_header,
126+
no_backup=no_backup,
127+
dry_run=dry_run,
128+
auto_approve=auto_approve,
129+
)
130+
131+
132+
def create_mcp_remove_args(
133+
host: str = "claude-desktop",
134+
server_name: str = "test-server",
135+
no_backup: bool = False,
136+
dry_run: bool = False,
137+
auto_approve: bool = False,
138+
) -> Namespace:
139+
"""Create a Namespace object for handle_mcp_remove testing.
140+
141+
Args:
142+
host: Target MCP host
143+
server_name: Name of the MCP server to remove
144+
no_backup: Disable backup creation
145+
dry_run: Preview changes without applying
146+
auto_approve: Skip confirmation prompts
147+
148+
Returns:
149+
Namespace object with all arguments set
150+
"""
151+
return Namespace(
152+
host=host,
153+
server_name=server_name,
154+
no_backup=no_backup,
155+
dry_run=dry_run,
156+
auto_approve=auto_approve,
157+
)
158+
159+
160+
def create_mcp_remove_server_args(
161+
env_manager: Any = None,
162+
server_name: str = "test-server",
163+
host: Optional[str] = None,
164+
env: Optional[str] = None,
165+
no_backup: bool = False,
166+
dry_run: bool = False,
167+
auto_approve: bool = False,
168+
) -> Namespace:
169+
"""Create a Namespace object for handle_mcp_remove_server testing.
170+
171+
Args:
172+
env_manager: Environment manager instance
173+
server_name: Name of the MCP server to remove
174+
host: Comma-separated list of target hosts
175+
env: Environment name
176+
no_backup: Disable backup creation
177+
dry_run: Preview changes without applying
178+
auto_approve: Skip confirmation prompts
179+
180+
Returns:
181+
Namespace object with all arguments set
182+
"""
183+
return Namespace(
184+
env_manager=env_manager,
185+
server_name=server_name,
186+
host=host,
187+
env=env,
188+
no_backup=no_backup,
189+
dry_run=dry_run,
190+
auto_approve=auto_approve,
191+
)
192+
193+
194+
def create_mcp_remove_host_args(
195+
env_manager: Any = None,
196+
host_name: str = "claude-desktop",
197+
no_backup: bool = False,
198+
dry_run: bool = False,
199+
auto_approve: bool = False,
200+
) -> Namespace:
201+
"""Create a Namespace object for handle_mcp_remove_host testing.
202+
203+
Args:
204+
env_manager: Environment manager instance
205+
host_name: Name of the host to remove configuration from
206+
no_backup: Disable backup creation
207+
dry_run: Preview changes without applying
208+
auto_approve: Skip confirmation prompts
209+
210+
Returns:
211+
Namespace object with all arguments set
212+
"""
213+
return Namespace(
214+
env_manager=env_manager,
215+
host_name=host_name,
115216
no_backup=no_backup,
116217
dry_run=dry_run,
117218
auto_approve=auto_approve,

tests/regression/test_mcp_kiro_cli_integration.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22
Kiro MCP CLI Integration Tests
33
44
Tests for CLI argument parsing and integration with Kiro-specific arguments.
5+
6+
Updated for M1.8: Uses Namespace-based handler calls via create_mcp_configure_args.
57
"""
68

79
import unittest
810
from unittest.mock import patch, MagicMock
911

1012
from wobble.decorators import regression_test
1113

12-
from hatch.cli_hatch import handle_mcp_configure
14+
from hatch.cli.cli_mcp import handle_mcp_configure
15+
from tests.cli_test_utils import create_mcp_configure_args
1316

1417

1518
class TestKiroCLIIntegration(unittest.TestCase):
@@ -27,23 +30,21 @@ def test_kiro_cli_with_disabled_flag(self, mock_manager_class):
2730
mock_result.backup_path = None
2831
mock_manager.configure_server.return_value = mock_result
2932

30-
result = handle_mcp_configure(
33+
args = create_mcp_configure_args(
3134
host='kiro',
3235
server_name='test-server',
33-
command='auggie',
36+
server_command='auggie',
3437
args=['--mcp'],
35-
disabled=True, # Kiro-specific argument
36-
auto_approve=True
38+
disabled=True,
39+
auto_approve=True,
3740
)
3841

42+
result = handle_mcp_configure(args)
3943
self.assertEqual(result, 0)
4044

41-
# Verify configure_server was called with Kiro model
4245
mock_manager.configure_server.assert_called_once()
4346
call_args = mock_manager.configure_server.call_args
4447
server_config = call_args.kwargs['server_config']
45-
46-
# Verify Kiro-specific field was set
4748
self.assertTrue(server_config.disabled)
4849

4950
@patch('hatch.cli.cli_mcp.MCPHostConfigurationManager')
@@ -57,18 +58,18 @@ def test_kiro_cli_with_auto_approve_tools(self, mock_manager_class):
5758
mock_result.success = True
5859
mock_manager.configure_server.return_value = mock_result
5960

60-
result = handle_mcp_configure(
61+
args = create_mcp_configure_args(
6162
host='kiro',
6263
server_name='test-server',
63-
command='auggie',
64-
args=['--mcp'], # Required parameter
64+
server_command='auggie',
65+
args=['--mcp'],
6566
auto_approve_tools=['codebase-retrieval', 'fetch'],
66-
auto_approve=True
67+
auto_approve=True,
6768
)
6869

70+
result = handle_mcp_configure(args)
6971
self.assertEqual(result, 0)
7072

71-
# Verify autoApprove field was set correctly
7273
call_args = mock_manager.configure_server.call_args
7374
server_config = call_args.kwargs['server_config']
7475
self.assertEqual(len(server_config.autoApprove), 2)
@@ -85,18 +86,18 @@ def test_kiro_cli_with_disable_tools(self, mock_manager_class):
8586
mock_result.success = True
8687
mock_manager.configure_server.return_value = mock_result
8788

88-
result = handle_mcp_configure(
89+
args = create_mcp_configure_args(
8990
host='kiro',
9091
server_name='test-server',
91-
command='python',
92-
args=['server.py'], # Required parameter
92+
server_command='python',
93+
args=['server.py'],
9394
disable_tools=['dangerous-tool', 'risky-tool'],
94-
auto_approve=True
95+
auto_approve=True,
9596
)
9697

98+
result = handle_mcp_configure(args)
9799
self.assertEqual(result, 0)
98100

99-
# Verify disabledTools field was set correctly
100101
call_args = mock_manager.configure_server.call_args
101102
server_config = call_args.kwargs['server_config']
102103
self.assertEqual(len(server_config.disabledTools), 2)
@@ -113,20 +114,20 @@ def test_kiro_cli_combined_arguments(self, mock_manager_class):
113114
mock_result.success = True
114115
mock_manager.configure_server.return_value = mock_result
115116

116-
result = handle_mcp_configure(
117+
args = create_mcp_configure_args(
117118
host='kiro',
118119
server_name='comprehensive-server',
119-
command='auggie',
120+
server_command='auggie',
120121
args=['--mcp', '-m', 'default'],
121122
disabled=False,
122123
auto_approve_tools=['codebase-retrieval'],
123124
disable_tools=['dangerous-tool'],
124-
auto_approve=True
125+
auto_approve=True,
125126
)
126127

128+
result = handle_mcp_configure(args)
127129
self.assertEqual(result, 0)
128130

129-
# Verify all Kiro fields were set correctly
130131
call_args = mock_manager.configure_server.call_args
131132
server_config = call_args.kwargs['server_config']
132133

@@ -138,4 +139,4 @@ def test_kiro_cli_combined_arguments(self, mock_manager_class):
138139

139140

140141
if __name__ == '__main__':
141-
unittest.main()
142+
unittest.main()

tests/test_cli_version.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ def test_version_command_displays_correct_format(self):
6464
test_args = ['hatch', '--version']
6565

6666
with patch('sys.argv', test_args):
67-
# Patch at point of use in cli_hatch (imported from cli_utils)
68-
with patch('hatch.cli_hatch.get_hatch_version', return_value='0.7.0-dev.3'):
67+
# Patch at point of use in __main__ (imported from cli_utils)
68+
with patch('hatch.cli.__main__.get_hatch_version', return_value='0.7.0-dev.3'):
6969
with patch('sys.stdout', new_callable=StringIO) as mock_stdout:
7070
with self.assertRaises(SystemExit) as cm:
7171
main()
@@ -100,7 +100,7 @@ def test_no_conflict_with_package_version_flag(self):
100100
test_args = ['hatch', 'package', 'add', 'test-package', '-v', '1.0.0']
101101

102102
with patch('sys.argv', test_args):
103-
with patch('hatch.cli_hatch.HatchEnvironmentManager') as mock_env:
103+
with patch('hatch.environment_manager.HatchEnvironmentManager') as mock_env:
104104
mock_env_instance = MagicMock()
105105
mock_env.return_value = mock_env_instance
106106
mock_env_instance.add_package_to_environment.return_value = True

0 commit comments

Comments
 (0)