Spaces:
Running
Running
| from __future__ import annotations | |
| from backend.rules import dashboard_rules | |
| from backend.utils.config_loader import load_scoring_config | |
| from tests.fixtures import bad_page, clean_page | |
| THRESHOLDS = load_scoring_config()["thresholds"] | |
| MAX_KPI = THRESHOLDS["dashboard"]["max_kpi_cards"] | |
| MIN_WS = THRESHOLDS["dashboard"]["min_whitespace_ratio"] | |
| def rule_ids(issues) -> list[str]: | |
| return [i.rule_id for i in issues] | |
| class TestCleanPage: | |
| def test_no_dashboard_issues(self): | |
| issues = dashboard_rules.analyze(clean_page(), THRESHOLDS) | |
| assert issues == [], f"Unexpected issues: {rule_ids(issues)}" | |
| class TestKpiCardOverload: | |
| def test_above_max_kpi_flagged(self): | |
| page = clean_page() | |
| page["kpi_card_count"] = MAX_KPI + 1 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| assert any(i.rule_id == "D1_kpi_card_overload" for i in issues) | |
| def test_at_max_kpi_not_flagged(self): | |
| page = clean_page() | |
| page["kpi_card_count"] = MAX_KPI | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| assert not any(i.rule_id == "D1_kpi_card_overload" for i in issues) | |
| def test_below_max_kpi_not_flagged(self): | |
| page = clean_page() | |
| page["kpi_card_count"] = MAX_KPI - 1 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| assert not any(i.rule_id == "D1_kpi_card_overload" for i in issues) | |
| def test_zero_kpi_cards_not_flagged(self): | |
| page = clean_page() | |
| page["kpi_card_count"] = 0 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| assert not any(i.rule_id == "D1_kpi_card_overload" for i in issues) | |
| def test_count_appears_in_message(self): | |
| page = clean_page() | |
| page["kpi_card_count"] = 12 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| d1 = next(i for i in issues if i.rule_id == "D1_kpi_card_overload") | |
| assert "12" in d1.message | |
| def test_severity_is_medium(self): | |
| from backend.models.issue import Severity | |
| page = clean_page() | |
| page["kpi_card_count"] = MAX_KPI + 1 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| d1 = next(i for i in issues if i.rule_id == "D1_kpi_card_overload") | |
| assert d1.severity == Severity.MEDIUM | |
| def test_bad_page_triggers_d1(self): | |
| issues = dashboard_rules.analyze(bad_page(), THRESHOLDS) | |
| assert any(i.rule_id == "D1_kpi_card_overload" for i in issues) | |
| class TestLowWhitespace: | |
| def test_below_min_whitespace_flagged(self): | |
| page = clean_page() | |
| page["whitespace_ratio"] = MIN_WS - 0.01 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| assert any(i.rule_id == "D2_low_whitespace" for i in issues) | |
| def test_at_min_whitespace_not_flagged(self): | |
| page = clean_page() | |
| page["whitespace_ratio"] = MIN_WS | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| assert not any(i.rule_id == "D2_low_whitespace" for i in issues) | |
| def test_above_min_whitespace_not_flagged(self): | |
| page = clean_page() | |
| page["whitespace_ratio"] = MIN_WS + 0.10 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| assert not any(i.rule_id == "D2_low_whitespace" for i in issues) | |
| def test_zero_whitespace_flagged(self): | |
| page = clean_page() | |
| page["whitespace_ratio"] = 0.0 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| assert any(i.rule_id == "D2_low_whitespace" for i in issues) | |
| def test_ratio_appears_in_evidence(self): | |
| page = clean_page() | |
| page["whitespace_ratio"] = 0.08 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| d2 = next(i for i in issues if i.rule_id == "D2_low_whitespace") | |
| assert "0.08" in d2.evidence | |
| def test_severity_is_high(self): | |
| from backend.models.issue import Severity | |
| page = clean_page() | |
| page["whitespace_ratio"] = 0.05 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| d2 = next(i for i in issues if i.rule_id == "D2_low_whitespace") | |
| assert d2.severity == Severity.HIGH | |
| def test_bad_page_triggers_d2(self): | |
| issues = dashboard_rules.analyze(bad_page(), THRESHOLDS) | |
| assert any(i.rule_id == "D2_low_whitespace" for i in issues) | |
| class TestBothRulesFire: | |
| def test_dense_dashboard_with_many_kpis_triggers_both(self): | |
| page = clean_page() | |
| page["kpi_card_count"] = MAX_KPI + 5 | |
| page["whitespace_ratio"] = 0.05 | |
| issues = dashboard_rules.analyze(page, THRESHOLDS) | |
| fired = rule_ids(issues) | |
| assert "D1_kpi_card_overload" in fired | |
| assert "D2_low_whitespace" in fired | |