# Testing Tasks

Tasks mocks - ToDo lists, creating, completing and deleting tasks.

Mock Tasks connections to test services that work with ToDo lists and tasks.

**Note:** If you're new to unit testing with Zato, check the [tutorial](https://zato.io/docs/api-testing/tutorial.html) first.

## Getting task lists {#getting-task-lists}

**The service**:

```python
from zato.server.service import Service

class GetTaskLists(Service):
    name = 'tasks.lists.get'

    def handle(self):
        conn = self.microsoft.cloud['ms365.Tasks']

        todo = conn.tasks()
        task_lists = todo.get_folders()

        self.response.payload = {
            'lists': [{'name': tl['name'], 'id': tl['id']} for tl in task_lists]
        }
```

**The test**:

```python
from zato_testing import ServiceTestCase
from myapp.services import GetTaskLists

class TestGetTaskLists(ServiceTestCase):

    def test_returns_task_lists(self):

        self.set_response('ms365.Tasks.tasks', {'id': 'tasks-123'})
        self.set_response('ms365.Tasks.tasks.get_folders', [
            {'name': 'Tasks', 'id': 'list-001'},
            {'name': 'Shopping', 'id': 'list-002'},
            {'name': 'Work', 'id': 'list-003'}
        ])

        service = self.invoke(GetTaskLists)

        lists = service.response.payload['lists']
        self.assertEqual(len(lists), 3)
        self.assertEqual(lists[0]['name'], 'Tasks')
```

## Getting tasks {#getting-tasks}

```python
class TestGetTasks(ServiceTestCase):

    def test_returns_tasks_from_default_list(self):

        self.set_response('ms365.Tasks.tasks', {'id': 'tasks-123'})
        self.set_response('ms365.Tasks.tasks.get_default_folder', {'id': 'list-001', 'name': 'Tasks'})
        self.set_response('ms365.Tasks.tasks.get_default_folder.get_tasks', [
            {'title': 'Buy groceries', 'id': 'task-001', 'status': 'notStarted'},
            {'title': 'Call dentist', 'id': 'task-002', 'status': 'inProgress'},
            {'title': 'Pay bills', 'id': 'task-003', 'status': 'completed'}
        ])

        service = self.invoke(GetTasks)

        self.assertEqual(len(service.response.payload['tasks']), 3)
        self.assertEqual(service.response.payload['tasks'][1]['status'], 'inProgress')

    def test_returns_tasks_from_specific_list(self):

        self.set_response('ms365.Tasks.tasks', {'id': 'tasks-123'})
        self.set_response('ms365.Tasks.tasks.get_folder', {'id': 'list-002', 'name': 'Work'})
        self.set_response('ms365.Tasks.tasks.get_folder.get_tasks', [
            {'title': 'Review PR', 'id': 'task-101', 'status': 'notStarted'},
            {'title': 'Write docs', 'id': 'task-102', 'status': 'notStarted'}
        ])

        service = self.invoke(GetTasks, list_id='list-002')

        self.assertEqual(len(service.response.payload['tasks']), 2)
```

## Creating tasks {#creating-tasks}

```python
class TestCreateTask(ServiceTestCase):

    def test_creates_task(self):

        self.set_response('ms365.Tasks.tasks', {'id': 'tasks-123'})
        self.set_response('ms365.Tasks.tasks.get_default_folder', {'id': 'list-001', 'name': 'Tasks'})
        self.set_response('ms365.Tasks.tasks.get_default_folder.new_task', {
            'object_id': 'task-new-001',
            'title': None,
            'due': None
        })
        self.set_response('ms365.Tasks.tasks.get_default_folder.new_task.save', True)

        service = self.invoke(CreateTask,
            title='New Important Task',
            due_date='2024-03-25'
        )

        self.assertEqual(service.response.payload['created'], True)
        self.assertEqual(service.response.payload['task_id'], 'task-new-001')
```

## Completing tasks {#completing-tasks}

```python
class TestCompleteTask(ServiceTestCase):

    def test_completes_task(self):

        self.set_response('ms365.Tasks.tasks', {'id': 'tasks-123'})
        self.set_response('ms365.Tasks.tasks.get_default_folder', {'id': 'list-001', 'name': 'Tasks'})
        self.set_response('ms365.Tasks.tasks.get_default_folder.get_task', {
            'id': 'task-001',
            'title': 'Task to Complete'
        })
        self.set_response('ms365.Tasks.tasks.get_default_folder.get_task.mark_completed', None)
        self.set_response('ms365.Tasks.tasks.get_default_folder.get_task.save', True)

        service = self.invoke(CompleteTask, task_id='task-001')

        self.assertEqual(service.response.payload['completed'], True)
```

## Deleting tasks {#deleting-tasks}

```python
class TestDeleteTask(ServiceTestCase):

    def test_deletes_task(self):

        self.set_response('ms365.Tasks.tasks', {'id': 'tasks-123'})
        self.set_response('ms365.Tasks.tasks.get_default_folder', {'id': 'list-001', 'name': 'Tasks'})
        self.set_response('ms365.Tasks.tasks.get_default_folder.get_task', {
            'id': 'task-001',
            'title': 'Task to Delete'
        })
        self.set_response('ms365.Tasks.tasks.get_default_folder.get_task.delete', True)

        service = self.invoke(DeleteTask, task_id='task-001')

        self.assertEqual(service.response.payload['deleted'], True)
```

## Creating task lists {#creating-task-lists}

```python
class TestCreateTaskList(ServiceTestCase):

    def test_creates_task_list(self):

        self.set_response('ms365.Tasks.tasks', {'id': 'tasks-123'})
        self.set_response('ms365.Tasks.tasks.new_folder', {
            'id': 'list-new-001',
            'name': 'New List'
        })

        service = self.invoke(CreateTaskList, name='New List')

        self.assertEqual(service.response.payload['created'], True)
        self.assertEqual(service.response.payload['list_id'], 'list-new-001')
```

## Learn more {#learn-more}

- [API testing](https://zato.io/docs/api-testing/) - Tests in plain English, run against real or mocked connections
- [API testing tutorial](https://zato.io/docs/api-testing/tutorial.html) - A complete test suite, from the first scenario to the report
- [Testing REST connections](https://zato.io/docs/api-testing/rest.html) - Mock outgoing REST calls and assert on what your service sent
- [Testing SQL connections](https://zato.io/docs/api-testing/sql.html) - Mock database queries and the rows they return
- [Testing LDAP connections](https://zato.io/docs/api-testing/ldap.html) - Mock directory lookups and the entries they find
- [Testing Microsoft 365](https://zato.io/docs/api-testing/ms365/) - Mock mailboxes, calendars, SharePoint, Teams and the rest
- [Testing service invocations](https://zato.io/docs/api-testing/services.html) - Services that call other services, with the callees mocked
- [Testing Jira connections](https://zato.io/docs/api-testing/jira.html) - Mock Jira API calls and the issues they return
- [Tests in CI/CD](https://zato.io/docs/api-testing/ci-cd.html) - Running the suite in a pipeline and reading its output
