"""Deletion integrity (relationship cleanup + cascade) and the self-person link.""" from tests.conftest import auth, register async def _setup(client, email): h = auth(await register(client, email)) tid = (await client.post("/api/v1/trees", json={"name": "T"}, headers=h)).json()["id"] return h, tid async def _person(client, h, tid, given): return ( await client.post(f"/api/v1/trees/{tid}/persons", json={"given": given}, headers=h) ).json()["id"] async def _link_parent(client, h, tid, parent, child): await client.post( f"/api/v1/trees/{tid}/relationships", json={"type": "parent_child", "person_from_id": parent, "person_to_id": child}, headers=h, ) async def test_delete_removes_relationships(client): h, tid = await _setup(client, "d-rels@example.com") gp = await _person(client, h, tid, "Grandpa") dad = await _person(client, h, tid, "Dad") await _link_parent(client, h, tid, gp, dad) r = await client.delete(f"/api/v1/trees/{tid}/persons/{gp}", headers=h) assert r.status_code == 200 and r.json()["deleted"] == 1 # The dangling edge is gone, so the tree view can't break on it. rels = ( await client.get(f"/api/v1/trees/{tid}/relationships", headers=h) ).json() assert rels == [] # Dad survives. ppl = {p["id"] for p in (await client.get(f"/api/v1/trees/{tid}/persons", headers=h)).json()} assert dad in ppl and gp not in ppl async def test_cascade_deletes_descendants(client): h, tid = await _setup(client, "d-cascade@example.com") gp = await _person(client, h, tid, "Grandpa") dad = await _person(client, h, tid, "Dad") kid = await _person(client, h, tid, "Kid") await _link_parent(client, h, tid, gp, dad) await _link_parent(client, h, tid, dad, kid) r = await client.delete(f"/api/v1/trees/{tid}/persons/{gp}?cascade=true", headers=h) assert r.status_code == 200 and r.json()["deleted"] == 3 ppl = (await client.get(f"/api/v1/trees/{tid}/persons", headers=h)).json() assert ppl == [] async def test_self_person_link(client): h, tid = await _setup(client, "self@example.com") me = await _person(client, h, tid, "Me") r = await client.patch( "/api/v1/users/me/self-person", json={"self_person_id": me}, headers=h ) assert r.status_code == 200 and r.json()["self_person_id"] == me # Reflected on /me. assert (await client.get("/api/v1/users/me", headers=h)).json()["self_person_id"] == me # Deleting that person clears the link (SET NULL). await client.delete(f"/api/v1/trees/{tid}/persons/{me}", headers=h) assert (await client.get("/api/v1/users/me", headers=h)).json()["self_person_id"] is None async def test_self_person_clear(client): h, tid = await _setup(client, "self-clear@example.com") me = await _person(client, h, tid, "Me") await client.patch("/api/v1/users/me/self-person", json={"self_person_id": me}, headers=h) r = await client.patch( "/api/v1/users/me/self-person", json={"self_person_id": None}, headers=h ) assert r.status_code == 200 and r.json()["self_person_id"] is None