From e19b7e95f4a1df622ffb3c693990dc03ca47423e Mon Sep 17 00:00:00 2001 From: starmen1265 Date: Wed, 11 Mar 2026 18:48:44 +0800 Subject: [PATCH] test(04-02): add failing tests for /gsd:use command handling - Test _handle_use_project updates user context - Test success card when project exists - Test error card with Create button when project doesn't exist - Test handle_message routes use command - Test empty project name returns error - Test subsequent commands use project from user context Co-Authored-By: Claude Opus 4.6 --- gsd-openclaw/tests/test_orchestrator.py | 122 ++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/gsd-openclaw/tests/test_orchestrator.py b/gsd-openclaw/tests/test_orchestrator.py index 270ac87..bc2d27d 100644 --- a/gsd-openclaw/tests/test_orchestrator.py +++ b/gsd-openclaw/tests/test_orchestrator.py @@ -725,3 +725,125 @@ class TestSpecialCommands: orch.formatter.format_error.assert_called_once() call_args = orch.formatter.format_error.call_args assert "Project name" in str(call_args) + + # ===== Task 2: /gsd:use command tests ===== + + def test_use_project_updates_user_context(self, orchestrator_with_mocks): + """_handle_use_project should update user context to new project.""" + from gsd_openclaw.tmux_session import TmuxSession + + orch = orchestrator_with_mocks + + mock_session = MagicMock(spec=TmuxSession) + mock_session.session_id = "test-123" + orch.tmux_manager.get_session.return_value = mock_session + + orch.formatter.format_success.return_value = {"card": "success"} + + result = orch._handle_use_project("user1", "existing-project") + + # Verify user context was updated + user_ctx = orch._get_user_context_manager("user1") + assert user_ctx.get_current_project() == "existing-project" + + def test_use_project_returns_success_when_project_exists(self, orchestrator_with_mocks): + """_handle_use_project should return success card when project exists.""" + from gsd_openclaw.tmux_session import TmuxSession + + orch = orchestrator_with_mocks + + mock_session = MagicMock(spec=TmuxSession) + mock_session.session_id = "test-123" + orch.tmux_manager.get_session.return_value = mock_session + + orch.formatter.format_success.return_value = {"card": "success"} + + result = orch._handle_use_project("user1", "existing-project") + + orch.formatter.format_success.assert_called_once() + + def test_use_project_returns_error_with_button_when_not_exists(self, orchestrator_with_mocks): + """_handle_use_project should return error card with Create button when project doesn't exist.""" + from gsd_openclaw.response_formatter import CardButton + + orch = orchestrator_with_mocks + + orch.tmux_manager.get_session.return_value = None + + orch.formatter.format_error.return_value = {"card": "error"} + + result = orch._handle_use_project("user1", "nonexistent-project") + + # Verify error card was returned with buttons + orch.formatter.format_error.assert_called_once() + call_args = orch.formatter.format_error.call_args + # Check that buttons argument was passed + assert call_args[1].get("buttons") is not None + + def test_handle_message_routes_use_command(self, orchestrator_with_mocks): + """handle_message should route 'use' command to _handle_use_project.""" + from gsd_openclaw.tmux_session import TmuxSession + + orch = orchestrator_with_mocks + + mock_session = MagicMock(spec=TmuxSession) + mock_session.session_id = "test-123" + orch.tmux_manager.get_session.return_value = mock_session + + orch.formatter.format_success.return_value = {"card": "success"} + + # Patch _handle_use_project to verify it's called + with patch.object(orch, '_handle_use_project', return_value={"card": "mocked"}) as mock_handler: + result = orch.handle_message( + user_id="user1", + message="/gsd:use my-project", + channel="test-channel", + context={} + ) + + mock_handler.assert_called_once_with("user1", "my-project") + + def test_use_project_with_no_args_returns_error(self, orchestrator_with_mocks): + """_handle_use_project with no args should return error card.""" + orch = orchestrator_with_mocks + + orch.formatter.format_error.return_value = {"card": "error"} + + result = orch._handle_use_project("user1", "") + + orch.formatter.format_error.assert_called_once() + call_args = orch.formatter.format_error.call_args + assert "Project name" in str(call_args) + + def test_subsequent_commands_use_project_from_user_context(self, orchestrator_with_mocks): + """Generic commands should use project from user context after /gsd:use.""" + from gsd_openclaw.tmux_session import TmuxSession + + orch = orchestrator_with_mocks + + # First set up user context with a project + user_ctx = orch._get_user_context_manager("user1") + user_ctx.set_current_project("context-project") + + mock_session = MagicMock(spec=TmuxSession) + mock_session.session_id = "test-123" + orch.tmux_manager.get_session.return_value = mock_session + + orch.executor.execute.return_value = CommandResult( + output="Status: OK", + completed=True, + has_error=False, + error_type=None + ) + orch.formatter.format_success.return_value = {"card": "success"} + + # Call a generic command without project in context + result = orch.handle_message( + user_id="user1", + message="/gsd:status", + channel="test-channel", + context={} # No project in context + ) + + # Verify get_session was called with the project from user context + orch.tmux_manager.get_session.assert_called_with("context-project")