Files
thunderheronight--splat-wor…/tests/test_groups.py
T
thunderheronightandClaude Opus 5.5 da00372c5a 0.2.2: tests hardened after an independent review; strict types for all text fields
206 tests instead of 57; every surviving mutation of the review is caught now. New fakes for
ffprobe, ssh/scp (the Frame as a folder) and notify-send; synthetic rooms with tracking noise,
scale error, turned splats, tracking turn and an adjustable walk-in. Fixed: wrongly typed
members/key/align/partition gave a 500 or were stored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:52:56 +02:00

81 lines
3.9 KiB
Python

"""Groups of scenes: one group per scene, suggestions, renaming, cleaning up together."""
import json
from conftest import RUNS, server
import synth
def make_flat():
synth.make_room(RUNS, "Kitchen", "A", name="Kitchen", recording="2026-10-12_16-40-00_stereo.mp4")
synth.make_room(RUNS, "Hallway", "B", name="Hallway", recording="2026-10-12_16-43-00_stereo.mp4")
synth.make_room(RUNS, "Statue", "A", name="Statue", recording="2026-10-03_19-00-00_stereo.mp4")
def test_rooms_recorded_one_after_another_are_suggested(api):
make_flat()
# 25 minutes after the hallway: more than the 20 minutes that still count as one session
synth.make_room(RUNS, "Garden", "A", name="Garden", recording="2026-10-12_17-08-00_stereo.mp4")
status, r = api.get("/api/groups")
assert status == 200 and r["groups"] == []
assert sorted(r["suggestion"]["members"]) == ["Hallway", "Kitchen"] # not the statue from another day
assert r["suggestion"]["date"] == "2026-10-12"
assert api.post("/api/group/dismiss", {"key": r["suggestion"]["key"]})[0] == 200
assert api.get("/api/groups")[1]["suggestion"] is None
def test_a_group_with_its_scenes(api):
make_flat()
status, r = api.post("/api/group", {"name": "Example home", "members": "Kitchen,Hallway"})
assert status == 200 and r["slug"] == "Example-home"
g = api.get("/api/groups")[1]["groups"][0]
assert (g["name"], g["members"], g["result"]) == ("Example home", ["Kitchen", "Hallway"], None)
assert "Example-home" not in {s["slug"] for s in api.get("/api/scenes")[1]} # a group is not a scene
assert "Example-home" not in {u["slug"] for u in api.get("/api/unfinished")[1]}
def test_a_scene_can_only_be_in_one_group(api):
make_flat()
api.post("/api/group", {"name": "Home", "members": "Kitchen,Hallway"})
status, r = api.post("/api/group", {"name": "Other", "members": "Kitchen,Statue"})
assert status == 400 and r["error"]["code"] == "err.in_other_group"
assert api.post("/api/group", {"name": "Empty", "members": ""})[0] == 400
assert api.post("/api/group", {"name": "Ghost", "members": "Nope"})[0] == 400
def test_renaming_and_changing_a_group(api):
make_flat()
api.post("/api/group", {"name": "Home", "members": "Kitchen,Hallway"})
status, r = api.post("/api/group", {"slug": "Home", "name": "Old flat", "members": "Kitchen"})
assert status == 200 and r["slug"] == "Old-flat"
assert not (RUNS / "Home.ui.json").exists()
g = api.get("/api/groups")[1]["groups"][0]
assert (g["slug"], g["name"], g["members"]) == ("Old-flat", "Old flat", ["Kitchen"])
def test_renamed_and_deleted_scenes_follow_their_group(api):
make_flat()
api.post("/api/group", {"name": "Home", "members": "Kitchen,Hallway"})
api.post("/api/rename", {"slug": "Kitchen", "new": "Küche"})
assert json.loads((RUNS / "Home.ui.json").read_text())["members"] == ["Kueche", "Hallway"]
api.post("/api/delete", {"slug": "Hallway"})
assert json.loads((RUNS / "Home.ui.json").read_text())["members"] == ["Kueche"]
def test_cleaning_up_a_group_cleans_only_its_scenes(api):
make_flat()
for slug in ("Kitchen", "Hallway", "Statue"):
(RUNS / slug / "spirula" / "training").mkdir(parents=True)
(RUNS / slug / "spirula" / "training" / "x").write_bytes(b"x" * 1000)
api.post("/api/group", {"name": "Home", "members": "Kitchen,Hallway"})
assert api.post("/api/clean", {"slug": "Home", "what": "temp"})[0] == 200
assert not (RUNS / "Kitchen/spirula/training").exists() and not (RUNS / "Hallway/spirula/training").exists()
assert (RUNS / "Statue/spirula/training/x").exists()
def test_dissolving_a_group_keeps_its_scenes(api):
make_flat()
api.post("/api/group", {"name": "Home", "members": "Kitchen,Hallway"})
assert api.post("/api/delete", {"slug": "Home"})[0] == 200
assert api.get("/api/groups")[1]["groups"] == []
assert {"Kitchen", "Hallway", "Statue"} <= {s["slug"] for s in server.scenes()}