| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- """
- Unit tests for Task API endpoints.
- Tests CRUD operations for tasks.
- """
- import pytest
- import os
- import json
- from fastapi.testclient import TestClient
- # Use a test database
- TEST_DB_PATH = "test_task_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)
- @pytest.fixture(scope="function")
- def sample_project(test_client):
- """Create a sample project for testing."""
- project_data = {
- "name": "Test Project",
- "description": "Test Description",
- "config": "<View><Image name='img' value='$image'/></View>"
- }
- response = test_client.post("/api/projects", json=project_data)
- return response.json()
- def test_list_tasks_empty(test_client):
- """Test listing tasks when database is empty."""
- response = test_client.get("/api/tasks")
- assert response.status_code == 200
- assert response.json() == []
- def test_create_task(test_client, sample_project):
- """Test creating a new task."""
- task_data = {
- "project_id": sample_project["id"],
- "name": "Test Task",
- "data": {"image_url": "https://example.com/image.jpg"},
- "assigned_to": "user_001"
- }
-
- response = test_client.post("/api/tasks", json=task_data)
- assert response.status_code == 201
-
- data = response.json()
- assert data["name"] == task_data["name"]
- assert data["project_id"] == task_data["project_id"]
- assert data["data"] == task_data["data"]
- assert data["assigned_to"] == task_data["assigned_to"]
- assert data["status"] == "pending"
- assert "id" in data
- assert data["id"].startswith("task_")
- assert data["progress"] == 0.0
- assert "created_at" in data
- def test_create_task_invalid_project(test_client):
- """Test creating a task with invalid project_id fails."""
- task_data = {
- "project_id": "nonexistent_project",
- "name": "Test Task",
- "data": {"image_url": "https://example.com/image.jpg"}
- }
-
- response = test_client.post("/api/tasks", json=task_data)
- assert response.status_code == 404
- assert "not found" in response.json()["detail"].lower()
- def test_get_task(test_client, sample_project):
- """Test getting a task by ID."""
- # Create a task first
- task_data = {
- "project_id": sample_project["id"],
- "name": "Test Task",
- "data": {"image_url": "https://example.com/image.jpg"}
- }
- create_response = test_client.post("/api/tasks", json=task_data)
- task_id = create_response.json()["id"]
-
- # Get the task
- response = test_client.get(f"/api/tasks/{task_id}")
- assert response.status_code == 200
-
- data = response.json()
- assert data["id"] == task_id
- assert data["name"] == task_data["name"]
- def test_get_task_not_found(test_client):
- """Test getting a non-existent task returns 404."""
- response = test_client.get("/api/tasks/nonexistent_id")
- assert response.status_code == 404
- assert "not found" in response.json()["detail"].lower()
- def test_update_task(test_client, sample_project):
- """Test updating a task."""
- # Create a task first
- task_data = {
- "project_id": sample_project["id"],
- "name": "Original Name",
- "data": {"image_url": "https://example.com/image.jpg"}
- }
- create_response = test_client.post("/api/tasks", json=task_data)
- task_id = create_response.json()["id"]
-
- # Update the task
- update_data = {
- "name": "Updated Name",
- "status": "in_progress"
- }
- response = test_client.put(f"/api/tasks/{task_id}", json=update_data)
- assert response.status_code == 200
-
- data = response.json()
- assert data["name"] == update_data["name"]
- assert data["status"] == update_data["status"]
- assert data["data"] == task_data["data"] # Data unchanged
- def test_update_task_not_found(test_client):
- """Test updating a non-existent task returns 404."""
- update_data = {"name": "Updated Name"}
- response = test_client.put("/api/tasks/nonexistent_id", json=update_data)
- assert response.status_code == 404
- def test_delete_task(test_client, sample_project):
- """Test deleting a task."""
- # Create a task first
- task_data = {
- "project_id": sample_project["id"],
- "name": "Test Task",
- "data": {"image_url": "https://example.com/image.jpg"}
- }
- create_response = test_client.post("/api/tasks", json=task_data)
- task_id = create_response.json()["id"]
-
- # Delete the task
- response = test_client.delete(f"/api/tasks/{task_id}")
- assert response.status_code == 204
-
- # Verify task is deleted
- get_response = test_client.get(f"/api/tasks/{task_id}")
- assert get_response.status_code == 404
- def test_delete_task_not_found(test_client):
- """Test deleting a non-existent task returns 404."""
- response = test_client.delete("/api/tasks/nonexistent_id")
- assert response.status_code == 404
- def test_list_tasks_after_creation(test_client, sample_project):
- """Test listing tasks after creating some."""
- # Create multiple tasks
- for i in range(3):
- task_data = {
- "project_id": sample_project["id"],
- "name": f"Task {i}",
- "data": {"image_url": f"https://example.com/image{i}.jpg"}
- }
- test_client.post("/api/tasks", json=task_data)
-
- # List tasks
- response = test_client.get("/api/tasks")
- assert response.status_code == 200
-
- data = response.json()
- assert len(data) == 3
- assert all("id" in task for task in data)
- assert all("progress" in task for task in data)
- def test_list_tasks_filter_by_project(test_client, sample_project):
- """Test filtering tasks by project_id."""
- # Create another project
- project2_data = {
- "name": "Project 2",
- "description": "Description 2",
- "config": "<View></View>"
- }
- project2_response = test_client.post("/api/projects", json=project2_data)
- project2 = project2_response.json()
-
- # Create tasks for both projects
- task1_data = {
- "project_id": sample_project["id"],
- "name": "Task 1",
- "data": {"image_url": "https://example.com/image1.jpg"}
- }
- test_client.post("/api/tasks", json=task1_data)
-
- task2_data = {
- "project_id": project2["id"],
- "name": "Task 2",
- "data": {"image_url": "https://example.com/image2.jpg"}
- }
- test_client.post("/api/tasks", json=task2_data)
-
- # Filter by first project
- response = test_client.get(f"/api/tasks?project_id={sample_project['id']}")
- assert response.status_code == 200
-
- data = response.json()
- assert len(data) == 1
- assert data[0]["project_id"] == sample_project["id"]
- def test_list_tasks_filter_by_status(test_client, sample_project):
- """Test filtering tasks by status."""
- # Create tasks with different statuses
- task1_data = {
- "project_id": sample_project["id"],
- "name": "Task 1",
- "data": {"image_url": "https://example.com/image1.jpg"}
- }
- response1 = test_client.post("/api/tasks", json=task1_data)
- task1_id = response1.json()["id"]
-
- task2_data = {
- "project_id": sample_project["id"],
- "name": "Task 2",
- "data": {"image_url": "https://example.com/image2.jpg"}
- }
- test_client.post("/api/tasks", json=task2_data)
-
- # Update first task status
- test_client.put(f"/api/tasks/{task1_id}", json={"status": "in_progress"})
-
- # Filter by status
- response = test_client.get("/api/tasks?status=in_progress")
- assert response.status_code == 200
-
- data = response.json()
- assert len(data) == 1
- assert data[0]["status"] == "in_progress"
- def test_get_project_tasks(test_client, sample_project):
- """Test getting all tasks for a specific project."""
- # Create tasks for the project
- for i in range(2):
- task_data = {
- "project_id": sample_project["id"],
- "name": f"Task {i}",
- "data": {"image_url": f"https://example.com/image{i}.jpg"}
- }
- test_client.post("/api/tasks", json=task_data)
-
- # Get project tasks using the alternative endpoint
- response = test_client.get(f"/api/tasks/projects/{sample_project['id']}/tasks")
- assert response.status_code == 200
-
- data = response.json()
- assert len(data) == 2
- assert all(task["project_id"] == sample_project["id"] for task in data)
- def test_get_project_tasks_not_found(test_client):
- """Test getting tasks for non-existent project returns 404."""
- response = test_client.get("/api/tasks/projects/nonexistent_id/tasks")
- assert response.status_code == 404
|