Exemplo n.º 1
0
    def test_bulk_partial_update(self):
        todo1 = TodoFactory(project=self.project,
                            step=self.step,
                            title='Test title1')
        todo2 = TodoFactory(project=self.project,
                            step=self.step,
                            title='Test title2')
        todo3 = TodoFactory(project=self.project,
                            step=self.step,
                            title='Test title3')
        todo_should_not_be_updated = TodoFactory(project=self.project,
                                                 step=self.step,
                                                 title='Not updated')
        # Change titles
        todos_with_updated_titles = [{
            'id': x.id,
            'title': 'Updated title {}'.format(x.id),
            'step': x.step.slug,
            'project': x.project.id
        } for x in [todo1, todo3, todo2]]
        resp = self.request_client.patch(
            self.list_url,
            data=json.dumps(todos_with_updated_titles),
            content_type='application/json')
        self.assertEqual(resp.status_code, 200)

        updated_todos = Todo.objects.filter(
            id__in=[todo1.id, todo2.id, todo3.id])
        for todo in updated_todos:
            self.assertEqual(todo.title, 'Updated title {}'.format(todo.id))
        self.assertEqual(todo_should_not_be_updated.title, 'Not updated')
Exemplo n.º 2
0
    def test_next_todo_with_earlier_due_time(self):
        task = self.tasks['next_todo_task']
        # create todos with different due date times and one without
        TodoFactory(
            task=task,
            description='todo1',
            due_datetime=parse(DEADLINE2_DATETIME))

        TodoFactory(
            task=task,
            description='todo2')

        tasks_assigned = tasks_assigned_to_worker(self.workers[5])

        for t in tasks_assigned:
            if t['id'] == task.id:
                next_todo_due = t['next_todo_dict'].get('due_datetime', None)

                # should select the todo with a deadline
                self.assertEqual(next_todo_due, DEADLINE2_DATETIME)
                self.assertEqual(t['should_be_active'], True)

        TodoFactory(
            task=task,
            description='todo3',
            due_datetime=parse(DEADLINE1_DATETIME))

        tasks_assigned = tasks_assigned_to_worker(self.workers[5])
        for t in tasks_assigned:
            if t['id'] == task.id:
                next_todo_due = t['next_todo_dict'].get('due_datetime', None)

                # should select the todo with earliest deadline
                self.assertEqual(next_todo_due, DEADLINE1_DATETIME)
                self.assertEqual(t['should_be_active'], True)
Exemplo n.º 3
0
    def test_update_todos(self, mock_request):
        # This converts `requests.patch` into DRF's `APIClient.patch`
        # To make it testable
        def patch_func(url, *args, **kwargs):
            kw = kwargs.get('data', '')
            data = json.loads(kw)
            return_value = self.request_client.put(url, data, format='json')
            return_value.text = json.dumps(return_value.data)
            return return_value

        mock_request.patch = patch_func

        todo1 = TodoFactory(step=self.step, project=self.project)
        todo2 = TodoFactory(step=self.step, project=self.project)
        todo3 = TodoFactory(step=self.step, project=self.project)
        todo_should_not_be_updated = TodoFactory(project=self.project,
                                                 step=self.step,
                                                 title='Not updated')
        # Change titles
        todos_with_updated_titles = [{
            'id': x.id,
            'title': 'Updated title {}'.format(x.id),
            'step': x.step.slug,
            'project': x.project.id
        } for x in [todo1, todo3, todo2]]
        result = update_todos(todos_with_updated_titles)
        self.assertEqual(len(result), 3)
        updated_todos = Todo.objects.filter(
            id__in=[todo1.id, todo2.id, todo3.id])
        for todo in updated_todos:
            self.assertEqual(todo.title, 'Updated title {}'.format(todo.id))
        self.assertEqual(todo_should_not_be_updated.title, 'Not updated')
Exemplo n.º 4
0
    def test_next_todo_with_earlier_start_time(self, mock_timezone):
        mock_timezone.now = MagicMock(return_value=parse(
                                        MOCK_CURRENT))
        task = self.tasks['next_todo_task']
        task.step = self.step
        task.project = self.project
        task.save()
        # create todos with different due date times and one without
        TodoFactory(
            step=self.step,
            project=self.project,
            title='todo1',
            start_by_datetime=parse(DEADLINE2_DATETIME))

        TodoFactory(
            step=self.step,
            project=self.project,
            title='todo2',
            start_by_datetime=parse(DEADLINE1_DATETIME))

        tasks_assigned = tasks_assigned_to_worker(self.workers[5])
        for t in tasks_assigned:
            if t['id'] == task.id:
                next_todo_start = t['next_todo_dict'].get(
                    'start_by_datetime', None)
                # should select the todo with a deadline
                self.assertEqual(next_todo_start, DEADLINE1_DATETIME)
                self.assertEqual(t['should_be_active'], False)
Exemplo n.º 5
0
 def test_todo_details_and_permissions(self):
     # You should be able to update Todos for projects in which
     # you're involved, and not for other projects.
     good_todo = TodoFactory(project=self.project, step=self.step)
     self._verify_todo_update(good_todo, True)
     bad_todo = TodoFactory()
     self._verify_todo_update(bad_todo, False)
Exemplo n.º 6
0
 def setUp(self):
     super().setUp()
     self.request_client = APIClient(enforce_csrf_checks=True)
     self.request_client.force_authenticate(user=SignedUser())
     setup_models(self)
     self.workflow_version = WorkflowVersionFactory()
     self.step = StepFactory(slug='step-slug',
                             workflow_version=self.workflow_version)
     self.project = ProjectFactory(workflow_version=self.workflow_version)
     self.list_url = reverse('orchestra:api:todo-api-list')
     self.todo = TodoFactory(project=self.project)
     self.todo_with_step = TodoFactory(project=self.project, step=self.step)
Exemplo n.º 7
0
    def test_fields_updated(self):
        old_todo = TodoFactory(title=self.old_title, details=self.old_details)
        new_todo = TodoFactory(title=self.new_title, details=self.new_details)
        msg = get_update_message(old_todo, new_todo, self.sender)
        expected_msg = (
            '{} has updated `{}`: changed title and details').format(
                self.sender.username, new_todo.title)
        self.assertEqual(msg, expected_msg)

        # Only title has changed
        old_todo = TodoFactory(title=self.old_title, details=self.old_details)
        new_todo = TodoFactory(title=self.new_title, details=self.old_details)
        msg = get_update_message(old_todo, new_todo, self.sender)
        expected_msg = ('{} has updated `{}`: changed title').format(
            self.sender.username, new_todo.title)
        self.assertEqual(msg, expected_msg)
Exemplo n.º 8
0
 def test_fields_not_updated_completed(self):
     new_todo = TodoFactory(title=self.old_title,
                            details=self.old_details,
                            completed=True)
     msg = get_update_message(self.old_todo, new_todo, self.sender)
     expected_msg = '{} has updated `{}`: marked complete'.format(
         self.sender.username, new_todo.title)
     self.assertEqual(msg, expected_msg)
Exemplo n.º 9
0
    def test_get_todos(self, mock_request):
        # This converts `requests.get` into DRF's `APIClient.get`
        # To make it testable
        def get(url, *args, **kwargs):
            return_value = self.request_client.get(url, format='json')
            return_value.text = json.dumps(return_value.data)
            return return_value

        mock_request.get = get

        step_1 = StepFactory(slug='step_1')
        step_2 = StepFactory(slug='step_2')
        project2 = ProjectFactory()
        # 2 todos have the same project
        todo1 = TodoFactory(step=step_1, project=self.project)
        todo2 = TodoFactory(step=step_1, project=self.project)
        # 1 todo has another project
        todo3 = TodoFactory(step=step_2, project=project2)

        todo4 = TodoFactory(step=step_1, project=project2)

        # Get todo1 and todo2
        res = get_todos(self.project.id, step_1.slug)
        self.assertEqual(len(res), 2)
        expected_ids = [todo1.id, todo2.id]
        for r in res:
            self.assertIn(r['id'], expected_ids)

        # Get todo3
        res = get_todos(project2.id, step_2.slug)
        self.assertEqual(len(res), 1)
        self.assertEqual(res[0]['id'], todo3.id)

        # Filter by project_id
        res = get_todos(project_id=project2.id)
        self.assertEqual(len(res), 2)
        expected_ids = [todo3.id, todo4.id]
        for r in res:
            self.assertIn(r['id'], expected_ids)

        # Test project_id is required
        msg = 'project_id is required'
        with self.assertRaisesMessage(OrchestraError, msg):
            get_todos(None)
Exemplo n.º 10
0
 def setUp(self):
     super().setUp()
     project = ProjectFactory()
     step = StepFactory()
     self.old_title = 'Old title'
     self.new_title = 'New title'
     self.old_details = 'Old details'
     self.new_details = 'New details'
     self.old_todo = TodoFactory(title=self.old_title,
                                 details=self.old_details,
                                 completed=False,
                                 project=project,
                                 step=step)
     self.new_todo = TodoFactory(title=self.new_title,
                                 details=self.new_details,
                                 completed=True,
                                 project=project,
                                 step=step)
     self.sender = UserFactory()
Exemplo n.º 11
0
    def test_update_functionality(self, mock_notify):
        todo1 = TodoFactory(project=self.project,
                            step=self.step,
                            title='Test title1')
        todo2 = TodoFactory(project=self.project,
                            step=self.step,
                            title='Test title2')
        # Set title of the todo2 to todo1
        serialized = BulkTodoSerializer(todo2).data
        detail_url = reverse('orchestra:api:todo-api-detail',
                             kwargs={'pk': todo1.id})
        resp = self.request_client.put(detail_url,
                                       data=json.dumps(serialized),
                                       content_type='application/json')
        self.assertEqual(resp.status_code, 200)

        # Check if title is updated
        updated_todo_1 = Todo.objects.get(pk=todo1.pk)
        self.assertEqual(updated_todo_1.title, todo2.title)
Exemplo n.º 12
0
    def test_bulk_update(self):
        todo1 = TodoFactory(project=self.project,
                            step=self.step,
                            title='Test title1')
        todo2 = TodoFactory(project=self.project,
                            step=self.step,
                            title='Test title2')
        todo3 = TodoFactory(project=self.project,
                            step=self.step,
                            title='Test title3')
        todo_wo_project = TodoFactory(title='Test title3')
        todo_should_not_be_updated = TodoFactory(project=self.project,
                                                 step=self.step,
                                                 title='Not updated')
        serialized = BulkTodoSerializer([todo3, todo2, todo1], many=True).data
        # Change titles
        updated = [
            self._change_attr(x, 'title', 'updated title {}'.format(x['id']))
            for x in serialized
        ]
        resp = self.request_client.put(self.list_url,
                                       data=json.dumps(updated),
                                       content_type='application/json')
        self.assertEqual(resp.status_code, 200)

        updated_todos = Todo.objects.filter(
            id__in=[todo1.id, todo2.id, todo3.id])
        for todo in updated_todos:
            self.assertEqual(todo.title, 'updated title {}'.format(todo.id))
        self.assertEqual(todo_should_not_be_updated.title, 'Not updated')

        serialized = BulkTodoSerializer([todo_wo_project], many=True).data
        updated = [
            self._change_attr(x, 'title', 'updated title {}'.format(x['id']))
            for x in serialized
        ]
        resp = self.request_client.put(self.list_url,
                                       data=json.dumps(updated),
                                       content_type='application/json')
        self.assertEqual(resp.status_code, 400)
        self.assertEqual(resp.json()[0]['step'],
                         ['This field may not be null.'])
Exemplo n.º 13
0
    def test_create_todo_with_start_by_datetime(self):
        START_DESCRIPTION = 'Start soon'

        start_by_todo = TodoFactory(task=self.task,
                                    start_by_datetime=self.deadline,
                                    description=START_DESCRIPTION)

        self._verify_todos_list(self.task.project.id, [
            self._todo_data(start_by_todo.task, START_DESCRIPTION, False,
                            self.deadline.strftime('%Y-%m-%dT%H:%M:%SZ'), None)
        ], True)
Exemplo n.º 14
0
    def test_create_todo_with_due_datetime(self):
        DUE_DESCRIPTION = 'Due soon'

        due_todo = TodoFactory(task=self.task,
                               due_datetime=self.deadline,
                               description=DUE_DESCRIPTION)

        self._verify_todos_list(self.task.project.id, [
            self._todo_data(due_todo.task, DUE_DESCRIPTION, False, None,
                            self.deadline.strftime('%Y-%m-%dT%H:%M:%SZ')),
        ], True)
Exemplo n.º 15
0
    def test_worker_task_recent_todo_qas(self):
        todo_task_0 = TodoFactory(task=self.task_0)
        todo_task_1 = TodoFactory(task=self.task_1)

        # Zero TodoQAs
        self._verify_worker_task_recent_todo_qas(
            self.task_0, None, True)

        todo_qa_task_0 = TodoQAFactory(todo=todo_task_0, approved=False)

        # Most recent TodoQA is todo_qa_task_0
        self._verify_worker_task_recent_todo_qas(
            self.task_0, todo_qa_task_0, True)

        self._verify_worker_task_recent_todo_qas(
            self.task_1, todo_qa_task_0, True)

        todo_qa_task_1 = TodoQAFactory(todo=todo_task_1, approved=False)

        # If available use the todo qa for the corresponding task.
        self._verify_worker_task_recent_todo_qas(
            self.task_0, todo_qa_task_0, True)

        self._verify_worker_task_recent_todo_qas(
            self.task_1, todo_qa_task_1, True)

        todo_qa_task_0.delete()

        # Most recent TodoQA is todo_qa_task_1
        self._verify_worker_task_recent_todo_qas(
            self.task_0, todo_qa_task_1, True)

        self._verify_worker_task_recent_todo_qas(
            self.task_1, todo_qa_task_1, True)

        # Can't make requests for projects in which you're uninvolved.
        bad_task = TaskFactory()
        todo_bad_task = TodoFactory(task=bad_task)
        todo_qa_bad_task = TodoQAFactory(todo=todo_bad_task, approved=False)
        self._verify_worker_task_recent_todo_qas(
            bad_task, todo_qa_bad_task, False)
Exemplo n.º 16
0
    def test_delete_todos(self, mock_request):
        # This converts `requests.delete` into DRF's `APIClient.delete`
        # To make it testable
        def delete(url, *args, **kwargs):
            kw = kwargs.get('data', '')
            data = json.loads(kw)
            return_value = self.request_client.delete(url, data, format='json')
            return_value.text = json.dumps(return_value.data)
            return return_value

        mock_request.delete = delete

        todo1 = TodoFactory(step=self.step, project=self.project)
        todo2 = TodoFactory(step=self.step, project=self.project)
        todo3 = TodoFactory(step=self.step, project=self.project)
        todo4 = TodoFactory(step=self.step, project=self.project)

        res = delete_todos([todo1.id, todo2.id, todo3.id])
        self.assertEqual(res[0], 3)
        left_todos = Todo.objects.all()
        self.assertEqual(left_todos.count(), 1)
        self.assertEqual(left_todos[0].id, todo4.id)
Exemplo n.º 17
0
    def test_fields_not_updated_not_relevant(self):
        new_todo = TodoFactory(title=self.old_title,
                               details=self.old_details,
                               completed=False,
                               skipped_datetime=timezone.now())
        msg = get_update_message(self.old_todo, new_todo, self.sender)
        expected_msg = '{} has updated `{}`: marked not relevant'.format(
            self.sender.username, new_todo.title)
        self.assertEqual(msg, expected_msg)

        # No sender
        msg = get_update_message(self.old_todo, new_todo)
        expected_msg = '`{}` has been updated: marked not relevant'.format(
            new_todo.title)
        self.assertEqual(msg, expected_msg)
Exemplo n.º 18
0
 def setUp(self):
     super().setUp()
     setup_models(self)
     self.worker = Worker.objects.get(user__username='******')
     self.request_client.login(username=self.worker.user.username,
                               password='******')
     self.list_create_url = reverse('orchestra:todos:todo_qas')
     self.worker_task_recent_todo_qas_url = reverse(
         'orchestra:todos:worker_task_recent_todo_qas')
     self.list_details_url_name = 'orchestra:todos:todo_qa'
     self.tasks = Task.objects.filter(assignments__worker=self.worker)
     self.task_0 = self.tasks[0]
     self.task_1 = self.tasks[1]
     self.todo = TodoFactory(task=self.task_0)
     self.comment = 'Test comment'
Exemplo n.º 19
0
    def test_create_todo_with_due_datetime(self):
        DUE_TITLE = 'Due soon'

        due_todo = TodoFactory(project=self.project,
                               step=self.step,
                               due_datetime=self.deadline,
                               title=DUE_TITLE)

        self._verify_todos_list(due_todo.project.id, [
            _todo_data(DUE_TITLE,
                       False,
                       None,
                       None,
                       self.deadline.strftime('%Y-%m-%dT%H:%M:%SZ'),
                       project=due_todo.project.id,
                       step=due_todo.step.slug),
        ], True)
Exemplo n.º 20
0
    def test_create_todo_with_start_by_datetime(self):
        START_TITLE = 'Start soon'

        start_by_todo = TodoFactory(project=self.project,
                                    step=self.step,
                                    start_by_datetime=self.deadline,
                                    title=START_TITLE)

        self._verify_todos_list(start_by_todo.project.id, [
            _todo_data(START_TITLE,
                       False,
                       None,
                       self.deadline.strftime('%Y-%m-%dT%H:%M:%SZ'),
                       None,
                       project=start_by_todo.project.id,
                       step=start_by_todo.step.slug)
        ], True)
Exemplo n.º 21
0
    def test_dangerous_sql(self):
        project = ProjectFactory()
        TodoFactory(project=project)
        dangerous_sql = ("if ((select user) = 'sa'"
                         " OR (select user) = 'dbo') select 1 else select 1/0")
        url_params = build_url_params(
            project.id, None, **{'additional_data__sql': dangerous_sql})
        kwargs = self._get_qs_kwargs(GenericTodoViewset, url_params)
        # kwargs doesn't contain additional_data__sql field
        self.assertEqual(kwargs, {'project__id': str(project.id)})

        url_params = build_url_params(project.id, None,
                                      **{'title': dangerous_sql})
        kwargs = self._get_qs_kwargs(GenericTodoViewset, url_params)
        todos = Todo.objects.filter(**kwargs)
        self.assertEqual(kwargs, {
            'project__id': str(project.id),
            'title': dangerous_sql
        })
        self.assertTrue(todos.count, 0)
Exemplo n.º 22
0
 def setUp(self):
     super().setUp()
     setup_models(self)
     self.worker = Worker.objects.get(user__username='******')
     self.request_client.login(username=self.worker.user.username,
                               password='******')
     self.list_create_url = reverse('orchestra:todos:todo_qas')
     self.worker_task_recent_todo_qas_url = reverse(
         'orchestra:todos:worker_task_recent_todo_qas')
     self.list_details_url_name = 'orchestra:todos:todo_qa'
     self.project0 = ProjectFactory()
     self.project1 = ProjectFactory()
     self.step = StepFactory(slug='some-slug')
     tasks = Task.objects.filter(assignments__worker=self.worker)
     self.task_0 = tasks[0]
     self.task_0.project = self.project0
     self.task_0.step = self.step
     self.task_0.save()
     self.task_1 = tasks[1]
     self.task_1.project = self.project1
     self.task_1.step = self.step
     self.task_1.save()
     self.todo = TodoFactory(project=self.project0, step=self.step)
     self.comment = 'Test comment'
Exemplo n.º 23
0
 def test_todo_qas_create_permissions(self):
     # Can't make requests for projects in which you're uninvolved.
     project = ProjectFactory()
     step = StepFactory()
     todo = TodoFactory(project=project, step=step)
     self._verify_todo_qa_creation(todo, False)
Exemplo n.º 24
0
 def test_todo_deletion(self):
     todo = TodoFactory(project=self.project, step=self.step)
     deletion_url = reverse(self.list_details_url_name,
                            kwargs={'pk': todo.id})
     resp = self.request_client.delete(deletion_url)
     self.assertEqual(resp.status_code, 204)