"""
Unit tests for Project API endpoints.
Tests CRUD operations for projects.
"""
import pytest
import os
import sqlite3
from fastapi.testclient import TestClient
# Use a test database
TEST_DB_PATH = "test_annotation_platform.db"
@pytest.fixture(scope="function", autouse=True)
def setup_test_db():
"""Setup test database before each test and cleanup after."""
# Set test database path
original_db_path = os.environ.get("DATABASE_PATH")
os.environ["DATABASE_PATH"] = TEST_DB_PATH
# Remove existing test database
if os.path.exists(TEST_DB_PATH):
os.remove(TEST_DB_PATH)
# Import after setting env var
from database import init_database
init_database()
yield
# Cleanup
if os.path.exists(TEST_DB_PATH):
os.remove(TEST_DB_PATH)
# Restore original path
if original_db_path:
os.environ["DATABASE_PATH"] = original_db_path
elif "DATABASE_PATH" in os.environ:
del os.environ["DATABASE_PATH"]
@pytest.fixture(scope="function")
def test_client():
"""Create a test client."""
from main import app
return TestClient(app)
def test_list_projects_empty(test_client):
"""Test listing projects when database is empty."""
response = test_client.get("/api/projects")
assert response.status_code == 200
assert response.json() == []
def test_create_project(test_client):
"""Test creating a new project."""
project_data = {
"name": "Test Project",
"description": "Test Description",
"config": ""
}
response = test_client.post("/api/projects", json=project_data)
assert response.status_code == 201
data = response.json()
assert data["name"] == project_data["name"]
assert data["description"] == project_data["description"]
assert data["config"] == project_data["config"]
assert "id" in data
assert data["id"].startswith("proj_")
assert data["task_count"] == 0
assert "created_at" in data
def test_create_project_empty_name(test_client):
"""Test creating a project with empty name fails validation."""
project_data = {
"name": "",
"description": "Test Description",
"config": ""
}
response = test_client.post("/api/projects", json=project_data)
assert response.status_code == 422 # Validation error
def test_get_project(test_client):
"""Test getting a project by ID."""
# Create a project first
project_data = {
"name": "Test Project",
"description": "Test Description",
"config": ""
}
create_response = test_client.post("/api/projects", json=project_data)
project_id = create_response.json()["id"]
# Get the project
response = test_client.get(f"/api/projects/{project_id}")
assert response.status_code == 200
data = response.json()
assert data["id"] == project_id
assert data["name"] == project_data["name"]
def test_get_project_not_found(test_client):
"""Test getting a non-existent project returns 404."""
response = test_client.get("/api/projects/nonexistent_id")
assert response.status_code == 404
assert "not found" in response.json()["detail"].lower()
def test_update_project(test_client):
"""Test updating a project."""
# Create a project first
project_data = {
"name": "Original Name",
"description": "Original Description",
"config": ""
}
create_response = test_client.post("/api/projects", json=project_data)
project_id = create_response.json()["id"]
# Update the project
update_data = {
"name": "Updated Name",
"description": "Updated Description"
}
response = test_client.put(f"/api/projects/{project_id}", json=update_data)
assert response.status_code == 200
data = response.json()
assert data["name"] == update_data["name"]
assert data["description"] == update_data["description"]
assert data["config"] == project_data["config"] # Config unchanged
def test_update_project_not_found(test_client):
"""Test updating a non-existent project returns 404."""
update_data = {"name": "Updated Name"}
response = test_client.put("/api/projects/nonexistent_id", json=update_data)
assert response.status_code == 404
def test_delete_project(test_client):
"""Test deleting a project."""
# Create a project first
project_data = {
"name": "Test Project",
"description": "Test Description",
"config": ""
}
create_response = test_client.post("/api/projects", json=project_data)
project_id = create_response.json()["id"]
# Delete the project
response = test_client.delete(f"/api/projects/{project_id}")
assert response.status_code == 204
# Verify project is deleted
get_response = test_client.get(f"/api/projects/{project_id}")
assert get_response.status_code == 404
def test_delete_project_not_found(test_client):
"""Test deleting a non-existent project returns 404."""
response = test_client.delete("/api/projects/nonexistent_id")
assert response.status_code == 404
def test_list_projects_after_creation(test_client):
"""Test listing projects after creating some."""
# Create multiple projects
for i in range(3):
project_data = {
"name": f"Project {i}",
"description": f"Description {i}",
"config": ""
}
test_client.post("/api/projects", json=project_data)
# List projects
response = test_client.get("/api/projects")
assert response.status_code == 200
data = response.json()
assert len(data) == 3
assert all("id" in project for project in data)
assert all("task_count" in project for project in data)