Files

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