File size: 3,175 Bytes
bb6a031
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Tests for `demo_data.py` — pure-Python helpers, no gradio dependency."""

from __future__ import annotations

import json
import os
import tempfile

import pytest

from demo_data import (
    empty_state_message,
    format_alert_card,
    format_response_card,
    format_truth_card,
    load_demo_examples,
)


def test_load_missing_file_returns_empty():
    assert load_demo_examples("/nonexistent/path/demo.json") == []


def test_load_handles_wrapped_payload():
    with tempfile.TemporaryDirectory() as td:
        p = os.path.join(td, "demo.json")
        with open(p, "w") as f:
            json.dump({"n": 1, "examples": [{"alert": {"alert_id": "A1"}, "events": []}]}, f)
        out = load_demo_examples(p)
        assert isinstance(out, list)
        assert out[0]["alert"]["alert_id"] == "A1"


def test_load_handles_bare_list():
    with tempfile.TemporaryDirectory() as td:
        p = os.path.join(td, "demo.json")
        with open(p, "w") as f:
            json.dump([{"alert": {"alert_id": "A1"}, "events": []}], f)
        out = load_demo_examples(p)
        assert len(out) == 1


def test_format_alert_card_includes_required_fields():
    alert = {
        "alert_id": "A-1",
        "category": "auth",
        "severity": "high",
        "host": "h1",
        "user": "u1",
        "summary": "Lots of failed logins",
    }
    events = [
        {
            "log_id": "L-1",
            "timestamp": "2026-04-25T12:00:00Z",
            "source": "auth",
            "event_type": "auth_failure",
            "fields": {"src_ip": "1.2.3.4", "user": "u1"},
        }
    ]
    md = format_alert_card(alert, events)
    assert "A-1" in md
    assert "high" in md
    assert "L-1" in md
    assert "auth_failure" in md
    assert "1.2.3.4" in md


def test_format_response_card_marks_correct_and_breakdown():
    resp = {
        "action": "block_ip",
        "cited_log_id": "L-1",
        "rationale": "Brute force pattern observed.",
        "reward": 1.1,
        "correct": True,
        "reward_breakdown": {"correct_action": 1.0, "correct_citation_bonus": 0.1},
        "raw_text": "Action: block_ip\nCitedLog: L-1\nRationale: Brute force pattern observed.",
    }
    md = format_response_card("OpenSOC", resp)
    assert "block_ip" in md
    assert "OK" in md  # correct emoji/marker
    assert "+1.10" in md
    assert "correct_action" in md


def test_format_response_card_marks_miss():
    resp = {
        "action": "dismiss",
        "cited_log_id": "L-1",
        "rationale": "Looks fine.",
        "reward": -1.0,
        "correct": False,
        "reward_breakdown": {"missed_malicious": -1.0},
    }
    md = format_response_card("Baseline", resp)
    assert "MISS" in md
    assert "-1.00" in md


def test_format_truth_card_smoke():
    md = format_truth_card({
        "ground_truth": "block_ip",
        "triggering_log_id": "L-2",
        "stage": "stage2_multi",
        "seed": 91234,
    })
    assert "block_ip" in md
    assert "L-2" in md
    assert "stage2_multi" in md


def test_empty_state_message_mentions_bake_demo():
    msg = empty_state_message()
    assert "bake_demo" in msg
    assert "placeholder" in msg