# backend/tests/test_triage.py — 트리아지 서비스 단위 from app.models import Notification, NotifyBucket from app.services.triage import classify_notification, detect_defer_pattern def test_sender_rule_wins(client, session): s, _ = session out = classify_notification(s, src="mail", sender="수아님", title="...") assert out["bucket"] == "now" # sr1 항상 즉시 def test_marketing_held(client, session): s, _ = session out = classify_notification(s, src="mail", sender="마케팅 · 프로모션", title="할인") assert out["bucket"] == "held" and out["held_by_rule"] == "sr5" def test_guard_defers_when_on(client, session): s, _ = session # 발신자 규칙에 안 걸리는 app src + guard on → later (집중 보호) out = classify_notification(s, src="app", sender="알수없음", title="x") assert out["bucket"] == "later" and out["why"] == "집중 보호 중" def test_cal_passes_guard(client, session): s, _ = session out = classify_notification(s, src="cal", sender="알수없음", title="회의 임박") assert out["bucket"] == "now" def test_defer_pattern(client, session): s, _ = session # later 알림 3건의 why 를 '내가 미룸'(같은 app)으로 바꿔 임계 도달 for nid in ("l1", "l3", "l6"): n = s.get(Notification, nid) n.app = "메일 · 개인" n.why = "내가 미룸" n.bucket = NotifyBucket.later s.add(n) s.commit() cands = detect_defer_pattern(s, threshold=3) assert any(c["count"] >= 3 and c["app"] == "메일 · 개인" for c in cands)