chore: import upstream snapshot with attribution
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:08:55 +08:00
commit 7a0da7932b
2985 changed files with 1049377 additions and 0 deletions
+258
View File
@@ -0,0 +1,258 @@
"""
Coverage tests for local_deep_research/mcp/server.py
Focuses on branches NOT covered by existing tests/mcp/test_server.py and
tests/mcp/test_validation.py:
- _classify_error() for each error-type keyword
- _validate_iterations max_val enforcement
- _validate_questions_per_iteration upper bound
- _validate_max_results boundaries
- _build_settings_overrides with various parameter combinations
- analyze_documents validation (empty collection_name)
- generate_report searches_per_section validation
- list_strategies / get_configuration exception paths
"""
import pytest
try:
import mcp # noqa: F401
MCP_AVAILABLE = True
except ImportError:
MCP_AVAILABLE = False
pytestmark = pytest.mark.skipif(
not MCP_AVAILABLE, reason="MCP package not installed"
)
# ---------------------------------------------------------------------------
# _classify_error
# ---------------------------------------------------------------------------
class TestClassifyError:
def _classify(self, msg):
from local_deep_research.mcp.server import _classify_error
return _classify_error(msg)
def test_service_unavailable_503(self):
assert self._classify("503 service error") == "service_unavailable"
def test_service_unavailable_keyword(self):
assert self._classify("service unavailable") == "service_unavailable"
def test_model_not_found_404(self):
assert self._classify("404 error") == "model_not_found"
def test_model_not_found_keyword(self):
assert self._classify("model not found") == "model_not_found"
def test_auth_error_api_key(self):
assert self._classify("invalid api key") == "auth_error"
def test_auth_error_401(self):
assert self._classify("401 unauthorized") == "auth_error"
def test_timeout(self):
assert self._classify("request timed out") == "timeout"
def test_rate_limit_429(self):
assert self._classify("429 too many requests") == "rate_limit"
def test_rate_limit_keyword(self):
assert self._classify("rate limit exceeded") == "rate_limit"
def test_connection_error(self):
assert self._classify("connection refused") == "connection_error"
def test_validation_error(self):
assert self._classify("invalid parameter") == "validation_error"
def test_unknown(self):
assert self._classify("some random error") == "unknown"
# ---------------------------------------------------------------------------
# _validate_iterations
# ---------------------------------------------------------------------------
class TestValidateIterations:
def _vi(self, val, max_val=20):
from local_deep_research.mcp.server import _validate_iterations
return _validate_iterations(val, max_val)
def test_none_returns_none(self):
assert self._vi(None) is None
def test_valid_value(self):
assert self._vi(5) == 5
def test_exceeds_max_raises(self):
from local_deep_research.mcp.server import ValidationError
with pytest.raises(ValidationError, match="cannot exceed"):
self._vi(21, max_val=20)
def test_zero_raises(self):
from local_deep_research.mcp.server import ValidationError
with pytest.raises(ValidationError, match="positive integer"):
self._vi(0)
def test_negative_raises(self):
from local_deep_research.mcp.server import ValidationError
with pytest.raises(ValidationError):
self._vi(-3)
def test_non_integer_raises(self):
from local_deep_research.mcp.server import ValidationError
with pytest.raises(ValidationError):
self._vi(2.5)
def test_exact_max_allowed(self):
assert self._vi(20, max_val=20) == 20
# ---------------------------------------------------------------------------
# _validate_questions_per_iteration
# ---------------------------------------------------------------------------
class TestValidateQPI:
def _vqpi(self, val):
from local_deep_research.mcp.server import (
_validate_questions_per_iteration,
)
return _validate_questions_per_iteration(val)
def test_none_returns_none(self):
assert self._vqpi(None) is None
def test_valid(self):
assert self._vqpi(3) == 3
def test_zero_raises(self):
from local_deep_research.mcp.server import ValidationError
with pytest.raises(ValidationError):
self._vqpi(0)
def test_exceeds_10_raises(self):
from local_deep_research.mcp.server import ValidationError
with pytest.raises(ValidationError, match="cannot exceed 10"):
self._vqpi(11)
def test_exactly_10_allowed(self):
assert self._vqpi(10) == 10
# ---------------------------------------------------------------------------
# _validate_max_results
# ---------------------------------------------------------------------------
class TestValidateMaxResults:
def _vmr(self, val):
from local_deep_research.mcp.server import _validate_max_results
return _validate_max_results(val)
def test_valid(self):
assert self._vmr(10) == 10
def test_zero_raises(self):
from local_deep_research.mcp.server import ValidationError
with pytest.raises(ValidationError):
self._vmr(0)
def test_exceeds_100_raises(self):
from local_deep_research.mcp.server import ValidationError
with pytest.raises(ValidationError, match="cannot exceed 100"):
self._vmr(101)
def test_exactly_100_allowed(self):
assert self._vmr(100) == 100
# ---------------------------------------------------------------------------
# _build_settings_overrides
# ---------------------------------------------------------------------------
class TestBuildSettingsOverrides:
def test_empty_params_returns_empty_dict(self):
from local_deep_research.mcp.server import _build_settings_overrides
result = _build_settings_overrides()
assert result == {}
def test_iterations_added(self):
from local_deep_research.mcp.server import _build_settings_overrides
result = _build_settings_overrides(iterations=3)
assert result.get("search.iterations") == 3
def test_temperature_added(self):
from local_deep_research.mcp.server import _build_settings_overrides
result = _build_settings_overrides(temperature=0.5)
assert result.get("llm.temperature") == pytest.approx(0.5)
def test_qpi_added(self):
from local_deep_research.mcp.server import _build_settings_overrides
result = _build_settings_overrides(questions_per_iteration=4)
assert result.get("search.questions_per_iteration") == 4
# ---------------------------------------------------------------------------
# analyze_documents empty collection_name
# ---------------------------------------------------------------------------
class TestAnalyzeDocumentsValidation:
def test_empty_collection_name_returns_error(self):
from local_deep_research.mcp.server import analyze_documents
result = analyze_documents(query="test query", collection_name="")
assert result["status"] == "error"
assert result["error_type"] == "validation_error"
def test_whitespace_collection_name_returns_error(self):
from local_deep_research.mcp.server import analyze_documents
result = analyze_documents(query="test query", collection_name=" ")
assert result["status"] == "error"
assert result["error_type"] == "validation_error"
# ---------------------------------------------------------------------------
# generate_report searches_per_section validation
# ---------------------------------------------------------------------------
class TestGenerateReportValidation:
def test_searches_per_section_zero_returns_error(self):
from local_deep_research.mcp.server import generate_report
result = generate_report(query="test", searches_per_section=0)
assert result["status"] == "error"
assert result["error_type"] == "validation_error"
def test_searches_per_section_over_10_returns_error(self):
from local_deep_research.mcp.server import generate_report
result = generate_report(query="test", searches_per_section=11)
assert result["status"] == "error"
assert result["error_type"] == "validation_error"