File size: 4,168 Bytes
4dc8e99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from __future__ import annotations

import json
import os
import uuid
from datetime import datetime, timezone
from pathlib import Path

os.environ["DEBUG"] = "false"

from db.models import AnalysisRecord
from services import report_service


def _report_dir() -> Path:
    path = Path("backend") / "test_outputs" / f"reports_{uuid.uuid4().hex}"
    path.mkdir(parents=True, exist_ok=True)
    return path


def _record(payload: dict) -> AnalysisRecord:
    return AnalysisRecord(
        id=17,
        user_id=1,
        media_type=payload.get("media_type", "text"),
        verdict=payload["verdict"]["label"],
        authenticity_score=float(payload["verdict"]["authenticity_score"]),
        result_json=json.dumps(payload),
    )


def _text_payload() -> dict:
    return {
        "analysis_id": "analysis-text-17",
        "record_id": 17,
        "media_type": "text",
        "timestamp": datetime(2026, 4, 30, 10, 0, tzinfo=timezone.utc).isoformat(),
        "verdict": {
            "label": "Very Likely Fake",
            "severity": "critical",
            "authenticity_score": 14,
            "model_confidence": 0.91,
            "model_label": "fake",
        },
        "explainability": {
            "original_text": "BREAKING!!! THIS SHOCKING claim is spreading without verified sourcing.",
            "fake_probability": 0.86,
            "top_label": "fake",
            "all_scores": {"fake": 0.86, "real": 0.14},
            "keywords": ["claim", "verified sourcing"],
            "sensationalism": {
                "score": 82,
                "level": "High",
                "exclamation_count": 3,
                "caps_word_count": 2,
                "clickbait_matches": 1,
                "emotional_word_count": 1,
                "superlative_count": 0,
            },
            "manipulation_indicators": [
                {
                    "pattern_type": "emotional_manipulation",
                    "matched_text": "SHOCKING",
                    "start_pos": 17,
                    "end_pos": 25,
                    "severity": "high",
                    "description": "Loaded language is used to heighten emotion before evidence is shown.",
                }
            ],
            "detected_language": "en",
        },
        "llm_summary": {
            "paragraph": "The claim uses urgent wording and lacks corroboration from reliable reporting.",
            "bullets": ["High sensationalism", "Trusted-source match is weak"],
            "model_used": "gemini-test",
        },
        "trusted_sources": [
            {
                "source_name": "Reuters",
                "title": "Verified reporting about the event",
                "url": "https://www.reuters.com/world/example-report",
                "description": "Independent report used for comparison.",
                "published_at": "2026-04-29",
                "relevance_score": 0.92,
            }
        ],
        "processing_summary": {
            "stages_completed": ["classification", "keyword_extraction", "news_lookup"],
            "total_duration_ms": 1842,
            "model_used": "test-text-model",
            "models_used": ["test-text-model"],
            "calibrator_applied": False,
        },
        "responsible_ai_notice": "DeepShield Responsible-AI Notice",
    }


def test_generate_report_creates_pdf_with_active_trusted_source_link(monkeypatch):
    monkeypatch.setattr(report_service.settings, "REPORT_DIR", str(_report_dir()))

    path = report_service.generate_report(_record(_text_payload()))

    data = path.read_bytes()
    assert data.startswith(b"%PDF")
    assert b"/URI (https://www.reuters.com/world/example-report)" in data


def test_report_pdf_contains_required_text_context_and_pipeline(monkeypatch):
    monkeypatch.setattr(report_service.settings, "REPORT_DIR", str(_report_dir()))

    path = report_service.generate_report(_record(_text_payload()))

    text = path.read_bytes().decode("latin-1", errors="ignore")
    assert "Analyzed Media Context" in text
    assert "BREAKING!!! THIS SHOCKING claim" in text
    assert "classification" in text
    assert "news_lookup" in text