121 lines
3.7 KiB
Python
121 lines
3.7 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
|
|
from pigway_frame_flow.providers.photo_sources import dimensions
|
|
|
|
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.setattr(
|
|
"pigway_frame_flow.providers.photo_sources.dimensions", dimensions
|
|
)
|
|
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"
|
|
)
|
|
|
|
|
|
# Legacy algorithms remain covered; production filesystem access is tested separately.
|
|
pytestmark = pytest.mark.usefixtures("legacy_photo_engine")
|