22
33from unittest .mock import AsyncMock , MagicMock , patch
44
5+ import pytest
56from click .testing import CliRunner
67
78from redis_sre_agent .cli .query import query
89
910
11+ @pytest .fixture
12+ def mock_thread_manager ():
13+ """Create a mock ThreadManager that doesn't require Redis."""
14+ mock_tm = MagicMock ()
15+ mock_tm .create_thread = AsyncMock (return_value = "test-thread-id" )
16+ mock_tm .get_thread = AsyncMock (return_value = None )
17+ mock_tm .update_thread_subject = AsyncMock ()
18+ mock_tm .append_messages = AsyncMock ()
19+ return mock_tm
20+
21+
22+ @pytest .fixture
23+ def mock_redis_client ():
24+ """Create a mock Redis client."""
25+ return MagicMock ()
26+
27+
1028def test_query_cli_help_shows_options ():
1129 runner = CliRunner ()
1230 result = runner .invoke (query , ["--help" ])
@@ -22,7 +40,7 @@ def test_query_cli_help_shows_options():
2240 assert "knowledge" in result .output
2341
2442
25- def test_query_without_instance_uses_knowledge_agent ():
43+ def test_query_without_instance_uses_knowledge_agent (mock_thread_manager , mock_redis_client ):
2644 runner = CliRunner ()
2745
2846 mock_agent = MagicMock ()
@@ -37,6 +55,8 @@ def test_query_without_instance_uses_knowledge_agent():
3755 "redis_sre_agent.cli.query.get_instance_by_id" ,
3856 new = AsyncMock (),
3957 ) as mock_get_instance ,
58+ patch ("redis_sre_agent.cli.query.get_redis_client" , return_value = mock_redis_client ),
59+ patch ("redis_sre_agent.cli.query.ThreadManager" , return_value = mock_thread_manager ),
4060 ):
4161 result = runner .invoke (query , ["What is Redis SRE?" ])
4262
@@ -47,7 +67,9 @@ def test_query_without_instance_uses_knowledge_agent():
4767 mock_agent .process_query .assert_awaited_once ()
4868
4969
50- def test_query_with_instance_uses_sre_agent_and_passes_instance_context ():
70+ def test_query_with_instance_uses_sre_agent_and_passes_instance_context (
71+ mock_thread_manager , mock_redis_client
72+ ):
5173 runner = CliRunner ()
5274
5375 class DummyInstance :
@@ -79,6 +101,8 @@ def __init__(self, id: str, name: str): # noqa: A003 - keep click-style arg nam
79101 "redis_sre_agent.cli.query.route_to_appropriate_agent" ,
80102 new = AsyncMock (return_value = AgentType .REDIS_TRIAGE ),
81103 ),
104+ patch ("redis_sre_agent.cli.query.get_redis_client" , return_value = mock_redis_client ),
105+ patch ("redis_sre_agent.cli.query.ThreadManager" , return_value = mock_thread_manager ),
82106 ):
83107 # Use -r / --redis-instance-id option to select instance
84108 result = runner .invoke (
@@ -107,7 +131,9 @@ def __init__(self, id: str, name: str): # noqa: A003 - keep click-style arg nam
107131 assert kwargs .get ("context" ) == {"instance_id" : instance .id }
108132
109133
110- def test_query_with_unknown_instance_exits_with_error_and_skips_agents ():
134+ def test_query_with_unknown_instance_exits_with_error_and_skips_agents (
135+ mock_thread_manager , mock_redis_client
136+ ):
111137 """If -r is provided but the instance does not exist, CLI should error and exit.
112138
113139 This directly tests the new existence-check logic in redis_sre_agent.cli.query.
@@ -129,6 +155,8 @@ def test_query_with_unknown_instance_exits_with_error_and_skips_agents():
129155 "redis_sre_agent.cli.query.get_knowledge_agent" , return_value = mock_agent
130156 ) as mock_get_knowledge ,
131157 patch ("redis_sre_agent.cli.query.get_sre_agent" ) as mock_get_sre ,
158+ patch ("redis_sre_agent.cli.query.get_redis_client" , return_value = mock_redis_client ),
159+ patch ("redis_sre_agent.cli.query.ThreadManager" , return_value = mock_thread_manager ),
132160 ):
133161 result = runner .invoke (
134162 query ,
@@ -152,7 +180,7 @@ def test_query_with_unknown_instance_exits_with_error_and_skips_agents():
152180 mock_agent .process_query .assert_not_awaited ()
153181
154182
155- def test_query_with_agent_triage_forces_triage_agent ():
183+ def test_query_with_agent_triage_forces_triage_agent (mock_thread_manager , mock_redis_client ):
156184 """Test that --agent triage forces use of the triage agent."""
157185 runner = CliRunner ()
158186
@@ -164,6 +192,8 @@ def test_query_with_agent_triage_forces_triage_agent():
164192 patch ("redis_sre_agent.cli.query.get_knowledge_agent" ) as mock_get_knowledge ,
165193 patch ("redis_sre_agent.cli.query.get_chat_agent" ) as mock_get_chat ,
166194 patch ("redis_sre_agent.cli.query.route_to_appropriate_agent" ) as mock_router ,
195+ patch ("redis_sre_agent.cli.query.get_redis_client" , return_value = mock_redis_client ),
196+ patch ("redis_sre_agent.cli.query.ThreadManager" , return_value = mock_thread_manager ),
167197 ):
168198 result = runner .invoke (query , ["--agent" , "triage" , "Check my Redis health" ])
169199
@@ -181,7 +211,7 @@ def test_query_with_agent_triage_forces_triage_agent():
181211 mock_agent .process_query .assert_awaited_once ()
182212
183213
184- def test_query_with_agent_knowledge_forces_knowledge_agent ():
214+ def test_query_with_agent_knowledge_forces_knowledge_agent (mock_thread_manager , mock_redis_client ):
185215 """Test that --agent knowledge forces use of the knowledge agent."""
186216 runner = CliRunner ()
187217
@@ -195,6 +225,8 @@ def test_query_with_agent_knowledge_forces_knowledge_agent():
195225 patch ("redis_sre_agent.cli.query.get_sre_agent" ) as mock_get_sre ,
196226 patch ("redis_sre_agent.cli.query.get_chat_agent" ) as mock_get_chat ,
197227 patch ("redis_sre_agent.cli.query.route_to_appropriate_agent" ) as mock_router ,
228+ patch ("redis_sre_agent.cli.query.get_redis_client" , return_value = mock_redis_client ),
229+ patch ("redis_sre_agent.cli.query.ThreadManager" , return_value = mock_thread_manager ),
198230 ):
199231 result = runner .invoke (query , ["-a" , "knowledge" , "What is Redis replication?" ])
200232
@@ -212,7 +244,7 @@ def test_query_with_agent_knowledge_forces_knowledge_agent():
212244 mock_agent .process_query .assert_awaited_once ()
213245
214246
215- def test_query_with_agent_chat_forces_chat_agent ():
247+ def test_query_with_agent_chat_forces_chat_agent (mock_thread_manager , mock_redis_client ):
216248 """Test that --agent chat forces use of the chat agent."""
217249 runner = CliRunner ()
218250
@@ -239,6 +271,8 @@ def __init__(self):
239271 new = AsyncMock (return_value = instance ),
240272 ),
241273 patch ("redis_sre_agent.cli.query.route_to_appropriate_agent" ) as mock_router ,
274+ patch ("redis_sre_agent.cli.query.get_redis_client" , return_value = mock_redis_client ),
275+ patch ("redis_sre_agent.cli.query.ThreadManager" , return_value = mock_thread_manager ),
242276 ):
243277 result = runner .invoke (query , ["--agent" , "chat" , "-r" , "test-instance" , "Quick question" ])
244278
@@ -256,7 +290,7 @@ def __init__(self):
256290 mock_agent .process_query .assert_awaited_once ()
257291
258292
259- def test_query_with_agent_auto_uses_router ():
293+ def test_query_with_agent_auto_uses_router (mock_thread_manager , mock_redis_client ):
260294 """Test that --agent auto (default) uses the router to select agent."""
261295 runner = CliRunner ()
262296
@@ -274,6 +308,8 @@ def test_query_with_agent_auto_uses_router():
274308 "redis_sre_agent.cli.query.route_to_appropriate_agent" ,
275309 new = AsyncMock (return_value = AgentType .KNOWLEDGE_ONLY ),
276310 ) as mock_router ,
311+ patch ("redis_sre_agent.cli.query.get_redis_client" , return_value = mock_redis_client ),
312+ patch ("redis_sre_agent.cli.query.ThreadManager" , return_value = mock_thread_manager ),
277313 ):
278314 # Default is auto, so router should be called
279315 result = runner .invoke (query , ["What is Redis?" ])
@@ -290,7 +326,7 @@ def test_query_with_agent_auto_uses_router():
290326 mock_get_sre .assert_not_called ()
291327
292328
293- def test_query_agent_option_is_case_insensitive ():
329+ def test_query_agent_option_is_case_insensitive (mock_thread_manager , mock_redis_client ):
294330 """Test that --agent option accepts different cases."""
295331 runner = CliRunner ()
296332
@@ -300,6 +336,8 @@ def test_query_agent_option_is_case_insensitive():
300336 with (
301337 patch ("redis_sre_agent.cli.query.get_knowledge_agent" , return_value = mock_agent ),
302338 patch ("redis_sre_agent.cli.query.route_to_appropriate_agent" ),
339+ patch ("redis_sre_agent.cli.query.get_redis_client" , return_value = mock_redis_client ),
340+ patch ("redis_sre_agent.cli.query.ThreadManager" , return_value = mock_thread_manager ),
303341 ):
304342 # Test uppercase
305343 result = runner .invoke (query , ["--agent" , "KNOWLEDGE" , "test query" ])
0 commit comments