"""Contract tests for the programmatic SDK report entry point (#3665).

Mirrors the MCP ``generate_report`` contract test: the SDK
``generate_report`` returns the in-memory report generator's assembled
``content`` verbatim — including the ``## Sources`` block — without a DB
read or any stripping. Pins the SDK-keeps-assembled-shape invariant the
audit confirmed.
"""

from unittest.mock import MagicMock, patch

import local_deep_research.api.research_functions as rf


def test_generate_report_content_includes_sources():
    assembled = (
        "# Research Report\n\n## Introduction\n\nBody text.\n\n"
        "## Sources\n\n[1] https://src.example\n\n"
        "## Research Metrics\n\nSearch Iterations: 2\n"
    )

    fake_system = MagicMock()
    fake_system.analyze_topic.return_value = {"findings": "x"}

    fake_generator = MagicMock()
    fake_generator.generate_report.return_value = {
        "content": assembled,
        "metadata": {"query": "q"},
    }

    # Mock the research pipeline so no real search/LLM work runs; the SDK must
    # pass the generator's assembled content straight through.
    with (
        patch.object(rf, "_init_search_system", return_value=fake_system),
        patch.object(
            rf, "IntegratedReportGenerator", return_value=fake_generator
        ),
        patch.object(rf, "_close_system"),
    ):
        result = rf.generate_report(query="q", settings_snapshot={})

    assert "content" in result
    # Verbatim passthrough: the SDK returns the generator's assembled content
    # unmodified. Full equality catches truncation/stripping, not just the
    # absence of the ## Sources header.
    assert result["content"] == assembled
