134 lines
5.2 KiB
Python
134 lines
5.2 KiB
Python
"""
|
|
ThinkStorm Trash & Empty Trash Tests
|
|
Tests moving ideas to trash, hiding from default browsing, restoring from trash,
|
|
permanently deleting single ideas, and emptying the entire trash bin with cascade cleanup.
|
|
"""
|
|
|
|
import pytest
|
|
from starlette.testclient import TestClient
|
|
from thinkstorm.main import app
|
|
from thinkstorm.database import init_db, get_db
|
|
|
|
@pytest.fixture(scope="module", autouse=True)
|
|
def setup_app():
|
|
init_db()
|
|
|
|
def get_auth_token(username="admin", password="admin-thinkstorm-pass-2026"):
|
|
client = TestClient(app)
|
|
resp = client.post("/api/auth/login", json={"username": username, "password": password})
|
|
assert resp.status_code == 200
|
|
return resp.json()["token"]
|
|
|
|
def test_trash_and_hide_from_default_catalog():
|
|
client = TestClient(app)
|
|
token = get_auth_token()
|
|
headers = {"Authorization": f"Bearer {token}"}
|
|
|
|
# 1. Create an idea and set to AVAILABLE
|
|
sub_resp = client.post("/api/ideas", json={"text": "A low-value idea that should be discarded: spam text test."})
|
|
idea_id = sub_resp.json()["id"]
|
|
|
|
with get_db() as conn:
|
|
conn.execute("UPDATE ideas SET lifecycle_state = 'AVAILABLE' WHERE id = ?", (idea_id,))
|
|
|
|
# Verify visible in default list
|
|
list_resp = client.get("/api/ideas", headers=headers)
|
|
idea_ids_default = [i["id"] for i in list_resp.json()]
|
|
assert idea_id in idea_ids_default
|
|
|
|
# 2. Move idea to Trash
|
|
trash_resp = client.post(f"/api/ideas/{idea_id}/trash", headers=headers)
|
|
assert trash_resp.status_code == 200
|
|
trash_data = trash_resp.json()
|
|
assert trash_data["lifecycle_state"] == "TRASHED"
|
|
assert trash_data["previous_lifecycle_state"] == "AVAILABLE"
|
|
|
|
# 3. Verify hidden from default ideas list and ALL filter
|
|
list_resp_after = client.get("/api/ideas", headers=headers)
|
|
idea_ids_after = [i["id"] for i in list_resp_after.json()]
|
|
assert idea_id not in idea_ids_after
|
|
|
|
list_all_resp = client.get("/api/ideas?state=ALL", headers=headers)
|
|
idea_ids_all = [i["id"] for i in list_all_resp.json()]
|
|
assert idea_id not in idea_ids_all
|
|
|
|
# 4. Verify visible when explicitly filtering by TRASHED
|
|
list_trashed_resp = client.get("/api/ideas?state=TRASHED", headers=headers)
|
|
idea_ids_trashed = [i["id"] for i in list_trashed_resp.json()]
|
|
assert idea_id in idea_ids_trashed
|
|
|
|
def test_restore_idea_from_trash():
|
|
client = TestClient(app)
|
|
token = get_auth_token()
|
|
headers = {"Authorization": f"Bearer {token}"}
|
|
|
|
# 1. Create idea, set to CLAIMED, then trash it
|
|
sub_resp = client.post("/api/ideas", json={"text": "Idea that was mistakenly trashed and needs retrieval."})
|
|
idea_id = sub_resp.json()["id"]
|
|
|
|
with get_db() as conn:
|
|
conn.execute("UPDATE ideas SET lifecycle_state = 'CLAIMED', claimed_by = 'admin' WHERE id = ?", (idea_id,))
|
|
|
|
trash_resp = client.post(f"/api/ideas/{idea_id}/trash", headers=headers)
|
|
assert trash_resp.status_code == 200
|
|
|
|
# 2. Restore idea
|
|
restore_resp = client.post(f"/api/ideas/{idea_id}/restore", headers=headers)
|
|
assert restore_resp.status_code == 200
|
|
assert restore_resp.json()["lifecycle_state"] == "CLAIMED"
|
|
|
|
# 3. Verify idea is restored and visible
|
|
detail_resp = client.get(f"/api/ideas/{idea_id}", headers=headers)
|
|
assert detail_resp.status_code == 200
|
|
assert detail_resp.json()["lifecycle_state"] == "CLAIMED"
|
|
|
|
def test_permanently_delete_single_idea():
|
|
client = TestClient(app)
|
|
token = get_auth_token()
|
|
headers = {"Authorization": f"Bearer {token}"}
|
|
|
|
# 1. Create idea and trash it
|
|
sub_resp = client.post("/api/ideas", json={"text": "Idea to be deleted permanently right now."})
|
|
idea_id = sub_resp.json()["id"]
|
|
client.post(f"/api/ideas/{idea_id}/trash", headers=headers)
|
|
|
|
# 2. Permanently delete
|
|
del_resp = client.delete(f"/api/ideas/{idea_id}/permanent", headers=headers)
|
|
assert del_resp.status_code == 200
|
|
assert "permanently deleted" in del_resp.json()["message"].lower()
|
|
|
|
# 3. Verify it no longer exists anywhere
|
|
detail_resp = client.get(f"/api/ideas/{idea_id}", headers=headers)
|
|
assert detail_resp.status_code == 404
|
|
|
|
def test_empty_trash_bulk():
|
|
client = TestClient(app)
|
|
token = get_auth_token()
|
|
headers = {"Authorization": f"Bearer {token}"}
|
|
|
|
# 1. Create 3 ideas and trash all 3
|
|
trash_ids = []
|
|
for i in range(3):
|
|
resp = client.post("/api/ideas", json={"text": f"Junk idea {i+1} destined for trash empty test."})
|
|
i_id = resp.json()["id"]
|
|
client.post(f"/api/ideas/{i_id}/trash", headers=headers)
|
|
trash_ids.append(i_id)
|
|
|
|
# Verify all 3 are currently in trash
|
|
trashed_list = client.get("/api/ideas?state=TRASHED", headers=headers).json()
|
|
trashed_ids_in_db = [x["id"] for x in trashed_list]
|
|
for tid in trash_ids:
|
|
assert tid in trashed_ids_in_db
|
|
|
|
# 2. Empty Trash
|
|
empty_resp = client.post("/api/trash/empty", headers=headers)
|
|
assert empty_resp.status_code == 200
|
|
data = empty_resp.json()
|
|
assert data["deleted_count"] >= 3
|
|
|
|
# 3. Verify trash list is now empty of those IDs
|
|
trashed_after = client.get("/api/ideas?state=TRASHED", headers=headers).json()
|
|
trashed_after_ids = [x["id"] for x in trashed_after]
|
|
for tid in trash_ids:
|
|
assert tid not in trashed_after_ids
|