Spaces:
Running
Running
| """ | |
| Tests for evidence case management system. | |
| Uses a temporary cases.jsonl for isolation. | |
| """ | |
| import pytest | |
| import uuid | |
| from pathlib import Path | |
| from unittest.mock import patch | |
| # Patch CASES_PATH to a temp file for all tests | |
| def temp_cases_file(tmp_path): | |
| temp = tmp_path / "test_cases.jsonl" | |
| with patch("backend.services.case_manager.CASES_PATH", temp): | |
| yield temp | |
| # ββ Service unit tests ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def test_create_case_returns_case_id(): | |
| from backend.services.case_manager import create_case | |
| result = create_case("Test Case", "A test investigation") | |
| assert "case_id" in result | |
| assert result["name"] == "Test Case" | |
| assert result["status"] == "open" | |
| assert result["evidence"] == [] | |
| def test_create_case_requires_name(): | |
| from backend.services.case_manager import create_case | |
| result = create_case("") | |
| assert "error" in result | |
| def test_create_case_persists(): | |
| from backend.services.case_manager import create_case, get_case | |
| case = create_case("Persistent Case") | |
| retrieved = get_case(case["case_id"]) | |
| assert retrieved["case_id"] == case["case_id"] | |
| assert retrieved["name"] == "Persistent Case" | |
| def test_add_evidence_to_case(): | |
| from backend.services.case_manager import create_case, add_evidence | |
| case = create_case("Evidence Case") | |
| result = add_evidence( | |
| case_id=case["case_id"], | |
| evidence_id=str(uuid.uuid4()), | |
| filename="test.jpg", | |
| ai_probability=0.85, | |
| classification="likely_ai_generated", | |
| notes="Suspicious image from social media", | |
| ) | |
| assert len(result["evidence"]) == 1 | |
| assert result["evidence"][0]["ai_probability"] == 0.85 | |
| assert result["evidence"][0]["classification"] == "likely_ai_generated" | |
| def test_add_evidence_to_nonexistent_case(): | |
| from backend.services.case_manager import add_evidence | |
| result = add_evidence( | |
| case_id=str(uuid.uuid4()), | |
| evidence_id=str(uuid.uuid4()), | |
| filename="test.jpg", | |
| ai_probability=0.5, | |
| classification="unknown", | |
| ) | |
| assert "error" in result | |
| def test_add_evidence_to_closed_case(): | |
| from backend.services.case_manager import create_case, add_evidence, update_status | |
| case = create_case("Closed Case") | |
| update_status(case["case_id"], "closed") | |
| result = add_evidence( | |
| case_id=case["case_id"], | |
| evidence_id=str(uuid.uuid4()), | |
| filename="test.jpg", | |
| ai_probability=0.5, | |
| classification="unknown", | |
| ) | |
| assert "error" in result | |
| def test_list_cases_returns_all(): | |
| from backend.services.case_manager import create_case, list_cases | |
| create_case("Case A") | |
| create_case("Case B") | |
| cases = list_cases() | |
| assert len(cases) == 2 | |
| def test_list_cases_filter_by_status(): | |
| from backend.services.case_manager import create_case, list_cases, update_status | |
| c1 = create_case("Open Case") | |
| c2 = create_case("Closed Case") | |
| update_status(c2["case_id"], "closed") | |
| open_cases = list_cases(status="open") | |
| assert len(open_cases) == 1 | |
| assert open_cases[0]["case_id"] == c1["case_id"] | |
| def test_update_status_valid(): | |
| from backend.services.case_manager import create_case, update_status | |
| case = create_case("Status Test") | |
| result = update_status(case["case_id"], "closed") | |
| assert result["status"] == "closed" | |
| def test_update_status_invalid(): | |
| from backend.services.case_manager import create_case, update_status | |
| case = create_case("Status Test") | |
| result = update_status(case["case_id"], "invalid_status") | |
| assert "error" in result | |
| def test_search_cases_by_name(): | |
| from backend.services.case_manager import create_case, search_cases | |
| create_case("Election Fraud Investigation", tags=["election", "2024"]) | |
| create_case("Unrelated Case") | |
| results = search_cases("election") | |
| assert len(results) == 1 | |
| assert "Election" in results[0]["name"] | |
| def test_search_cases_by_tag(): | |
| from backend.services.case_manager import create_case, search_cases | |
| create_case("Tagged Case", tags=["deepfake", "politics"]) | |
| results = search_cases("deepfake") | |
| assert len(results) == 1 | |
| def test_delete_case_archives(): | |
| from backend.services.case_manager import create_case, delete_case, get_case | |
| case = create_case("To Delete") | |
| delete_case(case["case_id"]) | |
| retrieved = get_case(case["case_id"]) | |
| assert retrieved["status"] == "archived" | |
| def test_case_summary_stats(): | |
| from backend.services.case_manager import create_case, add_evidence, get_case_summary | |
| case = create_case("Summary Test") | |
| for i, prob in enumerate([0.8, 0.9, 0.2]): | |
| add_evidence( | |
| case_id=case["case_id"], | |
| evidence_id=str(uuid.uuid4()), | |
| filename=f"img_{i}.jpg", | |
| ai_probability=prob, | |
| classification="likely_ai_generated" if prob > 0.5 else "likely_authentic", | |
| ) | |
| summary = get_case_summary(case["case_id"]) | |
| assert summary["evidence_count"] == 3 | |
| assert summary["ai_detected"] == 2 | |
| assert 0.0 <= summary["mean_ai_prob"] <= 1.0 | |
| # ββ API endpoint tests ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def test_api_create_case(client): | |
| response = client.post( | |
| "/api/v1/cases/", | |
| json={"name": "API Test Case", "description": "Created via API", "tags": ["test"]} | |
| ) | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert "case_id" in data | |
| assert data["name"] == "API Test Case" | |
| def test_api_list_cases(client): | |
| client.post("/api/v1/cases/", json={"name": "List Test"}) | |
| response = client.get("/api/v1/cases/") | |
| assert response.status_code == 200 | |
| assert "cases" in response.json() | |
| def test_api_get_case(client): | |
| create_resp = client.post("/api/v1/cases/", json={"name": "Get Test"}) | |
| case_id = create_resp.json()["case_id"] | |
| response = client.get(f"/api/v1/cases/{case_id}") | |
| assert response.status_code == 200 | |
| assert response.json()["case_id"] == case_id | |
| def test_api_get_nonexistent_case(client): | |
| response = client.get(f"/api/v1/cases/{uuid.uuid4()}") | |
| assert response.status_code == 404 | |
| def test_api_add_evidence(client): | |
| case_resp = client.post("/api/v1/cases/", json={"name": "Evidence Test"}) | |
| case_id = case_resp.json()["case_id"] | |
| response = client.post( | |
| f"/api/v1/cases/{case_id}/evidence", | |
| json={ | |
| "evidence_id": str(uuid.uuid4()), | |
| "filename": "suspect.jpg", | |
| "ai_probability": 0.92, | |
| "classification": "likely_ai_generated", | |
| "notes": "Found on social media", | |
| "tags": ["social_media"], | |
| } | |
| ) | |
| assert response.status_code == 200 | |
| assert len(response.json()["evidence"]) == 1 | |
| def test_api_update_status(client): | |
| case_resp = client.post("/api/v1/cases/", json={"name": "Status Test"}) | |
| case_id = case_resp.json()["case_id"] | |
| response = client.patch( | |
| f"/api/v1/cases/{case_id}/status", | |
| json={"status": "closed"} | |
| ) | |
| assert response.status_code == 200 | |
| assert response.json()["status"] == "closed" | |
| def test_api_delete_archives(client): | |
| case_resp = client.post("/api/v1/cases/", json={"name": "Delete Test"}) | |
| case_id = case_resp.json()["case_id"] | |
| response = client.delete(f"/api/v1/cases/{case_id}") | |
| assert response.status_code == 200 | |
| get_resp = client.get(f"/api/v1/cases/{case_id}") | |
| assert get_resp.json()["status"] == "archived" | |
| def test_api_search(client): | |
| client.post("/api/v1/cases/", json={"name": "Deepfake Investigation 2024"}) | |
| client.post("/api/v1/cases/", json={"name": "Unrelated"}) | |
| response = client.get("/api/v1/cases/search?q=deepfake") | |
| assert response.status_code == 200 | |
| cases = response.json()["cases"] | |
| assert len(cases) == 1 | |
| assert "Deepfake" in cases[0]["name"] | |