File size: 7,319 Bytes
b46b0ef f8d79e1 b46b0ef eef20d7 bd2c14a eef20d7 bd2c14a eef20d7 bd2c14a eef20d7 7880373 bd2c14a 7880373 bd2c14a f8d79e1 474b520 bd2c14a f8d79e1 7880373 bd2c14a 7880373 bd2c14a f8d79e1 | 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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | """Unit tests for dashboard/components.py HTML helpers."""
from __future__ import annotations
import pytest
from unittest.mock import patch, MagicMock
def test_ai_badge_default_label():
from dashboard.components import ai_badge
html = ai_badge()
assert "β¦ AI Synthesis" in html
assert "#7c3aed" in html
assert "#ede9fe" in html
def test_ai_badge_custom_label():
from dashboard.components import ai_badge
html = ai_badge("AI")
assert "β¦ AI" in html
assert "#7c3aed" in html
def test_interpretation_card_contains_badge_and_content():
from dashboard.components import interpretation_card
html = interpretation_card("What matters most", "<p>Some insight</p>")
assert "β¦ AI Synthesis" in html
assert "#8b5cf6" in html # purple border (PURPLE token value)
# card background is now white (#ffffff), not lavender AI_BG
assert "What matters most" in html
assert "<p>Some insight</p>" in html
def test_interpretation_card_custom_badge_label():
from dashboard.components import interpretation_card
html = interpretation_card("Language shift", "<p>tone changed</p>", badge_label="AI")
assert "β¦ AI" in html
assert "Language shift" in html
def _render_signal(sig) -> str:
"""Render a Signal through signal_card and return the produced HTML."""
import streamlit as st
from dashboard.components import signal_card
with patch.object(st, "markdown") as mock_md:
signal_card(sig)
return mock_md.call_args[0][0]
def test_signal_card_tension_variant():
"""Tension variant: two-sided body, exactly one β¦ AI badge in the header."""
from dashboard.signal_feed import Signal
html = _render_signal(Signal(
kind="tension",
headline="Revenue beat hides quality decline",
stance="mixed",
significance="HIGH",
extra={
"bullish_reading": "Strong top-line momentum",
"bearish_reading": "One-time item inflated result",
"bullish_evidence": {"evidence_snippet": "q1", "reliability": "HIGH", "source": "10-Q"},
"bearish_evidence": {"evidence_snippet": "q2", "reliability": "HIGH", "source": "10-Q"},
},
))
assert "β¦ AI Β· experimental" in html
assert html.count("β¦ AI") == 1 # badge is in the outer header, not per reading panel
assert "Strong top-line momentum" in html
assert "One-time item inflated result" in html
assert "Surface reading" in html
assert "Deeper reading" in html
assert "Material" in html # priority label, not raw HIGH/MED/LOW
# mixed stance β amber accent, never bull green or bear red on the frame
assert "#f59e0b" in html
def test_signal_card_quality_variant():
"""Quality variant: assessment chip + rationale + AI badge (AI-assessed kind)."""
from dashboard.signal_feed import Signal
html = _render_signal(Signal(
kind="quality",
body="Management raised full-year guidance for the third consecutive quarter.",
stance="bull",
category="guidance_dynamics",
extra={"assessment": "positive"},
evidence_snippet="raised guidance",
source="10-Q", reliability="HIGH",
))
assert "Management raised full-year guidance" in html
assert "Guidance" in html # dimension label for guidance_dynamics
assert "β²" in html
assert "Positive" in html
assert "β¦ AI Β· experimental" in html # quality assessments are experimental AI
assert "#10b981" in html # bull stance β green accent
def test_signal_card_delta_variant_redline():
"""Delta variant: computed-metric box + before/after redline, no AI badge."""
from dashboard.signal_feed import Signal
html = _render_signal(Signal(
kind="delta",
headline="export controls",
body="2β8 occurrences (+300%)",
stance="bear",
significance="HIGH",
category="term_frequency",
before_text="limited exposure to export restrictions",
after_text="new export restrictions may materially affect revenue",
source="10-Q",
period_range="4Q2024 β 1Q2025",
))
assert "computed" in html
assert "2β8 occurrences" in html
assert "before" in html and "after" in html
assert "4Q2024 β 1Q2025" in html
assert "β¦ AI" not in html # deltas are deterministic, not AI
assert "Heuristic Β· validate" in html
def test_signal_card_risk_new_badge():
"""Risk variant: category chip + NEW badge when is_new."""
from dashboard.signal_feed import Signal
html = _render_signal(Signal(
kind="risk",
body="China exposure may affect supply chains.",
stance="bear",
significance="HIGH",
category="Geopolitical",
is_new=True,
source="10-K", reliability="HIGH", impact="HIGH",
))
assert "Geopolitical" in html
assert "NEW" in html
assert "#ef4444" in html # bear stance β red accent
# ββ New helper tests ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def test_eyebrow_label():
from dashboard.components import eyebrow_label
html = eyebrow_label("what changed")
assert "text-transform:uppercase" in html
assert "what changed" in html
assert "letter-spacing" in html
html_colored = eyebrow_label("section", color="#ef4444")
assert "#ef4444" in html_colored
def test_importance_marker_levels():
from dashboard.components import importance_marker
high = importance_marker("HIGH")
assert "Critical" in high
assert "#0f172a" in high
assert "β" in high
# monochrome only β no green or red signal colors
assert "#10b981" not in high
assert "#ef4444" not in high
medium = importance_marker("MEDIUM")
assert "Important" in medium
assert "#64748b" in medium
assert "β" in medium
low = importance_marker("LOW")
assert "Context" in low
assert "#94a3b8" in low
assert "β" in low
# Unknown / empty returns empty string
assert importance_marker("") == ""
def test_meta_row_formatting():
from dashboard.components import meta_row
result = meta_row("HIGH", "10-Q", "HIGH")
assert "High confidence" in result
assert "10-Q" in result
assert "Critical" in result # from importance_marker("HIGH")
# All empty β empty string
assert meta_row("", "", "") == ""
result2 = meta_row("MEDIUM", "transcript", "LOW")
assert "Med. confidence" in result2
assert "transcript" in result2
assert "Context" in result2 # from importance_marker("LOW")
def test_sort_by_impact_order():
from dashboard.components import sort_by_impact
items = [
{"impact": "HIGH", "name": "h"},
{"impact": "LOW", "name": "l"},
{"impact": "MEDIUM", "name": "m"},
{"name": "none"}, # missing "impact" key
]
original = list(items) # copy to check mutation
sorted_items = sort_by_impact(items)
assert [i.get("impact", "") for i in sorted_items] == ["HIGH", "MEDIUM", "LOW", ""]
# Original list must not be mutated
assert items == original
|