Files
periscope/tests/test_project_delete.py
michele 7a32c552bb Stamp 2.60.0 incomplete PCB exam and owner project delete.
Partial layouts still use MODE=pcb. Missing copper is INSUFFICIENT or
skipped, never Euclidean stand-in tracks. Via≠Pad unchanged. DELETE
/api/projects/{id} is owner-only with a dashboard confirm dialog.
2026-09-20 21:17:26 +02:00

75 lines
2.7 KiB
Python

"""Owner-only project delete: files+meta gone; other owners and auth users untouched."""
from __future__ import annotations
from pathlib import Path
from fastapi.testclient import TestClient
from backend.services import projects as proj_svc
from backend.services.storage import LocalStorageBackend
def _client(tmp_path: Path) -> TestClient:
from backend.main import app
app.state.storage = LocalStorageBackend(tmp_path)
return TestClient(app)
def test_owner_delete_removes_project_files_not_auth(tmp_path: Path):
client = _client(tmp_path)
auth_users = tmp_path / "auth" / "users.json"
auth_users.parent.mkdir(parents=True)
auth_users.write_text('{"users":[{"email":"keep@example.com"}]}\n')
meta = client.post("/api/projects", json={"name": "mine"}).json()
pid = meta["id"]
prefix = f"users/local/projects/{pid}"
storage = client.app.state.storage
storage.write_json(f"{prefix}/report.json", {"findings": []})
storage.write_text(f"{prefix}/uploads/netlist.asc", "*PADS-PCB*\n")
resp = client.delete(f"/api/projects/{pid}")
assert resp.status_code == 200, resp.text
assert resp.json()["ok"] is True
assert not storage.exists(f"{prefix}/project.json")
assert not storage.exists(f"{prefix}/report.json")
assert auth_users.is_file()
assert "keep@example.com" in auth_users.read_text()
listed = client.get("/api/projects").json()
assert all(p["id"] != pid for p in listed)
def test_delete_another_owners_project_is_404(tmp_path: Path):
client = _client(tmp_path)
storage = client.app.state.storage
other = proj_svc.create_project(storage, "alice", "secret-board")
key = f"users/alice/projects/{other.id}/project.json"
report = f"users/alice/projects/{other.id}/report.json"
storage.write_json(report, {"findings": [{"id": 1}]})
alice_users = tmp_path / "users" / "alice" / "profile.json"
alice_users.parent.mkdir(parents=True, exist_ok=True)
alice_users.write_text('{"user_id":"alice"}\n')
resp = client.delete(f"/api/projects/{other.id}")
assert resp.status_code == 404
assert storage.exists(key)
assert storage.exists(report)
assert alice_users.is_file()
def test_collaborator_cannot_delete_owner_project(tmp_path: Path):
client = _client(tmp_path)
storage = client.app.state.storage
other = proj_svc.create_project(storage, "alice", "shared")
proj_svc.add_collaborator(storage, "alice", other.id, "local")
key = f"users/alice/projects/{other.id}/project.json"
resp = client.delete(f"/api/projects/{other.id}")
assert resp.status_code == 403, resp.text
assert storage.exists(key)
meta = proj_svc.get_project(storage, "alice", other.id)
assert meta is not None
assert "local" in meta.collaborators