"""데모 시더의 심각도가 실제 제품과 같은가. 시더는 데모·스크린샷·UI 검토에 쓰는 데이터를 만든다. 여기 심각도가 엣지와 다르면 검토자는 제품이 실제로 내지 않는 등급을 보고 판단하게 된다. 실제로 7종이 어긋나 있었고, 그중 `fall` 이 위급으로 찍혀 1.2.0 의 요점(넘어짐 HIGH / 추락 CRITICAL)이 데모에서 지워져 있었다. 라벨과 달리 심각도는 어긋나도 화면이 깨지지 않는다 — 그래서 사람 눈으로는 잡히지 않고 이 테스트가 필요하다. """ import re from pathlib import Path from edge.events import EventType, Severity, _SEVERITY ROOT = Path(__file__).resolve().parents[1] SEEDER = ROOT / "server" / "tools" / "seed_demo.php" # 서버만 발행하는 유형 — 엣지 enum 에 없다. SERVER_ONLY = {"unacked_escalation": "critical", "multi_down": "critical"} def _seeder_map() -> dict[str, str]: src = SEEDER.read_text(encoding="utf-8") m = re.search(r"\$severityOf\s*=\s*\[(.*?)\];", src, re.S) assert m, "seed_demo.php 의 $severityOf 배열을 찾지 못했습니다 (리팩터되었나요?)" return dict(re.findall(r"'([a-z_]+)'\s*=>\s*'([a-z]+)'", m.group(1))) def _expected() -> dict[str, str]: out = {e.value: _SEVERITY.get(e, Severity.INFO).value for e in EventType} out.update(SERVER_ONLY) return out def test_seeder_severity_matches_the_edge(): seeder, expected = _seeder_map(), _expected() wrong = {k: (v, expected[k]) for k, v in seeder.items() if k in expected and v != expected[k]} assert not wrong, ( "데모 시더가 제품과 다른 심각도를 씁니다 (유형: 시더 -> 제품): " + ", ".join(f"{k}: {a} -> {b}" for k, (a, b) in sorted(wrong.items()))) def test_seeder_covers_every_type(): seeder, expected = _seeder_map(), _expected() missing = set(expected) - set(seeder) assert not missing, ( f"시더에 심각도가 없는 유형: {sorted(missing)} — " "빠지면 기본값으로 조용히 잘못된 등급이 찍힙니다") def test_seeder_has_no_unknown_types(): seeder, expected = _seeder_map(), _expected() extra = set(seeder) - set(expected) assert not extra, f"시더에만 있는 유형(오타이거나 삭제된 유형): {sorted(extra)}"