116 lines
3.5 KiB
Python
116 lines
3.5 KiB
Python
from datetime import date, datetime, timezone
|
||
|
||
from sqlalchemy import create_engine
|
||
from sqlalchemy.orm import Session, sessionmaker
|
||
|
||
from app.db.models import Base, ChatSession, Message, User
|
||
from app.homelab.evening_summary import (
|
||
_fallback_summary,
|
||
_format_context_block,
|
||
_parse_llm_payload,
|
||
collect_day_context,
|
||
format_evening_notice,
|
||
)
|
||
|
||
|
||
def test_parse_llm_payload():
|
||
raw = '{"text": "Хороший день.", "scene_tags": "full_body, smile"}'
|
||
parsed = _parse_llm_payload(raw)
|
||
assert parsed is not None
|
||
text, scene = parsed
|
||
assert "Хороший" in text
|
||
assert "smile" in scene
|
||
|
||
|
||
def test_parse_llm_payload_markdown_wrapped():
|
||
raw = '```json\n{"text": "Ок", "scene_tags": "cozy"}\n```'
|
||
parsed = _parse_llm_payload(raw)
|
||
assert parsed is not None
|
||
assert parsed[0] == "Ок"
|
||
|
||
|
||
def test_fallback_summary():
|
||
ctx = {
|
||
"pomodoro_sessions": 2,
|
||
"has_fitness_data": True,
|
||
"calories": 1800,
|
||
"calorie_target": 2000,
|
||
"workouts_count": 0,
|
||
"completed_reminders": [],
|
||
}
|
||
text, scene = _fallback_summary(ctx)
|
||
assert "помидоро" in text.lower() or "Помидоро" in text or "2" in text
|
||
assert scene
|
||
|
||
|
||
def test_format_evening_notice_with_image():
|
||
notice = format_evening_notice("Итог дня.", "/api/v1/media/generated/x.png")
|
||
assert notice.startswith("💪 **Сводка дня**")
|
||
assert "Итог дня." in notice
|
||
assert "![day]" in notice
|
||
|
||
|
||
def test_format_evening_notice_text_only():
|
||
notice = format_evening_notice("Только текст.")
|
||
assert "Только текст." in notice
|
||
assert "![day]" not in notice
|
||
|
||
|
||
def test_collect_day_context_includes_chat_excerpt():
|
||
engine = create_engine("sqlite:///:memory:")
|
||
Base.metadata.create_all(engine)
|
||
SessionLocal = sessionmaker(bind=engine)
|
||
tz = timezone.utc
|
||
day = date(2026, 7, 3)
|
||
msg_time = datetime(2026, 7, 3, 14, 30, tzinfo=tz)
|
||
|
||
with SessionLocal() as db:
|
||
user = User(username="u", api_token_hash="x")
|
||
db.add(user)
|
||
db.commit()
|
||
db.refresh(user)
|
||
|
||
session = ChatSession(user_id=user.id, title="Болею")
|
||
db.add(session)
|
||
db.commit()
|
||
db.refresh(session)
|
||
|
||
db.add_all(
|
||
[
|
||
Message(
|
||
session_id=session.id,
|
||
role="user",
|
||
content="Сегодня болею, температура, работать не могу",
|
||
created_at=msg_time,
|
||
),
|
||
Message(
|
||
session_id=session.id,
|
||
role="assistant",
|
||
content="Отдыхай, поправляйся",
|
||
created_at=msg_time,
|
||
),
|
||
]
|
||
)
|
||
db.commit()
|
||
|
||
ctx = collect_day_context(db, user.id, day, tz)
|
||
|
||
assert "болею" in ctx["chat_excerpt"].lower()
|
||
block = _format_context_block(ctx)
|
||
assert "Последний чат за день" in block
|
||
assert "болею" in block.lower()
|
||
|
||
|
||
def test_fallback_summary_uses_chat_context():
|
||
ctx = {
|
||
"pomodoro_sessions": 0,
|
||
"has_fitness_data": False,
|
||
"calories": 0,
|
||
"calorie_target": 2000,
|
||
"workouts_count": 0,
|
||
"completed_reminders": [],
|
||
"chat_excerpt": "Пользователь: Сегодня болею и лежу дома",
|
||
}
|
||
text, _scene = _fallback_summary(ctx)
|
||
assert "болею" in text.lower() or "В чате" in text
|