Ctrl K
ComunidadGuías…

tests/test_report_footer.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""
Tests for the report footer generator (production details in the output
language of the run).
"""

import sys
from pathlib import Path

import pytest

sys.path.insert(0, str(Path(__file__).parent.parent))

from src import output_language
from src.exporters.report_footer import (
    USE_CASE_LABELS,
    generate_markdown_footer,
)
from src.pipeline.analysis_pipeline import USE_CASE_REGISTRY
from src.pipeline.models import (
    HarvestContext,
    SubTask,
    TaskPlan,
    TaskResult,
    TaskState,
)


@pytest.fixture
def german(monkeypatch):
    monkeypatch.setenv("OUTPUT_LANGUAGES", "en,de")
    output_language.reload()
    yield
    monkeypatch.delenv("OUTPUT_LANGUAGES")
    output_language.reload()


def test_footer_minimal():
    """Footer with minimal data."""
    ctx = HarvestContext(query="test")
    footer = generate_markdown_footer(ctx)
    assert "How this report was produced" in footer
    from src.about import TOOL_NAME
    assert TOOL_NAME in footer
    assert "Important:" in footer


def test_footer_with_llm_usage():
    """Footer with LLM statistics."""
    ctx = HarvestContext(query="test")
    ctx.llm_usage = {
        "primary": {"model": "Qwen3-235B", "requests": 5,
                    "prompt_tokens": 10000, "completion_tokens": 2000},
        "harvest": {"model": "Qwen3-30B", "requests": 12,
                    "prompt_tokens": 30000, "completion_tokens": 5000},
    }
    footer = generate_markdown_footer(ctx)
    assert "17" in footer  # 5 + 12 calls
    assert "Qwen3-235B" in footer
    assert "Qwen3-30B" in footer
    assert "40,000" in footer  # input tokens
    assert "7,000" in footer   # output tokens


def test_footer_explainer_use_case():
    """Footer with explainer-specific data from the active task plan."""
    ctx = HarvestContext(query="Explain LLMs")
    ctx.use_case = "explainer"
    ctx.preflight_data = {
        "topic": "How do LLMs work?",
        "audience": "Undergraduates",
    }
    ctx.task_plan = TaskPlan(use_case="explainer", tasks=[
        SubTask(id="EXP_1", phase="explanation", description="?",
                prompt_template="?", prompt_params={"concept": "Tokenisation"}),
        SubTask(id="EXP_2", phase="explanation", description="?",
                prompt_template="?", prompt_params={"concept": "Embeddings"}),
    ])
    ctx.task_results = {
        "EXP_1": TaskResult(task_id="EXP_1", state=TaskState.DONE, tokens_used=300),
        "EXP_2": TaskResult(task_id="EXP_2", state=TaskState.DONE, tokens_used=350),
    }
    footer = generate_markdown_footer(ctx)
    assert "In-depth explanation" in footer
    assert "How do LLMs work?" in footer
    assert "Undergraduates" in footer
    assert "Tokenisation" in footer and "Embeddings" in footer
    assert "2 successful" in footer


def test_footer_with_failed_tasks_and_counts_lines():
    """Failed/skipped tasks are counted; options are counted per line, not per character."""
    ctx = HarvestContext(query="test")
    ctx.use_case = "decision_analysis"
    ctx.task_results = {
        "T1": TaskResult(task_id="T1", state=TaskState.DONE),
        "T2": TaskResult(task_id="T2", state=TaskState.FAILED, error="?"),
        "T3": TaskResult(task_id="T3", state=TaskState.SKIPPED),
    }
    ctx.preflight_data = {"options": "Option A\nOption B", "criteria": "c1\nc2\nc3"}
    footer = generate_markdown_footer(ctx)
    assert "Decision analysis" in footer
    assert "1 successful" in footer and "1 failed" in footer and "1 skipped" in footer
    assert "**Number of options:** 2" in footer
    assert "**Number of criteria:** 3" in footer


def test_footer_grant_proposal():
    """Footer for a grant proposal shows the funder and duration."""
    ctx = HarvestContext(query="test")
    ctx.use_case = "grant_proposal"
    ctx.preflight_data = {"funder": "Example Foundation", "duration": "36 months"}
    footer = generate_markdown_footer(ctx)
    assert "Grant proposal" in footer
    assert "Example Foundation" in footer
    assert "36 months" in footer


def test_plan_confirmation_only_when_confirmed():
    """'Confirmed by the user' appears only if the plan gate was actually passed."""
    ctx = HarvestContext(query="test")
    ctx.use_case = "explainer"
    ctx.task_plan = TaskPlan(use_case="explainer", tasks=[])
    assert "confirmed by the user" not in generate_markdown_footer(ctx)
    ctx.plan_confirmed = True
    assert "confirmed by the user" in generate_markdown_footer(ctx)


def test_footer_in_german(german):
    """With German as the output language the footer is German."""
    ctx = HarvestContext(query="test")
    ctx.use_case = "decision_analysis"
    ctx.output_language = "de"
    ctx.preflight_data = {"options": "A\nB"}
    footer = generate_markdown_footer(ctx)
    assert "Hinweise zur Erstellung" in footer
    assert "Entscheidungsanalyse" in footer
    assert "Anzahl Optionen" in footer
    assert "Wichtiger Hinweis" in footer


def test_use_case_labels_complete():
    """Every analysis use case has a label."""
    for uc in USE_CASE_REGISTRY:
        assert uc in USE_CASE_LABELS, f"label missing: {uc}"