Art post-audit polish (Codex): image HEAD, texture immutable cache, lightbox a11y, spacing
- /api/art/image/{id} now answers HEAD as well as GET (was 404 on HEAD) — mirrors the
/a/{id} fix. Added tests/test_art_api.py (GET+HEAD+size=full fallback + today payload).
- /textures/* served immutable (long cache) instead of no-cache; excluded from the
revalidate matcher. Live Caddyfile + repo snapshot both updated.
- Lightbox: Escape closes it, and focus moves to it on open (keyboard-friendly).
- Trimmed the gallery's top padding so "Daily Art" sits closer to the bar.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
"""/api/art image + today endpoints: GET and HEAD both work (HEAD must not 404 — the
|
||||
share /a/{id} HEAD gap bit us once), and the today payload carries the lightbox's
|
||||
full-res URL."""
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client(tmp_path, monkeypatch):
|
||||
db = tmp_path / "t.sqlite3"
|
||||
cache = tmp_path / "art_cache"
|
||||
monkeypatch.setenv("GOODNEWS_DB", str(db))
|
||||
monkeypatch.setenv("GOODNEWS_ART_CACHE", str(cache))
|
||||
monkeypatch.setenv("GOODNEWS_PUBLIC_BASE_URL", "https://upbeatbytes.com")
|
||||
import importlib
|
||||
import goodnews.api as api
|
||||
importlib.reload(api)
|
||||
from goodnews.db import connect, init_db
|
||||
c = connect(str(db)); init_db(c)
|
||||
c.execute(
|
||||
"INSERT INTO daily_art (art_date, source, object_id, title, artist, date_text, "
|
||||
"medium, department, credit, source_url, image_file, image_url_full, is_public_domain) "
|
||||
"VALUES ('2026-06-21','met',10154,'Lander''s Peak','Bierstadt','1863','Oil','Paintings',"
|
||||
"'Gift','https://met/10154','10154.jpg','https://met/full.jpg',1)"
|
||||
)
|
||||
c.commit(); c.close()
|
||||
cache.mkdir(parents=True, exist_ok=True)
|
||||
(cache / "10154.jpg").write_bytes(b"\xff\xd8\xff" + b"x" * 5000) # web-large display copy
|
||||
return api.create_app()
|
||||
|
||||
|
||||
def test_image_get_and_head(client):
|
||||
tc = TestClient(client)
|
||||
assert tc.get("/api/art/image/10154").status_code == 200
|
||||
assert tc.head("/api/art/image/10154").status_code == 200 # HEAD must not 404
|
||||
# ?size=full falls back to the display copy when no -full is cached
|
||||
assert tc.get("/api/art/image/10154?size=full").status_code == 200
|
||||
assert tc.get("/api/art/image/9999").status_code == 404
|
||||
|
||||
|
||||
def test_today_exposes_full_res_url(client):
|
||||
a = TestClient(client).get("/api/art/today").json()
|
||||
assert a["image_url"] == "/api/art/image/10154"
|
||||
assert a["image_url_large"] == "/api/art/image/10154?size=full"
|
||||
assert a["license"] == "Public Domain (CC0)" and a["museum"] == "The Met"
|
||||
Reference in New Issue
Block a user