Private
Public Access
0
0
Files
manual_slop/tests/test_deepseek_provider.py
T
ed ada9617308 test(ai_client): rename send_result to send in 22 remaining test files
Batch rename of 22 test files. 62 references renamed total.

The full test suite is now GREEN again, matching the pre-rename baseline
from Task 1.1. Pure mechanical rename. No behavior change.

Files affected: test_ai_cache_tracking, test_ai_client_cli,
test_ai_client_result, test_api_events, test_context_pruner,
test_deepseek_provider, test_gemini_cli_* (3 files), test_gui2_mcp,
test_headless_* (2 files), test_live_gui_integration_v2,
test_orchestration_logic, test_phase6_engine, test_rag_integration,
test_run_worker_lifecycle_abort, test_spawn_interception_v2,
test_symbol_parsing, test_tier4_interceptor, test_tiered_aggregation,
test_token_usage.

Note: spec estimated 24 files; actual is 22 (test_deprecation_warnings
no longer exists, and 1 fewer file than spec's list).

Refs: conductor/tracks/send_result_to_send_20260616/
2026-06-17 00:38:29 -04:00

186 lines
6.2 KiB
Python

import unittest.mock
from unittest.mock import patch, MagicMock
from src import ai_client
from src.result_types import Result
def test_deepseek_model_selection() -> None:
"""
Verifies that ai_client.set_provider('deepseek', 'deepseek-chat') correctly updates the internal state.
"""
ai_client.set_provider("deepseek", "deepseek-chat")
assert ai_client._provider == "deepseek"
assert ai_client._model == "deepseek-chat"
@patch("requests.post")
def test_deepseek_completion_logic(mock_post: MagicMock) -> None:
"""
Verifies that ai_client.send() correctly calls the DeepSeek API and returns content.
"""
ai_client.set_provider("deepseek", "deepseek-chat")
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}):
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
"choices": [{"message": {"content": "Hello World"}, "finish_reason": "stop"}]
}
mock_post.return_value = mock_response
result = ai_client.send(md_content="Context", user_message="Hi", base_dir=".")
assert result.ok
assert result.data == "Hello World"
assert mock_post.called
@patch("requests.post")
def test_deepseek_reasoning_logic(mock_post: MagicMock) -> None:
"""
Verifies that reasoning_content is captured and wrapped in <thinking> tags.
"""
ai_client.set_provider("deepseek", "deepseek-reasoner")
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}):
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
"choices": [{
"message": {"content": "Final answer", "reasoning_content": "Chain of thought"},
"finish_reason": "stop"
}]
}
mock_post.return_value = mock_response
result = ai_client.send(md_content="Context", user_message="Hi", base_dir=".")
assert result.ok
assert "<thinking>\nChain of thought\n</thinking>" in result.data
assert "Final answer" in result.data
@patch("requests.post")
def test_deepseek_tool_calling(mock_post: MagicMock) -> None:
"""
Verifies that DeepSeek provider correctly identifies and executes tool calls.
"""
ai_client.set_provider("deepseek", "deepseek-chat")
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}), \
patch("src.mcp_client.async_dispatch", new_callable=unittest.mock.AsyncMock) as mock_dispatch:
# Round 1: Model calls a tool
mock_resp1 = MagicMock()
mock_resp1.status_code = 200
mock_resp1.json.return_value = {
"choices": [{
"message": {
"content": "I will read the file",
"tool_calls": [{
"id": "call_1",
"type": "function",
"function": {"name": "read_file", "arguments": '{"path": "test.txt"}'}
}]
},
"finish_reason": "tool_calls"
}]
}
# Round 2: Model provides final answer
mock_resp2 = MagicMock()
mock_resp2.status_code = 200
mock_resp2.json.return_value = {
"choices": [{"message": {"content": "File content is: Hello World"}, "finish_reason": "stop"}]
}
mock_post.side_effect = [mock_resp1, mock_resp2]
mock_dispatch.return_value = "Hello World"
result = ai_client.send(md_content="Context", user_message="Read test.txt", base_dir=".")
assert result.ok
assert "File content is: Hello World" in result.data
assert mock_dispatch.called
mock_dispatch.assert_called_with("read_file", {"path": "test.txt"})
@patch("requests.post")
def test_deepseek_streaming(mock_post: MagicMock) -> None:
"""
Verifies that DeepSeek provider correctly aggregates streaming chunks.
"""
ai_client.set_provider("deepseek", "deepseek-chat")
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}):
mock_response = MagicMock()
mock_response.status_code = 200
# Mocking an iterable response for stream=True
chunks = [
'data: {"choices": [{"delta": {"content": "Hello "}}]}\n',
'data: {"choices": [{"delta": {"content": "World"}}]}\n',
'data: [DONE]\n'
]
mock_response.iter_lines.return_value = [c.encode('utf-8') for c in chunks]
mock_post.return_value = mock_response
result = ai_client.send(md_content="Context", user_message="Stream test", base_dir=".", stream=True)
assert result.ok
assert result.data == "Hello World"
@patch("requests.post")
def test_deepseek_payload_verification(mock_post: MagicMock) -> None:
"""
Verifies that the correct JSON payload (tools, history, params) is sent to DeepSeek.
"""
ai_client.set_provider("deepseek", "deepseek-chat")
ai_client.reset_session()
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}):
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
"choices": [{"message": {"content": "OK"}, "finish_reason": "stop"}]
}
mock_post.return_value = mock_response
result = ai_client.send(md_content="Context", user_message="Message 1", base_dir=".", discussion_history="History")
assert result.ok
args, kwargs = mock_post.call_args
payload = kwargs["json"]
assert payload["model"] == "deepseek-chat"
assert "tools" in payload
assert len(payload["messages"]) == 2 # system + user
assert "[DISCUSSION HISTORY]\n\nHistory" in payload["messages"][1]["content"]
assert "temperature" in payload
assert "max_tokens" in payload
@patch("requests.post")
def test_deepseek_reasoner_payload_verification(mock_post: MagicMock) -> None:
"""
Verifies that deepseek-reasoner payload excludes tools and temperature.
"""
ai_client.set_provider("deepseek", "deepseek-reasoner")
ai_client.reset_session()
with patch("src.ai_client._load_credentials", return_value={"deepseek": {"api_key": "test-key"}}):
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
"choices": [{"message": {"content": "OK"}, "finish_reason": "stop"}]
}
mock_post.return_value = mock_response
result = ai_client.send(md_content="Context", user_message="Message 1", base_dir=".")
assert result.ok
args, kwargs = mock_post.call_args
payload = kwargs["json"]
assert payload["model"] == "deepseek-reasoner"
assert "tools" not in payload
assert "temperature" not in payload
assert "max_tokens" not in payload