You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
# backend/tests/test_proactive.py — 능동 감지 + 수락 실체화
|
|
from sqlmodel import select
|
|
|
|
from app.models import CalEvent, FinanceCategory, FocusBlock, ProactiveCard, Task
|
|
from app.worker.jobs.proactive import run_proactive
|
|
|
|
|
|
def test_meeting_streak_card(session):
|
|
s, _ = session
|
|
for i, t in enumerate([("10:00", "11:00"), ("11:00", "12:00"), ("13:00", "14:00")]):
|
|
s.add(CalEvent(id=f"te{i}", day=9, start=t[0], end=t[1], title=f"회의{i}", cal="meeting"))
|
|
s.commit()
|
|
cards = run_proactive(s)
|
|
streak = [c for c in cards if c.kind == "schedule"]
|
|
assert streak and "미팅 3연속" in streak[0].title
|
|
assert streak[0].action_kind == "focus_block"
|
|
|
|
|
|
def test_pricey_bill_card(session):
|
|
s, _ = session
|
|
s.add(FinanceCategory(id="cat-x", name="쇼핑", amt=298000, pct=120, icon="bag", over=True))
|
|
s.commit()
|
|
cards = run_proactive(s)
|
|
bill = [c for c in cards if c.kind == "finance"]
|
|
assert bill and "평소보다 많아요" in bill[0].title and bill[0].tone == "amber"
|
|
|
|
|
|
def test_run_proactive_idempotent(session):
|
|
s, _ = session
|
|
for i in range(3):
|
|
s.add(
|
|
CalEvent(
|
|
id=f"te{i}", day=9, start=f"1{i}:00", end=f"1{i+1}:00", title="회의", cal="meeting"
|
|
)
|
|
)
|
|
s.commit()
|
|
run_proactive(s)
|
|
run_proactive(s) # 2회차
|
|
streaks = s.exec(select(ProactiveCard).where(ProactiveCard.id == "pc-streak")).all()
|
|
assert len(streaks) == 1 # 중복 생성 없음
|
|
|
|
|
|
def test_accept_focus_block_materializes(client, session):
|
|
s, _ = session
|
|
# 시드 pc1(schedule/focus_block) 수락 → FocusBlock 생성
|
|
out = client.post("/api/proactive/pc1/accept").json()
|
|
assert out["action_kind"] == "focus_block" and out["created_id"]
|
|
s.expire_all()
|
|
assert s.get(FocusBlock, out["created_id"]) is not None
|
|
# 카드는 accepted → active 목록에서 사라짐
|
|
active = client.get("/api/proactive").json()
|
|
assert "pc1" not in [c["id"] for c in active]
|
|
|
|
|
|
def test_accept_task_materializes(client, session):
|
|
s, _ = session
|
|
out = client.post("/api/proactive/pc2/accept").json()
|
|
assert out["action_kind"] == "task" and out["created_id"]
|
|
s.expire_all()
|
|
assert s.get(Task, out["created_id"]) is not None
|
|
|
|
|
|
def test_dismiss_proactive(client):
|
|
assert client.post("/api/proactive/pc1/dismiss").json()["ok"] is True
|
|
assert "pc1" not in [c["id"] for c in client.get("/api/proactive").json()]
|
|
|
|
|
|
def test_worker_run_endpoint(client):
|
|
r = client.post("/api/worker/run/proactive").json()
|
|
assert r["job"] == "proactive" and r["ok"] is True
|
|
assert client.post("/api/worker/run/nope").status_code == 404
|