diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2025-12-19 17:24:44 +0100 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2025-12-19 17:24:44 +0100 |
| commit | dc0ff6c1a870bb0e01f35c653303da08fc19485b (patch) | |
| tree | 47f3138ad0fc545b6b052b4c5e9c0e8b26e2e412 /servers/taskwarrior/tests | |
| parent | bedbd86e8c70d8d8cfa964842e1eab314384271d (diff) | |
feat: implement task modification functionality in TaskWarrior server
- Added `modify_task` method to allow modification of tasks based on a filter expression, supporting parameters for project, priority, due date, description, and tags.
- Implemented validation for modification parameters, ensuring at least one parameter is provided and that priority and tag formats are correct.
- Introduced corresponding tests to validate the functionality of task modifications, including edge cases for invalid inputs and multiple modifications.
- Enhanced docstrings for clarity and detailed usage examples.
Diffstat (limited to 'servers/taskwarrior/tests')
| -rw-r--r-- | servers/taskwarrior/tests/test_server.py | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/servers/taskwarrior/tests/test_server.py b/servers/taskwarrior/tests/test_server.py index 97f7268..601a535 100644 --- a/servers/taskwarrior/tests/test_server.py +++ b/servers/taskwarrior/tests/test_server.py @@ -212,3 +212,168 @@ class TestTaskWarriorServer: await taskwarrior_server.manage_context("set") assert "Context name is required" in str(exc_info.value) + + @pytest.mark.asyncio + async def test_modify_task_project(self, taskwarrior_server): + """Test modifying a task's project.""" + mock_output = "Modified 1 task." + + with patch.object( + taskwarrior_server, '_run_task_command', + new_callable=AsyncMock, + return_value=(mock_output, '', 0) + ): + result = await taskwarrior_server.modify_task( + "uuid:test-uuid-123", + project="NewProject" + ) + assert result["filter_expr"] == "uuid:test-uuid-123" + assert result["modifications"]["project"] == "NewProject" + + @pytest.mark.asyncio + async def test_modify_task_priority(self, taskwarrior_server): + """Test modifying a task's priority.""" + mock_output = "Modified 1 task." + + with patch.object( + taskwarrior_server, '_run_task_command', + new_callable=AsyncMock, + return_value=(mock_output, '', 0) + ): + result = await taskwarrior_server.modify_task( + "uuid:test-uuid-123", + priority="H" + ) + assert result["modifications"]["priority"] == "H" + + @pytest.mark.asyncio + async def test_modify_task_clear_priority(self, taskwarrior_server): + """Test clearing a task's priority.""" + mock_output = "Modified 1 task." + + with patch.object( + taskwarrior_server, '_run_task_command', + new_callable=AsyncMock, + return_value=(mock_output, '', 0) + ): + result = await taskwarrior_server.modify_task( + "uuid:test-uuid-123", + priority="" + ) + assert result["modifications"]["priority"] is None + + @pytest.mark.asyncio + async def test_modify_task_due(self, taskwarrior_server): + """Test modifying a task's due date.""" + mock_output = "Modified 1 task." + + with patch.object( + taskwarrior_server, '_run_task_command', + new_callable=AsyncMock, + return_value=(mock_output, '', 0) + ): + result = await taskwarrior_server.modify_task( + "uuid:test-uuid-123", + due="tomorrow" + ) + assert result["modifications"]["due"] == "tomorrow" + + @pytest.mark.asyncio + async def test_modify_task_description(self, taskwarrior_server): + """Test modifying a task's description.""" + mock_output = "Modified 1 task." + + with patch.object( + taskwarrior_server, '_run_task_command', + new_callable=AsyncMock, + return_value=(mock_output, '', 0) + ): + result = await taskwarrior_server.modify_task( + "uuid:test-uuid-123", + description="New description" + ) + assert result["modifications"]["description"] == "New description" + + @pytest.mark.asyncio + async def test_modify_task_tags(self, taskwarrior_server): + """Test modifying a task's tags.""" + mock_output = "Modified 1 task." + + with patch.object( + taskwarrior_server, '_run_task_command', + new_callable=AsyncMock, + return_value=(mock_output, '', 0) + ): + result = await taskwarrior_server.modify_task( + "uuid:test-uuid-123", + tags=["+urgent", "-later"] + ) + assert result["modifications"]["tags"] == ["+urgent", "-later"] + + @pytest.mark.asyncio + async def test_modify_task_multiple_fields(self, taskwarrior_server): + """Test modifying multiple fields at once.""" + mock_output = "Modified 1 task." + + with patch.object( + taskwarrior_server, '_run_task_command', + new_callable=AsyncMock, + return_value=(mock_output, '', 0) + ): + result = await taskwarrior_server.modify_task( + "+work", + project="Work", + priority="H", + tags=["+urgent"] + ) + assert result["filter_expr"] == "+work" + assert result["modifications"]["project"] == "Work" + assert result["modifications"]["priority"] == "H" + assert result["modifications"]["tags"] == ["+urgent"] + + @pytest.mark.asyncio + async def test_modify_task_no_modifications(self, taskwarrior_server): + """Test that modifying without any parameters raises ValueError.""" + with pytest.raises(ValueError) as exc_info: + await taskwarrior_server.modify_task("uuid:test-uuid-123") + + assert "At least one modification parameter must be provided" in str(exc_info.value) + + @pytest.mark.asyncio + async def test_modify_task_invalid_priority(self, taskwarrior_server): + """Test that invalid priority raises ValueError.""" + with pytest.raises(ValueError) as exc_info: + await taskwarrior_server.modify_task( + "uuid:test-uuid-123", + priority="X" + ) + + assert "Priority must be H, M, or L" in str(exc_info.value) + + @pytest.mark.asyncio + async def test_modify_task_invalid_tag_format(self, taskwarrior_server): + """Test that tags without +/- prefix raise ValueError.""" + with pytest.raises(ValueError) as exc_info: + await taskwarrior_server.modify_task( + "uuid:test-uuid-123", + tags=["invalidtag"] + ) + + assert "Tags must start with + or -" in str(exc_info.value) + + @pytest.mark.asyncio + async def test_modify_task_with_filter_expression(self, taskwarrior_server): + """Test modifying tasks with complex filter expression.""" + mock_output = "Modified 2 tasks." + + with patch.object( + taskwarrior_server, '_run_task_command', + new_callable=AsyncMock, + return_value=(mock_output, '', 0) + ): + result = await taskwarrior_server.modify_task( + "project:Home status:pending", + priority="M" + ) + assert result["filter_expr"] == "project:Home status:pending" + assert result["modifications"]["priority"] == "M" |
