Add protected soft deletion for research runs

This commit is contained in:
faligam
2026-09-07 12:34:41 +02:00
parent 2c532bc9bb
commit f921e978a0
8 changed files with 445 additions and 37 deletions

View File

@@ -0,0 +1,19 @@
"""Focused tests for deletion-protection primitives without external providers."""
from __future__ import annotations
import pytest
from nsct.security.deletion_protection import hash_deletion_password, verify_deletion_password
@pytest.mark.asyncio
async def test_deletion_password_is_salted_and_verifiable() -> None:
password = "a-long-enough-deletion-password"
first = await hash_deletion_password(password)
second = await hash_deletion_password(password)
assert first != password
assert first != second
assert await verify_deletion_password(password, first)
assert not await verify_deletion_password("incorrect-password", first)

View File

@@ -413,8 +413,8 @@ def test_get_report_not_completed(client: TestClient) -> None:
# ---------------------------------------------------------------------------
def test_delete_research_active_fails(client: TestClient) -> None:
"""DELETE handles both active and finished research."""
def test_delete_research_soft_deletes_all_states(client: TestClient) -> None:
"""DELETE hides a run, including a completed one, instead of destroying it."""
from nsct.api.rest_research import _research_store, ResearchRunState
_research_store.clear()
@@ -434,14 +434,12 @@ def test_delete_research_active_fails(client: TestClient) -> None:
# Already deleted by previous tests — skip
return
# If completed, delete should return 400 (immutable)
# If failed/created, delete should succeed
resp = client.delete(f"/v1/research/{research_id}")
assert resp.status_code in (200, 400)
if resp.status_code == 200:
body = resp.json()
assert body["status"] == "deleted"
assert body["research_id"] == research_id
assert resp.status_code == 200
body = resp.json()
assert body["status"] == "hidden"
assert body["research_id"] == research_id
assert research_id not in _research_store or _research_store[research_id].is_hidden
def test_delete_research_not_found(client: TestClient) -> None: