"""Sources and citations (the provenance spine).""" import uuid from tests.conftest import auth, register async def _setup(client, email): h = auth(await register(client, email)) tree_id = (await client.post("/api/v1/trees", json={"name": "S"}, headers=h)).json()["id"] person = ( await client.post( f"/api/v1/trees/{tree_id}/persons", json={"given": "Cy"}, headers=h ) ).json()["id"] event = ( await client.post( f"/api/v1/trees/{tree_id}/events", json={"event_type": "birth", "person_id": person}, headers=h, ) ).json()["id"] return h, tree_id, person, event async def test_source_and_citation_flow(client): h, tree_id, person, event = await _setup(client, "src1@example.com") src = await client.post( f"/api/v1/trees/{tree_id}/sources", json={"title": "1880 Census", "repository": "NARA"}, headers=h, ) assert src.status_code == 201, src.text source_id = src.json()["id"] assert len((await client.get(f"/api/v1/trees/{tree_id}/sources", headers=h)).json()) == 1 # Cite the source on the birth event. cite = await client.post( f"/api/v1/trees/{tree_id}/citations", json={"source_id": source_id, "event_id": event, "page": "p. 4"}, headers=h, ) assert cite.status_code == 201, cite.text citation_id = cite.json()["id"] citations = (await client.get(f"/api/v1/trees/{tree_id}/citations", headers=h)).json() assert len(citations) == 1 assert citations[0]["event_id"] == event assert citations[0]["source_id"] == source_id resp = await client.delete(f"/api/v1/trees/{tree_id}/citations/{citation_id}", headers=h) assert resp.status_code == 204 assert len((await client.get(f"/api/v1/trees/{tree_id}/citations", headers=h)).json()) == 0 async def test_citation_needs_exactly_one_target(client): h, tree_id, person, event = await _setup(client, "src2@example.com") source_id = ( await client.post( f"/api/v1/trees/{tree_id}/sources", json={"title": "X"}, headers=h ) ).json()["id"] # No target. r = await client.post( f"/api/v1/trees/{tree_id}/citations", json={"source_id": source_id}, headers=h ) assert r.status_code == 409 # Two targets. r = await client.post( f"/api/v1/trees/{tree_id}/citations", json={"source_id": source_id, "person_id": person, "event_id": event}, headers=h, ) assert r.status_code == 409 async def test_citation_unknown_source_404(client): h, tree_id, person, _ = await _setup(client, "src3@example.com") r = await client.post( f"/api/v1/trees/{tree_id}/citations", json={"source_id": str(uuid.uuid4()), "person_id": person}, headers=h, ) assert r.status_code == 404 async def test_non_member_cannot_create_source(client): h, tree_id, _, _ = await _setup(client, "src4@example.com") other = auth(await register(client, "src-intruder@example.com")) r = await client.post( f"/api/v1/trees/{tree_id}/sources", json={"title": "nope"}, headers=other ) assert r.status_code == 403