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
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:
@@ -0,0 +1,334 @@
|
||||
"""
|
||||
Tests for citation_handler.py
|
||||
|
||||
Tests cover:
|
||||
- CitationHandler initialization
|
||||
- Handler type selection
|
||||
- Method delegation
|
||||
"""
|
||||
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
|
||||
class TestCitationHandlerInit:
|
||||
"""Tests for CitationHandler initialization."""
|
||||
|
||||
def test_default_handler_type(self):
|
||||
"""Test default handler type is standard."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
handler = CitationHandler(mock_llm)
|
||||
|
||||
mock_handler_class.assert_called_once()
|
||||
assert handler._handler == mock_handler
|
||||
|
||||
def test_explicit_standard_handler(self):
|
||||
"""Test explicit standard handler type."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, handler_type="standard")
|
||||
|
||||
mock_handler_class.assert_called_once()
|
||||
|
||||
def test_forced_handler_type(self):
|
||||
"""Test forced handler type."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.forced_answer_citation_handler.ForcedAnswerCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, handler_type="forced")
|
||||
|
||||
mock_handler_class.assert_called_once()
|
||||
|
||||
def test_browsecomp_handler_type(self):
|
||||
"""Test browsecomp handler type maps to forced."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.forced_answer_citation_handler.ForcedAnswerCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, handler_type="browsecomp")
|
||||
|
||||
mock_handler_class.assert_called_once()
|
||||
|
||||
def test_precision_handler_type(self):
|
||||
"""Test precision handler type."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.precision_extraction_handler.PrecisionExtractionHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, handler_type="precision")
|
||||
|
||||
mock_handler_class.assert_called_once()
|
||||
|
||||
def test_simpleqa_handler_type(self):
|
||||
"""Test simpleqa handler type maps to precision."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.precision_extraction_handler.PrecisionExtractionHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, handler_type="simpleqa")
|
||||
|
||||
mock_handler_class.assert_called_once()
|
||||
|
||||
def test_unknown_handler_type_fallback(self):
|
||||
"""Test unknown handler type falls back to standard."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, handler_type="unknown_type")
|
||||
|
||||
# Called twice - once for unknown fallback
|
||||
assert mock_handler_class.call_count >= 1
|
||||
|
||||
def test_handler_type_from_settings_snapshot(self):
|
||||
"""Test handler type from settings snapshot."""
|
||||
mock_llm = Mock()
|
||||
settings_snapshot = {"citation.handler_type": "forced"}
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.forced_answer_citation_handler.ForcedAnswerCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, settings_snapshot=settings_snapshot)
|
||||
|
||||
mock_handler_class.assert_called_once()
|
||||
|
||||
def test_handler_type_from_settings_snapshot_dict_value(self):
|
||||
"""Test handler type from settings snapshot with dict value."""
|
||||
mock_llm = Mock()
|
||||
settings_snapshot = {"citation.handler_type": {"value": "precision"}}
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.precision_extraction_handler.PrecisionExtractionHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, settings_snapshot=settings_snapshot)
|
||||
|
||||
mock_handler_class.assert_called_once()
|
||||
|
||||
def test_handler_type_case_insensitive(self):
|
||||
"""Test handler type is case insensitive."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.forced_answer_citation_handler.ForcedAnswerCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, handler_type="FORCED")
|
||||
|
||||
mock_handler_class.assert_called_once()
|
||||
|
||||
|
||||
class TestCitationHandlerMethods:
|
||||
"""Tests for CitationHandler method delegation."""
|
||||
|
||||
def test_analyze_initial_delegation(self):
|
||||
"""Test analyze_initial delegates to handler."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler.analyze_initial.return_value = {"result": "test"}
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
handler = CitationHandler(mock_llm)
|
||||
result = handler.analyze_initial("test query", [])
|
||||
|
||||
mock_handler.analyze_initial.assert_called_once_with(
|
||||
"test query", []
|
||||
)
|
||||
assert result == {"result": "test"}
|
||||
|
||||
def test_analyze_followup_delegation(self):
|
||||
"""Test analyze_followup delegates to handler."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler.analyze_followup.return_value = {"result": "followup"}
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
handler = CitationHandler(mock_llm)
|
||||
result = handler.analyze_followup(
|
||||
"test question", [], "previous knowledge", 5
|
||||
)
|
||||
|
||||
mock_handler.analyze_followup.assert_called_once_with(
|
||||
"test question", [], "previous knowledge", 5
|
||||
)
|
||||
assert result == {"result": "followup"}
|
||||
|
||||
def test_backward_compatibility_methods_exposed(self):
|
||||
"""Test backward compatibility methods are exposed."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_create_docs = Mock()
|
||||
mock_format_sources = Mock()
|
||||
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = mock_create_docs
|
||||
mock_handler._format_sources = mock_format_sources
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
handler = CitationHandler(mock_llm)
|
||||
|
||||
assert handler._create_documents == mock_create_docs
|
||||
assert handler._format_sources == mock_format_sources
|
||||
|
||||
|
||||
class TestCitationHandlerSettings:
|
||||
"""Tests for CitationHandler settings handling."""
|
||||
|
||||
def test_empty_settings_snapshot(self):
|
||||
"""Test with empty settings snapshot."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, settings_snapshot={})
|
||||
|
||||
# Should use standard handler as default
|
||||
mock_handler_class.assert_called_once()
|
||||
|
||||
def test_settings_passed_to_handler(self):
|
||||
"""Test settings are passed to underlying handler."""
|
||||
mock_llm = Mock()
|
||||
settings_snapshot = {"some_setting": "value"}
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm, settings_snapshot=settings_snapshot)
|
||||
|
||||
call_kwargs = mock_handler_class.call_args[1]
|
||||
assert call_kwargs["settings_snapshot"] == settings_snapshot
|
||||
|
||||
def test_llm_passed_to_handler(self):
|
||||
"""Test LLM is passed to underlying handler."""
|
||||
mock_llm = Mock()
|
||||
|
||||
with patch(
|
||||
"local_deep_research.citation_handlers.standard_citation_handler.StandardCitationHandler"
|
||||
) as mock_handler_class:
|
||||
mock_handler = Mock()
|
||||
mock_handler._create_documents = Mock()
|
||||
mock_handler._format_sources = Mock()
|
||||
mock_handler_class.return_value = mock_handler
|
||||
|
||||
from local_deep_research.citation_handler import CitationHandler
|
||||
|
||||
CitationHandler(mock_llm)
|
||||
|
||||
call_args = mock_handler_class.call_args[0]
|
||||
assert call_args[0] == mock_llm
|
||||
Reference in New Issue
Block a user