"""GET /api/frames/{id}/widgets/{widget_id}/preview/calendar -- the calendar dialog's live render preview. No prior coverage existed for this endpoint; added after a Phase 3 refactor (calendar_render.py's size-tier rewrite, see the widget-system plan) left a stale photo_inlay=None kwarg here that would have TypeError'd on the very next request -- nothing in the existing suite actually called this endpoint to catch it.""" from __future__ import annotations import time from app.models import CalendarWidgetConfig, Frame, FrameCalendar, Widget from .conftest import csrf_headers def _configure_calendar_widget(db_session) -> Widget: client_frame = db_session.get(Frame, 1) widget = Widget(frame_id=client_frame.id, widget_type="calendar", x=0, y=0, w=8, h=5, sort_order=1, created_at=time.time()) db_session.add(widget) db_session.flush() db_session.add(CalendarWidgetConfig(widget_id=widget.id, view="agenda")) db_session.commit() return widget def _photo_widget_id(db_session) -> int: return db_session.query(Widget).filter_by(frame_id=1, widget_type="photos").one().id def test_preview_calendar_404s_for_a_widget_id_that_does_not_exist(client, db_session): client.post("/setup", data={"username": "alice", "password": "hunter22"}) resp = client.get("/api/frames/1/widgets/999999/preview/calendar") assert resp.status_code == 404 def test_preview_calendar_400s_when_widget_is_not_a_calendar(client, db_session): client.post("/setup", data={"username": "alice", "password": "hunter22"}) photo_widget_id = _photo_widget_id(db_session) resp = client.get(f"/api/frames/1/widgets/{photo_widget_id}/preview/calendar") assert resp.status_code == 400 def test_preview_calendar_requires_an_included_calendar(client, db_session): client.post("/setup", data={"username": "alice", "password": "hunter22"}) widget = _configure_calendar_widget(db_session) resp = client.get(f"/api/frames/1/widgets/{widget.id}/preview/calendar") assert resp.status_code == 400 assert "calendar" in resp.json()["detail"].lower() def test_preview_calendar_renders_a_png(client, db_session, monkeypatch): client.post("/setup", data={"username": "alice", "password": "hunter22"}) widget = _configure_calendar_widget(db_session) alice = db_session.get(Frame, 1).owner alice.calendar_ics_url = "http://example.invalid/alice.ics" db_session.add(FrameCalendar(widget_id=widget.id, user_id=alice.id, calendar_key="ics", calendar_label="My calendar", included=True)) db_session.commit() monkeypatch.setattr( "app.routers.api_widgets.get_or_refresh_calendar_events_for_widget", lambda db, frame, widget: ([], ""), ) resp = client.get(f"/api/frames/1/widgets/{widget.id}/preview/calendar", headers=csrf_headers(client)) assert resp.status_code == 200, resp.text assert resp.headers["content-type"] == "image/png" assert resp.content[:8] == b"\x89PNG\r\n\x1a\n"