calendar_render.py's _build_* functions now take a real target box and pick font sizes/margins from three discrete size tiers (nearest pixel-area fit) instead of always laying out at full panel size and resizing after the fact -- a calendar widget placed smaller than the full panel gets an actually-legible layout instead of shrunk text. Month view falls back to agenda below the smallest tier, where 7 columns can no longer stay readable. The old photo-inlay split (inlay_region/_content_region/_paste_inlay) is deleted along with it -- arbitrary widget placement already subsumes what a fixed half-panel split did, and every call site has passed photo_inlay=None since the Phase 2 cutover. Also adds HTTP-level test coverage for GET .../preview/calendar, which had none before this -- it's what caught a stale photo_inlay kwarg left over from the _build signature change that would have TypeError'd on every request.
61 lines
2.4 KiB
Python
61 lines
2.4 KiB
Python
"""GET /api/frames/{id}/preview/calendar -- the Calendar tab'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 test_preview_calendar_requires_a_calendar_widget(client, db_session):
|
|
client.post("/setup", data={"username": "alice", "password": "hunter22"})
|
|
resp = client.get("/api/frames/1/preview/calendar")
|
|
assert resp.status_code == 400
|
|
assert "widget" in resp.json()["detail"].lower()
|
|
|
|
|
|
def test_preview_calendar_requires_an_included_calendar(client, db_session):
|
|
client.post("/setup", data={"username": "alice", "password": "hunter22"})
|
|
_configure_calendar_widget(db_session)
|
|
resp = client.get("/api/frames/1/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"})
|
|
_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(frame_id=1, user_id=alice.id, calendar_key="ics",
|
|
calendar_label="My calendar", included=True))
|
|
db_session.commit()
|
|
|
|
monkeypatch.setattr(
|
|
"app.routers.api_frames.get_or_refresh_calendar_events_for_widget",
|
|
lambda db, frame, widget: ([], ""),
|
|
)
|
|
|
|
resp = client.get("/api/frames/1/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"
|