from io import BytesIO import pytest from PIL import Image from pigway_frame_flow.providers.poetry import catalog, get_poem def test_daily_selection_is_stable_and_changes_next_day(): today = get_poem("2026-10-02") assert today == get_poem("2026-10-02") assert today["id"] != get_poem("2026-10-03")["id"] assert len({p["id"] for p in catalog()}) == 20 @pytest.mark.parametrize("profile", ["color", "grayscale"]) def test_poetry_native_size(service, profile): image = Image.open(BytesIO(service.renderer.render("daily-poetry", {}, profile))) assert image.size == (1200, 1600) def test_selected_poem_and_custom_poem(service): selected = service.renderer.resolve("daily-poetry", {"poem_id": "jing-ye-si"}) assert selected["poem_title"] == "静夜思" and selected["poem_author"] == "李白" custom = service.renderer.resolve( "daily-poetry", {"poem_title": "Custom", "poem_lines": "User text"} ) assert custom["poem_title"] == "Custom" and custom["poem_lines"] == "User text" def test_poetry_api_validation(client): assert client.get("/api/v1/providers/poetry").status_code == 200 assert client.get("/api/v1/providers/poetry?date=wrong").status_code == 400 assert client.get("/api/v1/providers/poetry?poem_id=missing").status_code == 400 def test_poetry_does_not_fetch_unrelated_weather(service): def unwanted(): raise AssertionError("Poetry must not fetch weather") service.renderer.weather.get_current = unwanted assert service.renderer.render("daily-poetry", {}) def test_final_write_gate_blocks_queued_writes(service): from pigway_frame_flow.errors import FlowError service.settings.mock = False service.settings.write_enabled = False with pytest.raises(FlowError): service._start_write("queued-operation") # Disabled writes leave pending override restoration intact. service.expire()