feat: add audit logging for admin trash restore/purge and notification clear actions
- Record audit events in `admin_trash_restore` and `admin_trash_purge` endpoints with target metadata - Log `notification.read.all` event when user clears devRant notification feed - Include `devrant` as a valid origin in audit categories - Add `admin_section` and `pagination_query` fields to audit and backup schemas for UI consistency
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import time
|
||||
import requests
|
||||
from tests.conftest import BASE_URL
|
||||
|
||||
JSON_trash = {"Accept": "application/json"}
|
||||
_counter_trash = [0]
|
||||
|
||||
|
||||
def _unique_trash(prefix="tr"):
|
||||
_counter_trash[0] += 1
|
||||
return f"{prefix}{int(time.time() * 1000)}{_counter_trash[0]}"
|
||||
|
||||
|
||||
def _member_trash():
|
||||
name = _unique_trash("trmem")
|
||||
s = requests.Session()
|
||||
s.post(
|
||||
f"{BASE_URL}/auth/signup",
|
||||
data={
|
||||
"username": name,
|
||||
"email": f"{name}@t.dev",
|
||||
"password": "secret123",
|
||||
"confirm_password": "secret123",
|
||||
},
|
||||
allow_redirects=True,
|
||||
)
|
||||
return s, name
|
||||
|
||||
|
||||
def _admin_trash(seeded_db):
|
||||
s = requests.Session()
|
||||
creds = seeded_db["alice"]
|
||||
s.post(
|
||||
f"{BASE_URL}/auth/login",
|
||||
data={"email": creds["email"], "password": creds["password"]},
|
||||
allow_redirects=True,
|
||||
)
|
||||
return s
|
||||
|
||||
|
||||
def _create_post_trash(session):
|
||||
return session.post(
|
||||
f"{BASE_URL}/posts/create",
|
||||
headers=JSON_trash,
|
||||
data={"title": _unique_trash("trp"), "content": "trash post body text", "topic": "devlog"},
|
||||
).json()["data"]
|
||||
|
||||
|
||||
def _soft_delete_post_trash(session, slug):
|
||||
return session.post(
|
||||
f"{BASE_URL}/posts/delete/{slug}", headers=JSON_trash, allow_redirects=False
|
||||
)
|
||||
|
||||
|
||||
def test_trash_requires_admin(seeded_db):
|
||||
member, _ = _member_trash()
|
||||
r = member.get(f"{BASE_URL}/admin/trash", allow_redirects=False)
|
||||
assert r.status_code in (302, 303)
|
||||
|
||||
|
||||
def test_trash_lists_soft_deleted_post(seeded_db):
|
||||
member, _ = _member_trash()
|
||||
post = _create_post_trash(member)
|
||||
_soft_delete_post_trash(member, post["slug"])
|
||||
admin = _admin_trash(seeded_db)
|
||||
body = admin.get(
|
||||
f"{BASE_URL}/admin/trash", headers=JSON_trash, params={"table": "posts"}
|
||||
).json()
|
||||
assert body["table"] == "posts"
|
||||
assert body["admin_section"] == "trash"
|
||||
assert any(item["uid"] == post["uid"] for item in body["items"])
|
||||
|
||||
|
||||
def test_trash_unknown_table_falls_back_to_posts(seeded_db):
|
||||
admin = _admin_trash(seeded_db)
|
||||
body = admin.get(
|
||||
f"{BASE_URL}/admin/trash", headers=JSON_trash, params={"table": "bogus"}
|
||||
).json()
|
||||
assert body["table"] == "posts"
|
||||
Reference in New Issue
Block a user