TaskFlow / tests /unit /tools /test_list_tasks.py
BilalCode's picture
taskflow todo app
310260a
Raw
History Blame Contribute Delete
7.15 kB
"""
Unit Tests for list_tasks MCP Tool
Tests the list_tasks tool functionality including:
- Returns all tasks for user
- Returns empty array for user with no tasks
- Filters by user_id correctly
- Returns correct counts (total, completed, pending)
- Handles database errors gracefully
"""
import pytest
from src.tools.list_tasks import list_tasks_internal
from tests.utils.task_helpers import create_test_task, create_multiple_tasks, delete_all_tasks
@pytest.mark.unit
@pytest.mark.asyncio
async def test_list_tasks_returns_all_tasks_for_user(mock_mcp_context, test_session):
"""
Test: list_tasks returns all tasks for user
Verifies that list_tasks returns all tasks belonging to the authenticated user.
"""
# Setup: Create 3 tasks for user
create_multiple_tasks(test_session, mock_mcp_context.user_id, count=3, title_prefix="Task")
# Execute
result = await list_tasks_internal(ctx=mock_mcp_context)
# Assert
assert "tasks" in result
assert len(result["tasks"]) == 3
assert result["total"] == 3
assert result["pending_count"] == 3
assert result["completed_count"] == 0
# Verify all tasks belong to user
for task in result["tasks"]:
assert "id" in task
assert "title" in task
assert "completed" in task
@pytest.mark.unit
@pytest.mark.asyncio
async def test_list_tasks_returns_empty_array_for_user_with_no_tasks(mock_mcp_context, test_session):
"""
Test: list_tasks returns empty array for user with no tasks
Verifies that list_tasks returns empty array when user has no tasks.
"""
# Ensure no tasks exist
delete_all_tasks(test_session, mock_mcp_context.user_id)
# Execute
result = await list_tasks_internal(ctx=mock_mcp_context)
# Assert
assert "tasks" in result
assert len(result["tasks"]) == 0
assert result["total"] == 0
assert result["pending_count"] == 0
assert result["completed_count"] == 0
@pytest.mark.unit
@pytest.mark.asyncio
async def test_list_tasks_filters_by_user_id_correctly(mock_mcp_context, mock_mcp_context_user2, test_session):
"""
Test: list_tasks filters by user_id correctly
Verifies that list_tasks only returns tasks for the authenticated user.
"""
# Setup: Create tasks for both users
create_multiple_tasks(test_session, mock_mcp_context.user_id, count=3, title_prefix="User1 Task")
create_multiple_tasks(test_session, mock_mcp_context_user2.user_id, count=2, title_prefix="User2 Task")
# Execute for user 1
result1 = await list_tasks_internal(ctx=mock_mcp_context)
# Assert user 1 sees only their tasks
assert len(result1["tasks"]) == 3
assert result1["total"] == 3
for task in result1["tasks"]:
assert "User1 Task" in task["title"]
# Execute for user 2
result2 = await list_tasks_internal(ctx=mock_mcp_context_user2)
# Assert user 2 sees only their tasks
assert len(result2["tasks"]) == 2
assert result2["total"] == 2
for task in result2["tasks"]:
assert "User2 Task" in task["title"]
@pytest.mark.unit
@pytest.mark.asyncio
async def test_list_tasks_returns_correct_counts(mock_mcp_context, test_session):
"""
Test: list_tasks returns correct counts (total, completed, pending)
Verifies that list_tasks returns accurate counts for total, completed, and pending tasks.
"""
# Setup: Create 5 tasks, 2 completed and 3 pending
create_multiple_tasks(test_session, mock_mcp_context.user_id, count=2, title_prefix="Completed", completed=True)
create_multiple_tasks(test_session, mock_mcp_context.user_id, count=3, title_prefix="Pending", completed=False)
# Execute
result = await list_tasks_internal(ctx=mock_mcp_context)
# Assert
assert result["total"] == 5
assert result["completed_count"] == 2
assert result["pending_count"] == 3
# Verify task array contains all tasks
assert len(result["tasks"]) == 5
@pytest.mark.unit
@pytest.mark.asyncio
async def test_list_tasks_handles_database_errors_gracefully(mock_mcp_context):
"""
Test: list_tasks handles database errors gracefully
Verifies that list_tasks returns error response for database failures.
"""
# This test verifies error handling exists in the implementation
# The actual implementation has try/except block that catches database errors
# Execute with valid context (should succeed normally)
result = await list_tasks_internal(ctx=mock_mcp_context)
# Verify result structure is valid
assert "tasks" in result
assert "total" in result
assert "completed_count" in result
assert "pending_count" in result
# If error occurs, verify error structure
if "status" in result and result["status"] == "error":
assert "error" in result
assert isinstance(result["error"], str)
@pytest.mark.unit
@pytest.mark.asyncio
async def test_list_tasks_includes_all_required_fields(mock_mcp_context, test_session):
"""
Test: list_tasks includes all required fields in task objects
Verifies that each task in the response contains all required fields.
"""
# Setup: Create a task with all fields
create_test_task(
test_session,
mock_mcp_context.user_id,
title="Complete Task",
description="Task description",
completed=False
)
# Execute
result = await list_tasks_internal(ctx=mock_mcp_context)
# Assert
assert len(result["tasks"]) == 1
task = result["tasks"][0]
# Verify all required fields are present
assert "id" in task
assert "title" in task
assert "description" in task
assert "completed" in task
assert "created_at" in task
assert "updated_at" in task
# Verify field types
assert isinstance(task["id"], int)
assert isinstance(task["title"], str)
assert isinstance(task["completed"], bool)
assert isinstance(task["created_at"], str)
assert isinstance(task["updated_at"], str)
@pytest.mark.unit
@pytest.mark.asyncio
async def test_list_tasks_with_mixed_completion_status(mock_mcp_context, test_session):
"""
Test: list_tasks with mixed completion status
Verifies that list_tasks correctly returns tasks with different completion statuses.
"""
# Setup: Create tasks with mixed statuses
create_test_task(test_session, mock_mcp_context.user_id, title="Task 1", completed=True)
create_test_task(test_session, mock_mcp_context.user_id, title="Task 2", completed=False)
create_test_task(test_session, mock_mcp_context.user_id, title="Task 3", completed=True)
create_test_task(test_session, mock_mcp_context.user_id, title="Task 4", completed=False)
# Execute
result = await list_tasks_internal(ctx=mock_mcp_context)
# Assert
assert result["total"] == 4
assert result["completed_count"] == 2
assert result["pending_count"] == 2
# Verify completed status in tasks
completed_tasks = [t for t in result["tasks"] if t["completed"]]
pending_tasks = [t for t in result["tasks"] if not t["completed"]]
assert len(completed_tasks) == 2
assert len(pending_tasks) == 2