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