# Testing Planner

Planner mocks - plans, tasks, buckets, updates and assignments.

Mock Planner connections to test services that work with plans, tasks, and buckets.

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

## Getting plans {#getting-plans}

**The service**:

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

class GetMyPlans(Service):
    name = 'planner.plans.get'

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

        planner = conn.planner()
        plans = planner.list_my_plans()

        self.response.payload = {
            'plans': [{'title': p['title'], 'id': p['id']} for p in plans]
        }
```

**The test**:

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

class TestGetMyPlans(ServiceTestCase):

    def test_returns_plans(self):

        self.set_response('ms365.Planner.planner', {'id': 'planner-123'})
        self.set_response('ms365.Planner.planner.list_my_plans', [
            {'title': 'Q1 Goals', 'id': 'plan-001'},
            {'title': 'Product Launch', 'id': 'plan-002'},
            {'title': 'Team Building', 'id': 'plan-003'}
        ])

        service = self.invoke(GetMyPlans)

        plans = service.response.payload['plans']
        self.assertEqual(len(plans), 3)
        self.assertEqual(plans[0]['title'], 'Q1 Goals')
```

## Getting plan tasks {#getting-plan-tasks}

```python
class TestGetPlanTasks(ServiceTestCase):

    def test_returns_tasks(self):

        self.set_response('ms365.Planner.planner', {'id': 'planner-123'})
        self.set_response('ms365.Planner.planner.get_plan', {'id': 'plan-001', 'title': 'Q1 Goals'})
        self.set_response('ms365.Planner.planner.get_plan.list_tasks', [
            {'title': 'Review budget', 'id': 'task-001', 'percent_complete': 100},
            {'title': 'Hire new developer', 'id': 'task-002', 'percent_complete': 50},
            {'title': 'Launch feature X', 'id': 'task-003', 'percent_complete': 0}
        ])

        service = self.invoke(GetPlanTasks, plan_id='plan-001')

        self.assertEqual(len(service.response.payload['tasks']), 3)
        self.assertEqual(service.response.payload['tasks'][1]['percent_complete'], 50)
```

## Creating tasks {#creating-tasks}

```python
class TestCreateTask(ServiceTestCase):

    def test_creates_task(self):

        self.set_response('ms365.Planner.planner', {'id': 'planner-123'})
        self.set_response('ms365.Planner.planner.get_plan', {'id': 'plan-001', 'title': 'Q1 Goals'})
        self.set_response('ms365.Planner.planner.get_plan.create_task', {
            'id': 'task-new-001',
            'title': 'New Task'
        })

        service = self.invoke(CreatePlanTask,
            plan_id='plan-001',
            bucket_id='bucket-001',
            title='New Task'
        )

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

## Getting buckets {#getting-buckets}

```python
class TestGetPlanBuckets(ServiceTestCase):

    def test_returns_buckets(self):

        self.set_response('ms365.Planner.planner', {'id': 'planner-123'})
        self.set_response('ms365.Planner.planner.get_plan', {'id': 'plan-001', 'title': 'Q1 Goals'})
        self.set_response('ms365.Planner.planner.get_plan.list_buckets', [
            {'name': 'To Do', 'id': 'bucket-001'},
            {'name': 'In Progress', 'id': 'bucket-002'},
            {'name': 'Done', 'id': 'bucket-003'}
        ])

        service = self.invoke(GetPlanBuckets, plan_id='plan-001')

        self.assertEqual(len(service.response.payload['buckets']), 3)
        self.assertEqual(service.response.payload['buckets'][1]['name'], 'In Progress')
```

## Updating tasks {#updating-tasks}

```python
class TestUpdateTask(ServiceTestCase):

    def test_updates_task(self):

        self.set_response('ms365.Planner.planner', {'id': 'planner-123'})
        self.set_response('ms365.Planner.planner.get_task', {
            'id': 'task-001',
            'title': 'Old Title',
            'percent_complete': 0
        })
        self.set_response('ms365.Planner.planner.get_task.update', True)

        service = self.invoke(UpdateTask,
            task_id='task-001',
            updates={'percent_complete': 100, 'title': 'Completed Task'}
        )

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

## Assigning tasks {#assigning-tasks}

```python
class TestAssignTask(ServiceTestCase):

    def test_assigns_task(self):

        self.set_response('ms365.Planner.planner', {'id': 'planner-123'})
        self.set_response('ms365.Planner.planner.get_task', {
            'id': 'task-001',
            'title': 'Task to Assign'
        })
        self.set_response('ms365.Planner.planner.get_task.assign', True)

        service = self.invoke(AssignTask, task_id='task-001', user_id='user-001')

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

## 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
