Files
pigway-frame-flow/tests/test_photo_orientation.py
T

113 lines
3.4 KiB
Python

import pytest
from PIL import Image
from pigway_frame_flow.providers.photo_sources import PhotoSourceInput
@pytest.fixture
def oriented(service, settings):
settings.photo_root = settings.data_dir.parent / "photos"
root = settings.photo_root / "20240101 Day"
root.mkdir(parents=True)
for name, size, rotation in [
("wide.jpg", (200, 100), 1),
("tall.jpg", (100, 200), 1),
("rotated.jpg", (200, 100), 6),
("square.jpg", (100, 100), 1),
]:
exif = Image.Exif()
exif[274] = rotation
Image.new("RGB", size).save(root / name, exif=exif)
return service.photo_sources
@pytest.mark.parametrize(
"direction,names",
[
("landscape", {"wide.jpg"}),
("portrait", {"tall.jpg", "rotated.jpg"}),
("auto", {"tall.jpg", "rotated.jpg"}),
(None, {"wide.jpg", "tall.jpg", "rotated.jpg", "square.jpg"}),
],
)
def test_orientation_catalog_and_exif(oriented, direction, names):
oriented.save(
"family",
PhotoSourceInput(
name="Family",
kind="local",
location=".",
orientation=direction,
organized_only=True,
),
)
rows = oriented.catalog("family")
assert {r["name"] for r in rows} == names
if direction:
assert oriented.db.one("SELECT COUNT(*) AS n FROM photo_dimensions")["n"] == 4
if direction != "landscape":
rotated = next(r for r in rows if r["name"] == "rotated.jpg")
assert (rotated["width"], rotated["height"]) == (100, 200)
def test_cached_dimensions_invalidation_and_no_fallback(
oriented, settings, monkeypatch
):
from pigway_frame_flow.errors import FlowError
oriented.save(
"family",
PhotoSourceInput(
name="Family", kind="local", location=".", orientation="landscape"
),
)
assert len(oriented.catalog("family")) == 1
monkeypatch.setattr(
"pigway_frame_flow.providers.photo_sources.dimensions",
lambda *a: pytest.fail("unchanged dimensions should be cached"),
)
assert len(oriented.catalog("family", refresh=True)) == 1
monkeypatch.undo()
Image.new("RGB", (50, 100)).save(settings.photo_root / "20240101 Day" / "wide.jpg")
assert oriented.catalog("family", refresh=True) == []
with pytest.raises(FlowError):
oriented.read("family")
def test_orientation_validation_and_api(client, oriented):
r = client.put(
"/api/v1/photo-sources/family",
json={
"name": "Family",
"kind": "local",
"location": ".",
"orientation": "landscape",
},
)
assert r.status_code == 200 and r.json()["orientation"] == "landscape"
assert client.get("/api/v1/photo-sources/family/images").json()["total"] == 1
assert (
client.put(
"/api/v1/photo-sources/family",
json={
"name": "Family",
"kind": "local",
"location": ".",
"orientation": "sideways",
},
).status_code
== 422
)
assert (
client.put(
"/api/v1/photo-sources/dav",
json={
"name": "Remote",
"kind": "webdav",
"location": "https://example.com/",
"orientation": "portrait",
},
).json()["error"]["code"]
== "UNSUPPORTED_CAPABILITY"
)