todo-backend / Chatbot /tests /unit /test_update_task_tool.py
Fizu123's picture
BACKEND FIX: Filter by credential provider during login
08af9fd
"""
Unit tests for update_task tool.
"""
import pytest
from unittest.mock import MagicMock, patch
from sqlmodel import Session
from backend.mcp_server.tools.update_task import update_task
from backend.mcp_server.schemas import ErrorCode
def test_update_task_title_only():
"""Test updating only the task title."""
mock_task = MagicMock()
mock_task.id = 1
mock_task.title = "Old Title"
mock_task.description = "Original description"
mock_task.completed = False
with patch('backend.mcp_server.tools.update_task.get_engine') as mock_get_engine, \
patch('backend.mcp_server.tools.update_task.Session') as mock_session_class, \
patch('backend.mcp_server.tools.update_task.select') as mock_select:
mock_get_engine.return_value = MagicMock()
mock_session = MagicMock()
mock_session_class.return_value.__enter__.return_value = mock_session
mock_session_class.return_value.__exit__.return_value = False
mock_session.exec.return_value.first.return_value = mock_task
result = update_task(user_id="user_abc123", task_id=1, title="New Title")
assert result["success"] is True
assert result["data"]["task_id"] == 1
assert result["data"]["status"] == "updated"
assert result["data"]["title"] == "New Title"
assert result["error"] is None
def test_update_task_description_only():
"""Test updating only the task description."""
mock_task = MagicMock()
mock_task.id = 1
mock_task.title = "Task Title"
mock_task.description = "Old description"
mock_task.completed = False
with patch('backend.mcp_server.tools.update_task.get_engine') as mock_get_engine, \
patch('backend.mcp_server.tools.update_task.Session') as mock_session_class, \
patch('backend.mcp_server.tools.update_task.select') as mock_select:
mock_get_engine.return_value = MagicMock()
mock_session = MagicMock()
mock_session_class.return_value.__enter__.return_value = mock_session
mock_session_class.return_value.__exit__.return_value = False
mock_session.exec.return_value.first.return_value = mock_task
result = update_task(user_id="user_abc123", task_id=1, description="New description")
assert result["success"] is True
assert result["data"]["task_id"] == 1
assert result["data"]["status"] == "updated"
def test_update_task_both_fields():
"""Test updating both title and description."""
mock_task = MagicMock()
mock_task.id = 1
mock_task.title = "Old Title"
mock_task.description = "Old description"
mock_task.completed = False
with patch('backend.mcp_server.tools.update_task.get_engine') as mock_get_engine, \
patch('backend.mcp_server.tools.update_task.Session') as mock_session_class, \
patch('backend.mcp_server.tools.update_task.select') as mock_select:
mock_get_engine.return_value = MagicMock()
mock_session = MagicMock()
mock_session_class.return_value.__enter__.return_value = mock_session
mock_session_class.return_value.__exit__.return_value = False
mock_session.exec.return_value.first.return_value = mock_task
result = update_task(
user_id="user_abc123",
task_id=1,
title="New Title",
description="New description"
)
assert result["success"] is True
assert result["data"]["task_id"] == 1
def test_update_task_neither_field():
"""Test updating with neither title nor description returns error."""
result = update_task(user_id="user_abc123", task_id=1)
assert result["success"] is False
assert result["error"]["code"] == ErrorCode.INVALID_INPUT
assert "at least one" in result["error"]["message"].lower()
def test_update_task_not_found():
"""Test updating a non-existent task returns NOT_FOUND."""
with patch('backend.mcp_server.tools.update_task.get_engine') as mock_get_engine, \
patch('backend.mcp_server.tools.update_task.Session') as mock_session_class, \
patch('backend.mcp_server.tools.update_task.select') as mock_select:
mock_get_engine.return_value = MagicMock()
mock_session = MagicMock()
mock_session_class.return_value.__enter__.return_value = mock_session
mock_session_class.return_value.__exit__.return_value = False
mock_session.exec.return_value.first.return_value = None
result = update_task(user_id="user_abc123", task_id=999, title="New Title")
assert result["success"] is False
assert result["data"] is None
assert result["error"]["code"] == ErrorCode.NOT_FOUND
def test_update_task_invalid_title_length():
"""Test updating with title that exceeds 200 characters."""
result = update_task(
user_id="user_abc123",
task_id=1,
title="A" * 201
)
assert result["success"] is False
assert result["error"]["code"] == ErrorCode.INVALID_INPUT
def test_update_task_invalid_description_length():
"""Test updating with description that exceeds 1000 characters."""
result = update_task(
user_id="user_abc123",
task_id=1,
description="A" * 1001
)
assert result["success"] is False
assert result["error"]["code"] == ErrorCode.INVALID_INPUT
def test_update_task_invalid_user_id():
"""Test updating a task with empty user_id."""
result = update_task(user_id="", task_id=1, title="New Title")
assert result["success"] is False
assert result["error"]["code"] == ErrorCode.INVALID_INPUT
def test_update_task_invalid_task_id():
"""Test updating a task with invalid task_id."""
result = update_task(user_id="user_abc123", task_id=0, title="New Title")
assert result["success"] is False
assert result["error"]["code"] == ErrorCode.INVALID_INPUT
def test_update_task_response_format():
"""Test update_task returns correct response format."""
mock_task = MagicMock()
mock_task.id = 1
mock_task.title = "Task Title"
mock_task.description = "Description"
mock_task.completed = False
with patch('backend.mcp_server.tools.update_task.get_engine') as mock_get_engine, \
patch('backend.mcp_server.tools.update_task.Session') as mock_session_class, \
patch('backend.mcp_server.tools.update_task.select') as mock_select:
mock_get_engine.return_value = MagicMock()
mock_session = MagicMock()
mock_session_class.return_value.__enter__.return_value = mock_session
mock_session_class.return_value.__exit__.return_value = False
mock_session.exec.return_value.first.return_value = mock_task
result = update_task(user_id="user_abc123", task_id=1, title="New Title")
# Response must have all three top-level keys
assert "success" in result
assert "data" in result
assert "error" in result
# Data must have required fields
assert result["data"]["task_id"] is not None
assert result["data"]["status"] is not None
assert result["data"]["title"] is not None
def test_update_task_filters_by_user_id():
"""Test that update_task filters by user_id."""
mock_task = MagicMock()
mock_task.id = 1
mock_task.title = "Task Title"
mock_task.user_id = "user_abc123"
with patch('backend.mcp_server.tools.update_task.get_engine') as mock_get_engine, \
patch('backend.mcp_server.tools.update_task.Session') as mock_session_class, \
patch('backend.mcp_server.tools.update_task.select') as mock_select, \
patch('backend.mcp_server.tools.update_task.Task') as mock_task_class:
mock_get_engine.return_value = MagicMock()
mock_session = MagicMock()
mock_session_class.return_value.__enter__.return_value = mock_session
mock_session_class.return_value.__exit__.return_value = False
mock_session.exec.return_value.first.return_value = mock_task
update_task(user_id="user_abc123", task_id=1, title="New Title")
# Verify select was called
mock_select.assert_called()
def test_update_task_whitespace_only_title():
"""Test updating with title that contains only whitespace."""
result = update_task(
user_id="user_abc123",
task_id=1,
title=" "
)
assert result["success"] is False
assert result["error"]["code"] == ErrorCode.INVALID_INPUT
def test_update_task_empty_title():
"""Test updating with empty string title."""
result = update_task(
user_id="user_abc123",
task_id=1,
title=""
)
assert result["success"] is False
assert result["error"]["code"] == ErrorCode.INVALID_INPUT