Move favorites to local library and keep confirmed task heads in cloud
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
from io import BytesIO
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from pigway_frame_flow.providers.photo_sources import PhotoSourceInput
|
||||
|
||||
|
||||
def setup_photos(service, settings):
|
||||
root = settings.data_dir.parent / "photos"
|
||||
root.mkdir()
|
||||
settings.photo_root = root
|
||||
Image.new("RGB", (300, 200)).save(root / "a.jpg")
|
||||
service.photo_sources.save(
|
||||
"family", PhotoSourceInput(name="Family", kind="local", location=".")
|
||||
)
|
||||
|
||||
|
||||
def make_job(client, name):
|
||||
r = client.post(
|
||||
"/api/v1/jobs",
|
||||
json={
|
||||
"name": name,
|
||||
"enabled": False,
|
||||
"schedule": {"type": "daily", "time": "07:00"},
|
||||
"source": {"type": "photo_source", "source_id": "family"},
|
||||
},
|
||||
)
|
||||
assert r.status_code == 201
|
||||
return r.json()["id"]
|
||||
|
||||
|
||||
def run(client, service, job, confirm=True):
|
||||
r = client.post(f"/api/v1/jobs/{job}/run")
|
||||
assert r.status_code == 202, r.text
|
||||
id = r.json()["operation_id"]
|
||||
service.process_one()
|
||||
if confirm:
|
||||
service.sync()
|
||||
op = client.get("/api/v1/operations/" + id).json()
|
||||
return op["result"]["image_id"], op["result"]["rendered_asset_id"]
|
||||
|
||||
|
||||
def test_task_origin_filter_and_star_bulk(client, service, settings):
|
||||
setup_photos(service, settings)
|
||||
job = make_job(client, "Family random")
|
||||
image, asset = run(client, service, job)
|
||||
rows = client.get("/api/v1/assets", params={"origin": "task", "job_id": job}).json()
|
||||
assert len(rows) == 1 and rows[0]["job_name"] == "Family random"
|
||||
r = client.post(
|
||||
"/api/v1/assets/batch", json={"action": "star", "asset_ids": [asset, asset]}
|
||||
)
|
||||
assert len(r.json()["results"]) == 1
|
||||
assert client.get("/api/v1/assets").json()[0]["starred"]
|
||||
r = client.post(
|
||||
"/api/v1/assets/batch",
|
||||
json={"action": "delete", "asset_ids": [asset, "missing"]},
|
||||
)
|
||||
assert [x["status"] for x in r.json()["results"]] == ["completed", "failed"]
|
||||
|
||||
|
||||
def test_each_task_keeps_one_after_confirmation(client, service, settings):
|
||||
setup_photos(service, settings)
|
||||
job = make_job(client, "A")
|
||||
first, _ = run(client, service, job)
|
||||
second, _ = run(client, service, job)
|
||||
service.cloud_library.sweep()
|
||||
assert service.process_one()
|
||||
assert first not in {
|
||||
x.image_id for x in service.registry.get("living-room").images()
|
||||
}
|
||||
assert second in {x.image_id for x in service.registry.get("living-room").images()}
|
||||
other = make_job(client, "B")
|
||||
third, _ = run(client, service, other)
|
||||
service.cloud_library.checked = 0
|
||||
service.cloud_library.sweep()
|
||||
assert second in {x.image_id for x in service.registry.get("living-room").images()}
|
||||
assert third in {x.image_id for x in service.registry.get("living-room").images()}
|
||||
|
||||
|
||||
def test_unconfirmed_replacement_never_evicts_previous(client, service, settings):
|
||||
setup_photos(service, settings)
|
||||
job = make_job(client, "A")
|
||||
first, _ = run(client, service, job)
|
||||
second, _ = run(client, service, job, confirm=False)
|
||||
service.cloud_library.sweep()
|
||||
assert not service.process_one()
|
||||
assert first in {x.image_id for x in service.registry.get("living-room").images()}
|
||||
assert not service.db.one(
|
||||
"SELECT cleanup_operation FROM managed_cloud_uploads WHERE image_id=?", (first,)
|
||||
)["cleanup_operation"]
|
||||
|
||||
|
||||
def test_starred_old_upload_survives_then_unstar_cleans(client, service, settings):
|
||||
setup_photos(service, settings)
|
||||
job = make_job(client, "A")
|
||||
first, asset = run(client, service, job)
|
||||
assert (
|
||||
client.put(f"/api/v1/assets/{asset}/star", json={"starred": True}).status_code
|
||||
== 200
|
||||
)
|
||||
run(client, service, job)
|
||||
service.cloud_library.sweep()
|
||||
assert not service.process_one()
|
||||
assert (
|
||||
client.put(f"/api/v1/assets/{asset}/star", json={"starred": False}).status_code
|
||||
== 200
|
||||
)
|
||||
service.cloud_library.checked = 0
|
||||
service.cloud_library.sweep()
|
||||
assert service.process_one()
|
||||
assert first not in {
|
||||
x.image_id for x in service.registry.get("living-room").images()
|
||||
}
|
||||
assert service.assets.path(asset).exists()
|
||||
|
||||
|
||||
def test_manual_upload_origin(client, service):
|
||||
buf = BytesIO()
|
||||
Image.new("RGB", (30, 20)).save(buf, "JPEG")
|
||||
r = client.post(
|
||||
"/api/v1/preview", files={"file": ("manual.jpg", buf.getvalue(), "image/jpeg")}
|
||||
)
|
||||
id = r.json()["asset_id"]
|
||||
r = client.post(
|
||||
"/api/v1/devices/living-room/upload", json={"type": "image", "asset_id": id}
|
||||
)
|
||||
service.process_one()
|
||||
rows = client.get("/api/v1/assets", params={"origin": "manual"}).json()
|
||||
assert len(rows) == 1 and rows[0]["asset_id"] == id
|
||||
|
||||
|
||||
def test_clear_cloud_requires_confirmation_and_clears_current(client, service):
|
||||
before = len(service.registry.get("living-room").images())
|
||||
assert (
|
||||
client.post(
|
||||
"/api/v1/devices/living-room/images/clear", json={"confirm_current": False}
|
||||
).status_code
|
||||
== 400
|
||||
)
|
||||
r = client.post(
|
||||
"/api/v1/devices/living-room/images/clear", json={"confirm_current": True}
|
||||
)
|
||||
assert r.status_code == 200 and len(r.json()["operations"]) == before
|
||||
for _ in range(before):
|
||||
assert service.process_one()
|
||||
assert not service.registry.get("living-room").images()
|
||||
Reference in New Issue
Block a user