项目文件夹

文件
wehub-resource-sync 7a0da7932b
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
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

649 行
20 KiB
Python

"""
Extended tests for utilities/search_utilities.py
Tests cover edge cases and scenarios not covered in the base test file:
- Phase parsing for Follow-up and Sub-query formats
- Invalid phase format handling
- Source aggregation behavior
- Edge cases in format_findings
"""
class TestFormatFindingsPhaseParsingFollowUp:
"""Tests for Follow-up Iteration phase parsing in format_findings."""
def test_followup_iteration_format_basic(self):
"""Test Follow-up Iteration X.Y format is parsed correctly."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Follow-up Iteration 1.1",
"content": "First follow-up content",
"search_results": [],
}
]
questions = {1: ["First question", "Second question"]}
result = format_findings(findings, "Summary", questions)
# The question should be displayed
assert "First question" in result
assert "First follow-up content" in result
def test_followup_iteration_second_question(self):
"""Test Follow-up Iteration X.2 shows second question."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Follow-up Iteration 1.2",
"content": "Second follow-up",
"search_results": [],
}
]
questions = {1: ["First question", "Second question", "Third question"]}
result = format_findings(findings, "Summary", questions)
assert "Second question" in result
def test_followup_iteration_multiple_iterations(self):
"""Test Follow-up Iteration across multiple iterations."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Follow-up Iteration 1.1",
"content": "Iter 1 Q1",
"search_results": [],
},
{
"phase": "Follow-up Iteration 2.1",
"content": "Iter 2 Q1",
"search_results": [],
},
]
questions = {
1: ["Iteration 1 Question 1"],
2: ["Iteration 2 Question 1"],
}
result = format_findings(findings, "Summary", questions)
assert "Iteration 1 Question 1" in result
assert "Iteration 2 Question 1" in result
def test_followup_iteration_missing_question_index(self):
"""Test Follow-up Iteration with question index out of bounds."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Follow-up Iteration 1.5", # Index 5 doesn't exist
"content": "Out of bounds",
"search_results": [],
}
]
questions = {1: ["Only one question"]}
# Should not raise, just skip showing question
result = format_findings(findings, "Summary", questions)
assert "Out of bounds" in result
# Should not crash
def test_followup_iteration_missing_iteration(self):
"""Test Follow-up Iteration with iteration not in questions dict."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Follow-up Iteration 3.1", # Iteration 3 doesn't exist
"content": "No matching iteration",
"search_results": [],
}
]
questions = {1: ["Question 1"]}
result = format_findings(findings, "Summary", questions)
assert "No matching iteration" in result
class TestFormatFindingsPhaseParsingSubQuery:
"""Tests for Sub-query phase parsing in format_findings."""
def test_subquery_format_basic(self):
"""Test Sub-query X format is parsed correctly."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Sub-query 1",
"content": "Sub-query content",
"search_results": [],
}
]
# IterDRAG stores sub-queries in iteration 0
questions = {0: ["First sub-query", "Second sub-query"]}
result = format_findings(findings, "Summary", questions)
assert "First sub-query" in result
assert "Sub-query content" in result
def test_subquery_second_question(self):
"""Test Sub-query 2 shows second question."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Sub-query 2",
"content": "Second sub-query content",
"search_results": [],
}
]
questions = {0: ["First", "Second", "Third"]}
result = format_findings(findings, "Summary", questions)
assert "Second" in result
def test_subquery_out_of_bounds(self):
"""Test Sub-query with index out of bounds."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Sub-query 10", # Index 10 doesn't exist
"content": "Out of bounds sub-query",
"search_results": [],
}
]
questions = {0: ["Only one"]}
result = format_findings(findings, "Summary", questions)
assert "Out of bounds sub-query" in result
def test_subquery_no_iteration_zero(self):
"""Test Sub-query when iteration 0 doesn't exist."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Sub-query 1",
"content": "Sub-query content",
"search_results": [],
}
]
questions = {1: ["Not iteration zero"]}
result = format_findings(findings, "Summary", questions)
assert "Sub-query content" in result
class TestFormatFindingsInvalidPhaseFormat:
"""Tests for invalid phase format handling in format_findings."""
def test_invalid_followup_format_non_numeric(self):
"""Test Follow-up Iteration with non-numeric parts."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Follow-up Iteration abc.def",
"content": "Invalid format content",
"search_results": [],
}
]
questions = {1: ["Question 1"]}
result = format_findings(findings, "Summary", questions)
assert "Invalid format content" in result
def test_invalid_followup_format_missing_dot(self):
"""Test Follow-up Iteration without dot separator."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Follow-up Iteration 1", # Missing .X
"content": "Missing dot content",
"search_results": [],
}
]
questions = {1: ["Question 1"]}
result = format_findings(findings, "Summary", questions)
assert "Missing dot content" in result
def test_invalid_subquery_format_non_numeric(self):
"""Test Sub-query with non-numeric index."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Sub-query abc",
"content": "Invalid sub-query content",
"search_results": [],
}
]
questions = {0: ["Question 1"]}
result = format_findings(findings, "Summary", questions)
assert "Invalid sub-query content" in result
def test_phase_with_special_characters(self):
"""Test phase with special characters."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Phase: Special <chars>",
"content": "Special content",
"search_results": [],
}
]
result = format_findings(findings, "Summary", {})
assert "Special content" in result
assert "Phase: Special <chars>" in result
def test_phase_none_value(self):
"""Test finding with None phase."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": None,
"content": "Content with None phase",
"search_results": [],
}
]
result = format_findings(findings, "Summary", {})
# Should use "Unknown Phase" default
assert "Content with None phase" in result
class TestFormatFindingsSourceAggregation:
"""Tests for source aggregation in format_findings."""
def test_aggregates_sources_from_multiple_findings(self):
"""Test sources are aggregated from multiple findings."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Search 1",
"content": "Content 1",
"search_results": [
{"title": "Source A", "link": "https://a.com", "index": "1"}
],
},
{
"phase": "Search 2",
"content": "Content 2",
"search_results": [
{"title": "Source B", "link": "https://b.com", "index": "2"}
],
},
]
result = format_findings(findings, "Summary", {})
assert "ALL SOURCES" in result
assert "https://a.com" in result
assert "https://b.com" in result
def test_deduplicates_sources(self):
"""Test duplicate sources are deduplicated."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Search 1",
"content": "Content 1",
"search_results": [
{"title": "Same", "link": "https://same.com", "index": "1"}
],
},
{
"phase": "Search 2",
"content": "Content 2",
"search_results": [
{"title": "Same", "link": "https://same.com", "index": "2"}
],
},
]
result = format_findings(findings, "Summary", {})
# URL should only appear once in the ALL SOURCES section
all_sources_section = (
result.split("ALL SOURCES")[1] if "ALL SOURCES" in result else ""
)
assert all_sources_section.count("https://same.com") == 1
def test_handles_finding_without_search_results(self):
"""Test findings without search_results key."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Search",
"content": "Content without search results",
# No search_results key
}
]
result = format_findings(findings, "Summary", {})
assert "Content without search results" in result
def test_handles_empty_search_results(self):
"""Test findings with empty search_results list."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Search",
"content": "Content with empty results",
"search_results": [],
}
]
result = format_findings(findings, "Summary", {})
assert "Content with empty results" in result
class TestFormatFindingsQuestionInFinding:
"""Tests for question field in finding itself."""
def test_displays_question_from_finding(self):
"""Test question from finding is displayed if not from phase."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Custom Phase",
"content": "Content here",
"question": "What is the meaning of life?",
"search_results": [],
}
]
result = format_findings(findings, "Summary", {})
assert "What is the meaning of life?" in result
assert "SEARCH QUESTION" in result
def test_phase_question_overrides_finding_question(self):
"""Test question from phase takes precedence over finding question."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Follow-up Iteration 1.1",
"content": "Content",
"question": "Question from finding",
"search_results": [],
}
]
questions = {1: ["Question from iteration"]}
result = format_findings(findings, "Summary", questions)
# Should show iteration question, not finding question
assert "Question from iteration" in result
def test_empty_question_field_ignored(self):
"""Test empty question field is ignored."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "Search",
"content": "Content",
"question": "",
"search_results": [],
}
]
result = format_findings(findings, "Summary", {})
assert "SEARCH QUESTION" not in result
class TestFormatFindingsEdgeCases:
"""Tests for edge cases in format_findings."""
def test_empty_synthesized_content(self):
"""Test with empty synthesized content."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
result = format_findings([], "", {})
# Should not crash with empty content
assert result is not None
def test_synthesized_content_with_newlines(self):
"""Test synthesized content with newlines is preserved."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
content = "Line 1\n\nLine 2\n\nLine 3"
result = format_findings([], content, {})
assert "Line 1" in result
assert "Line 2" in result
assert "Line 3" in result
def test_large_number_of_findings(self):
"""Test with large number of findings."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": f"Phase {i}",
"content": f"Content {i}",
"search_results": [],
}
for i in range(100)
]
result = format_findings(findings, "Summary", {})
assert "Phase 0" in result
assert "Phase 99" in result
assert "Content 0" in result
assert "Content 99" in result
def test_findings_with_all_none_values(self):
"""Test findings with all None values use defaults."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": None,
"content": None,
"search_results": None,
}
]
result = format_findings(findings, "Summary", {})
assert "Unknown Phase" in result or result is not None
def test_unicode_content_handling(self):
"""Test unicode content is handled correctly."""
from local_deep_research.utilities.search_utilities import (
format_findings,
)
findings = [
{
"phase": "搜索结果",
"content": "日本語テキスト с русским 🎉",
"search_results": [
{
"title": "日本語",
"link": "https://example.com",
"index": "1",
}
],
}
]
result = format_findings(findings, "概要 Summary", {})
assert "日本語テキスト" in result
assert "🎉" in result
class TestExtractLinksEdgeCases:
"""Additional edge case tests for extract_links_from_search_results."""
def test_handles_integer_index(self):
"""Test handles integer index instead of string."""
from local_deep_research.utilities.search_utilities import (
extract_links_from_search_results,
)
results = [
{
"title": "Test",
"link": "https://example.com",
"index": 1, # Integer instead of string
}
]
# This might fail if strip() is called on integer
# The function should handle this gracefully
try:
links = extract_links_from_search_results(results)
# If it succeeds, check the result
assert len(links) >= 0
except Exception:
# If it fails, that's also acceptable behavior
pass
def test_handles_mixed_key_formats(self):
"""Test handles results with different key formats."""
from local_deep_research.utilities.search_utilities import (
extract_links_from_search_results,
)
results = [
{"title": "Normal", "link": "https://normal.com", "index": "1"},
{
"title": " Spaces ",
"link": " https://spaces.com ",
"index": "2",
},
]
links = extract_links_from_search_results(results)
assert len(links) == 2
assert links[1]["title"] == "Spaces"
assert links[1]["url"] == "https://spaces.com"
class TestFormatLinksEdgeCases:
"""Additional edge case tests for format_links_to_markdown."""
def test_handles_untitled_default(self):
"""Test handles links without title using default."""
from local_deep_research.utilities.search_utilities import (
format_links_to_markdown,
)
links = [
{"url": "https://example.com", "index": "1"}
# No title
]
result = format_links_to_markdown(links)
assert "Untitled" in result or "https://example.com" in result
def test_multiple_indices_same_url(self):
"""Test multiple indices for same URL are aggregated."""
from local_deep_research.utilities.search_utilities import (
format_links_to_markdown,
)
links = [
{"title": "Same", "url": "https://same.com", "index": "1"},
{"title": "Same", "url": "https://same.com", "index": "3"},
{"title": "Same", "url": "https://same.com", "index": "5"},
]
result = format_links_to_markdown(links)
# URL should appear once with aggregated indices
assert result.count("https://same.com") == 1
# Should show multiple indices
assert "1" in result
assert "3" in result
assert "5" in result