""" Tests for search_utilities.py — format_links_to_markdown and format_findings edge cases not covered by the existing test_search_utilities.py and test_search_utilities_extended.py files. Tests cover: - format_links_to_markdown: None/empty URL handling, special characters, index aggregation for 'link' key fallback - format_findings: iteration numbering, question_by_iteration edge cases, findings with search results that have errors, malformed finding structures """ # --------------------------------------------------------------------------- # format_links_to_markdown — additional edge cases # --------------------------------------------------------------------------- class TestFormatLinksToMarkdownNoneUrls: """Tests for format_links_to_markdown with None/empty URLs.""" def test_none_url_skipped(self): """Links with None url are skipped.""" from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ {"title": "Valid", "url": "https://valid.com", "index": "1"}, {"title": "None URL", "url": None, "index": "2"}, ] result = format_links_to_markdown(links) assert "https://valid.com" in result assert "None URL" not in result def test_empty_string_url_skipped(self): """Links with empty string url are skipped.""" from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ {"title": "Empty URL", "url": "", "index": "1"}, {"title": "Good", "url": "https://good.com", "index": "2"}, ] result = format_links_to_markdown(links) assert "https://good.com" in result assert "Empty URL" not in result def test_no_url_or_link_key_skipped(self): """Links with neither 'url' nor 'link' key are skipped.""" from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ {"title": "No URL key", "index": "1"}, ] result = format_links_to_markdown(links) assert "No URL key" not in result class TestFormatLinksToMarkdownSpecialChars: """Tests for format_links_to_markdown with special characters.""" def test_url_with_query_params(self): """URLs with query parameters are preserved.""" from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ { "title": "Search", "url": "https://example.com/search?q=hello+world&lang=en", "index": "1", } ] result = format_links_to_markdown(links) assert "https://example.com/search?q=hello+world&lang=en" in result def test_url_with_fragment(self): """URLs with fragments are stripped in the Sources display. Fragments are anchor-only and have no effect on click-through landing pages; the canonical form drops them for a cleaner UI. """ from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ { "title": "Section", "url": "https://example.com/page#section-2", "index": "1", } ] result = format_links_to_markdown(links) assert "URL: https://example.com/page" in result assert "#section-2" not in result def test_title_with_special_markdown_chars(self): """Titles with markdown-special chars are included.""" from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ { "title": "Results [2024] — *Important*", "url": "https://example.com", "index": "1", } ] result = format_links_to_markdown(links) assert "Results [2024]" in result class TestFormatLinksToMarkdownIndexAggregation: """Tests for index aggregation in format_links_to_markdown.""" def test_link_key_fallback_aggregates_indices(self): """'link' key fallback still aggregates indices for same URL.""" from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ {"title": "Same", "link": "https://same.com", "index": "1"}, {"title": "Same", "link": "https://same.com", "index": "4"}, ] result = format_links_to_markdown(links) assert result.count("https://same.com") == 1 assert "1" in result assert "4" in result def test_mixed_url_and_link_keys(self): """Handles mix of 'url' and 'link' keys for same actual URL.""" from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ {"title": "First", "url": "https://a.com", "index": "1"}, {"title": "Second", "link": "https://b.com", "index": "2"}, ] result = format_links_to_markdown(links) assert "https://a.com" in result assert "https://b.com" in result # --------------------------------------------------------------------------- # format_findings — additional edge cases # --------------------------------------------------------------------------- class TestFormatFindingsIterationNumbering: """Tests for iteration numbering in format_findings.""" def test_single_iteration_with_questions(self): """Single iteration with questions formatted correctly.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) questions = {1: ["Q1", "Q2", "Q3"]} result = format_findings([], "Summary content", questions) assert "Iteration 1" in result assert "1. Q1" in result assert "2. Q2" in result assert "3. Q3" in result def test_non_sequential_iteration_numbers(self): """Non-sequential iteration numbers (e.g., 1, 3, 5) handled correctly.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) questions = { 1: ["First iter Q"], 3: ["Third iter Q"], 5: ["Fifth iter Q"], } result = format_findings([], "Summary", questions) assert "Iteration 1" in result assert "Iteration 3" in result assert "Iteration 5" in result assert "Iteration 2" not in result def test_zero_iteration_key(self): """Iteration 0 (used by IterDRAG) is formatted.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) questions = {0: ["Sub-query A", "Sub-query B"]} result = format_findings([], "Summary", questions) assert "Iteration 0" in result assert "Sub-query A" in result class TestFormatFindingsMalformedStructures: """Tests for malformed finding structures.""" def test_finding_missing_content_key(self): """Finding without 'content' key uses default.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) findings = [{"phase": "Phase 1", "search_results": []}] result = format_findings(findings, "Summary", {}) assert "No content available" in result def test_finding_missing_phase_key(self): """Finding without 'phase' key uses default.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) findings = [{"content": "Some content", "search_results": []}] result = format_findings(findings, "Summary", {}) assert "Unknown Phase" in result assert "Some content" in result def test_finding_with_only_question_field(self): """Finding with only 'question' field displays it.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) findings = [ { "phase": "Custom", "content": "Answer text", "question": "How does X work?", "search_results": [], } ] result = format_findings(findings, "Summary", {}) assert "How does X work?" in result assert "SEARCH QUESTION" in result def test_empty_questions_dict_shows_warning_section(self): """Empty questions dict (no iterations) omits section.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) result = format_findings([], "Summary", {}) assert "SEARCH QUESTIONS BY ITERATION" not in result def test_findings_with_search_results_error(self): """Findings with non-list search_results handled gracefully.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) findings = [ { "phase": "Search", "content": "Content", "search_results": None, # None instead of list } ] # Should not crash result = format_findings(findings, "Summary", {}) assert "Content" in result # --------------------------------------------------------------------------- # _format_quality_tag — journal quality tags in source lists # --------------------------------------------------------------------------- class TestFormatQualityTag: """Test the _format_quality_tag helper for source list quality indicators.""" def test_none_returns_empty(self): from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) assert _format_quality_tag(None) == "" def test_elite_tier(self): from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) assert "Q1" in _format_quality_tag(10) assert "Q1" in _format_quality_tag(9) def test_strong_tier(self): from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) assert "Q1" in _format_quality_tag(7) assert "Q1" in _format_quality_tag(8) def test_moderate_tier(self): from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) assert "Q2" in _format_quality_tag(5) assert "Q2" in _format_quality_tag(6) def test_default_unknown_tier(self): """Score 4 (JOURNAL_QUALITY_DEFAULT) is rendered as [Unranked ★].""" from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) assert _format_quality_tag(4) == " [Unranked ★]" def test_predatory_tier(self): """Score 1 (predatory — normally auto-removed) falls back to Q4.""" from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) assert "Q4" in _format_quality_tag(1) def test_score_boundary_5_is_q2_not_unranked(self): """Score 5 crosses the Q2 threshold; must not fall through to Unranked.""" from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) assert _format_quality_tag(5) == " [Q2 ★★★]" def test_score_3_renders_unranked_not_q4(self): """Score 3 is the filter's 'no scoring data' fallback — rendered as Unranked rather than Q4 so it reads as "we don't know this venue" rather than "we know it's low-quality".""" from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) assert _format_quality_tag(3) == " [Unranked ★]" def test_preprint_sentinel(self): """QUALITY_PREPRINT marks results with no journal_ref at all.""" from local_deep_research.utilities.search_utilities import ( QUALITY_PREPRINT, _format_quality_tag, ) tag = _format_quality_tag(QUALITY_PREPRINT) assert "preprint" in tag assert "not in journal catalog" in tag def test_pending_sentinel(self): from local_deep_research.utilities.search_utilities import ( QUALITY_PENDING, _format_quality_tag, ) assert "downloading" in _format_quality_tag(QUALITY_PENDING) def test_out_of_range_value_surfaces_raw(self): """Out-of-set inputs must not silently bucket into Q4 — the catch-all renders ``[quality=]`` so bad scoring logic is visible in the output. """ from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) tag = _format_quality_tag(99) assert "quality=" in tag assert "99" in tag def test_every_valid_score_has_explicit_branch(self): """Every value in VALID_QUALITY_SCORES must map to a real tier tag — none should fall through to the debug catch-all. """ from local_deep_research.constants import VALID_QUALITY_SCORES from local_deep_research.utilities.search_utilities import ( _format_quality_tag, ) for score in VALID_QUALITY_SCORES: tag = _format_quality_tag(score) assert "quality=" not in tag, ( f"score {score} fell through to the debug catch-all: {tag!r}" ) # --------------------------------------------------------------------------- # format_links_to_markdown — dedup via canonical URL key # --------------------------------------------------------------------------- class TestFormatLinksDedupCanonical: """Canonicalized dedup: slight URL variants collapse to one Sources entry.""" def setup_method(self): # canonical_url_key is cached across tests; clear so each test starts # from a clean slate (otherwise earlier test inputs can pollute the # expected-output behavior if we ever depend on cache-miss timing). from local_deep_research.utilities.url_utils import canonical_url_key canonical_url_key.cache_clear() def test_dedup_trailing_slash(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ {"title": "Page", "url": "https://x.com/p", "index": "1"}, {"title": "Page", "url": "https://x.com/p/", "index": "2"}, ] result = format_links_to_markdown(links) # One entry, two indices. assert result.count("URL: https://x.com/p") == 1 assert "[1, 2]" in result def test_dedup_tracking_params(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ { "title": "Vox", "url": "https://www.vox.com/a?utm_source=g&utm_medium=s", "index": "1", }, {"title": "Vox", "url": "https://www.vox.com/a", "index": "2"}, ] result = format_links_to_markdown(links) assert "[1, 2]" in result # Canonical (clean) URL is displayed — tracking params stripped. assert "utm_source" not in result assert "utm_medium" not in result assert "URL: https://www.vox.com/a" in result def test_dedup_fragment_variants(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ {"title": "Wiki", "url": "https://x.com/p", "index": "1"}, { "title": "Wiki", "url": "https://x.com/p#section", "index": "2", }, ] result = format_links_to_markdown(links) assert "[1, 2]" in result def test_dedup_default_port(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ {"title": "Site", "url": "https://x.com/p", "index": "1"}, {"title": "Site", "url": "https://x.com:443/p", "index": "2"}, ] result = format_links_to_markdown(links) assert "[1, 2]" in result def test_distinct_urls_stay_distinct(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ {"title": "A", "url": "https://x.com/a", "index": "1"}, {"title": "B", "url": "https://x.com/b", "index": "2"}, ] result = format_links_to_markdown(links) assert "https://x.com/a" in result assert "https://x.com/b" in result assert "[1, 2]" not in result def test_display_shows_canonical_url_not_raw(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) # Even when the utm-bearing variant comes first, the Sources # section shows the canonical (tracking-stripped) URL — cleaner # UI, identical click-through behavior. links = [ { "title": "Article", "url": "https://x.com/a?utm_source=g", "index": "1", }, {"title": "Article", "url": "https://x.com/a", "index": "2"}, ] result = format_links_to_markdown(links) assert "URL: https://x.com/a\n" in result assert "utm_source" not in result def test_display_strips_userinfo(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) # Userinfo in a URL would leak credentials if displayed. Canonical # form drops it, so the Sources section is always safe. links = [ { "title": "Internal", "url": "https://user:secret@internal.example.com/p", "index": "1", } ] result = format_links_to_markdown(links) assert "secret" not in result assert "user:" not in result assert "URL: https://internal.example.com/p" in result def test_ref_param_not_stripped(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) # ?ref= on GitHub is a branch selector, not a tracker. links = [ { "title": "Repo on main", "url": "https://github.com/o/r?ref=main", "index": "1", }, { "title": "Repo on dev", "url": "https://github.com/o/r?ref=dev", "index": "2", }, ] result = format_links_to_markdown(links) # Must remain two separate entries. assert "ref=main" in result assert "ref=dev" in result assert "[1, 2]" not in result # --------------------------------------------------------------------------- # format_findings — exact character-by-character output # --------------------------------------------------------------------------- class TestFormatFindingsExactOutput: """Character-by-character tests of the markdown produced by ``format_findings`` for predetermined inputs. Locks in the exact layout (indentation, blank lines, ``[1]`` citation markers, the 80-char ``_`` separator) so a renderer regression — even a single extra newline or a moved citation — fails loudly. """ def test_exact_output_minimal_findings(self): """One finding, one source, one iteration, one question.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) findings_list = [ { "phase": "Initial", "content": "Qubits enable quantum computing [1].", "search_results": [ { "title": "Qubit Basics", "link": "https://example.com/q", "index": "1", }, ], }, ] synthesized_content = "Quantum computing uses qubits [1]." questions_by_iteration = {1: ["What is a qubit?"]} # Expected output is the verbatim string format_findings produces # for the inputs above. Anchored to today's exact layout — any # change (added blank line, moved citation, renamed section # header) will fail this test, which is the point. expected = ( "Quantum computing uses qubits [1].\n" "\n" "[1] Qubit Basics (source nr: 1)\n" " URL: https://example.com/q\n" "\n" "\n" "\n" "\n" "## SEARCH QUESTIONS BY ITERATION\n" "\n" "\n" " #### Iteration 1:\n" "1. What is a qubit?\n" "\n" "\n" "\n" "## DETAILED FINDINGS\n" "\n" "\n" "### Initial\n" "\n" "\n" "\n" "\n" "Qubits enable quantum computing [1].\n" "\n" "### SOURCES USED IN THIS SECTION:\n" "[1] Qubit Basics (source nr: 1)\n" " URL: https://example.com/q\n" "\n" "\n" "\n" "\n" + ("_" * 80) + "\n" "\n" "## ALL SOURCES:\n" "[1] Qubit Basics (source nr: 1)\n" " URL: https://example.com/q\n" "\n" "\n" ) actual = format_findings( findings_list, synthesized_content, questions_by_iteration ) assert actual == expected, ( f"format_findings output drifted from the locked-in layout.\n" f"--- expected ---\n{expected!r}\n" f"--- actual ---\n{actual!r}" ) def test_citations_in_synthesized_content_preserved(self): """``[1]`` and ``[2]`` markers in the synthesized content reach the final output unchanged. Independent narrower assertion to catch citation-handling regressions even when the broader exact- match test is in flux for unrelated layout reasons.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) synthesized = "First fact [1]. Second fact [2]. Third fact [1]." result = format_findings( findings_list=[], synthesized_content=synthesized, questions_by_iteration={}, ) # The synthesized content is the very first thing written. assert result.startswith(synthesized + "\n\n"), ( f"Synthesized content (with citations) was rewritten or " f"prefixed by format_findings: result starts with " f"{result[: len(synthesized) + 20]!r}" ) assert result.count("[1]") == 2 assert result.count("[2]") == 1 def test_source_indices_match_citation_markers(self): """When a finding's search_results have indices ``"1"`` and ``"2"``, format_links_to_markdown emits ``[1]`` and ``[2]`` — these should align with the citation markers in the synthesized content. Tests the citation→source alignment that makes the markdown navigable.""" from local_deep_research.utilities.search_utilities import ( format_findings, ) findings_list = [ { "phase": "Initial", "content": "Body referencing [1] and [2].", "search_results": [ { "title": "Source One", "link": "https://example.com/one", "index": "1", }, { "title": "Source Two", "link": "https://example.com/two", "index": "2", }, ], }, ] result = format_findings( findings_list, synthesized_content="See [1] and [2].", questions_by_iteration={}, ) # Both [1] and [2] appear in source listings, attached to the # right titles and URLs. assert "[1] Source One" in result assert "https://example.com/one" in result assert "[2] Source Two" in result assert "https://example.com/two" in result # And the synthesized [1]/[2] citations at the top survive. assert result.startswith("See [1] and [2].\n\n") class TestFormatLinksToMarkdownCollections: """Tests for the optional ``Collection:`` line surfaced for RAG / library results so the source-tagged citation mode can read the collection name back from the rendered sources block.""" def test_emits_collection_line_when_metadata_present(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ { "title": "Local Paper", "url": "/library/document/abc123", "index": "1", "metadata": {"collection_name": "My Papers"}, }, ] result = format_links_to_markdown(links) assert "URL: /library/document/abc123" in result assert "Collection: My Papers" in result def test_no_collection_line_when_metadata_absent(self): from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) # Plain web hit, no metadata. links = [ { "title": "Web Page", "url": "https://example.com/page", "index": "1", }, ] result = format_links_to_markdown(links) assert "URL: https://example.com/page" in result assert "Collection:" not in result def test_no_collection_line_when_metadata_lacks_collection_name(self): """metadata may exist for other reasons (engine_name, score, etc.) without carrying a collection name. Don't emit the line then.""" from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ { "title": "Web Page", "url": "https://example.com/page", "index": "1", "metadata": {"engine_name": "web", "score": 0.91}, }, ] result = format_links_to_markdown(links) assert "Collection:" not in result def test_first_non_empty_collection_wins_per_url(self): """Two hits for the same canonical URL — the first source with a non-empty collection name sets it; later hits don't overwrite. Mirrors how title and journal_quality work.""" from local_deep_research.utilities.search_utilities import ( format_links_to_markdown, ) links = [ { "title": "Doc", "url": "/library/document/abc", "index": "1", "metadata": {"collection_name": "first"}, }, { "title": "Doc", "url": "/library/document/abc", "index": "2", "metadata": {"collection_name": "second"}, }, ] result = format_links_to_markdown(links) # Single entry (URLs deduped), carries the first collection. assert "Collection: first" in result assert "Collection: second" not in result