Example #1
0
    def test_create_with_bad_data(self):
        """
        Test that we get appropriate errors when trying to create a project
        with bad data
        """
        bob_user = mommy.make("auth.User")
        alice_user = mommy.make("auth.User")
        mocked_target_object = mommy.make("tasking.Task")

        # test bad target_id validation
        bad_target_id = {
            "name": "Livestock prices",
            "target_content_type": self.task_type.id,
            "target_id": 1337,
        }

        view1 = ProjectViewSet.as_view({"post": "create"})
        request1 = self.factory.post("/projects", bad_target_id)
        # Need authenticated user
        force_authenticate(request1, user=bob_user)
        response1 = view1(request=request1)

        self.assertEqual(response1.status_code, 400)

        self.assertIn("target_id", response1.data.keys())
        self.assertEqual(TARGET_DOES_NOT_EXIST,
                         str(response1.data["target_id"][0]))

        # test bad content type validation
        bad_content_type = {
            "name": "Half Life Three",
            "target_content_type": 999,
            "target_id": mocked_target_object.id,
        }

        view2 = ProjectViewSet.as_view({"post": "create"})
        request2 = self.factory.post("/projects", bad_content_type)
        # Need authenticated user
        force_authenticate(request2, user=alice_user)
        response2 = view2(request=request2)

        self.assertEqual(response2.status_code, 400)

        self.assertIn("target_content_type", response2.data.keys())
        self.assertEqual(
            'Invalid pk "999" - object does not exist.',
            str(response2.data["target_content_type"][0]),
        )
Example #2
0
    def _create_project(self):
        """
        Helper to create a single project
        """
        mocked_target_object = mommy.make('tasking.Task')

        task1 = mommy.make('tasking.Task')
        task2 = mommy.make('tasking.Task')

        user = mommy.make('auth.User')

        data = {
            'name': "Livestock prices",
            'target_content_type': self.task_type.id,
            'target_id': mocked_target_object.id,
        }

        data_with_projects = data.copy()
        data_with_projects['tasks'] = [task1.id, task2.id]

        view = ProjectViewSet.as_view({'post': 'create'})
        request = self.factory.post('/projects', data_with_projects)
        # Need authenticated user
        force_authenticate(request, user=user)
        response = view(request=request)

        # we test that we do have our tasks
        self.assertEqual(set([task1.id, task2.id]),
                         set(response.data['tasks']))
        self.assertEqual(response.status_code, 201, response.data)
        # the order of tasks may have changed so a dict comparison
        # may fail, we use `data` that does not include tasks
        self.assertDictContainsSubset(data, response.data)
        return response.data
Example #3
0
    def test_task_filter(self):
        """
        Test that you can filter by task
        """
        user = mommy.make("auth.User")
        project1 = mommy.make("tasking.Project", name="StarLord")
        project2 = mommy.make("tasking.Project", name="Local income")
        task1 = mommy.make("tasking.Task", name="Groot")
        for _ in range(0, 7):
            task = mommy.make("tasking.Task", name="Normal")
            project2.tasks.add(task)

        view = ProjectViewSet.as_view({"get": "list"})

        # assert that there are no projects with Groot task
        request = self.factory.get("/projects?", {"tasks": task1.id})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 0)
        # pylint: disable=no-member
        self.assertEqual(Project.objects.filter(tasks=task1).count(), 0)

        # add Groot task to project1 and assert its there
        project1.tasks.add(task1)

        request = self.factory.get("/projects", {"tasks": task1.id})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 1)
        self.assertEqual(response.data[0]["name"], project1.name)
        self.assertEqual(Project.objects.filter(tasks=task1).count(), 1)
Example #4
0
    def test_project_sorting(self):
        """
        Test that sorting works
        """
        user = mommy.make("auth.User")
        project1 = mommy.make("tasking.Project", name="Argicultural")
        project2 = mommy.make("tasking.Project", name="Racer")

        view = ProjectViewSet.as_view({"get": "list"})

        # order by name descending
        request = self.factory.get("/projects", {"ordering": "-name"})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.data[0]["name"], project2.name)
        self.assertEqual(response.data[0]["id"], project2.id)
        self.assertEqual(response.data[-1]["name"], project1.name)
        self.assertEqual(response.data[-1]["id"], project1.id)

        # order by created ascending
        request = self.factory.get("/projects", {"ordering": "created"})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(
            response.data[0]["created"],
            project1.created.astimezone(
                pytz.timezone("Africa/Nairobi")).isoformat(),
        )
        self.assertEqual(response.data[0]["id"], project1.id)
        self.assertEqual(
            response.data[-1]["created"],
            project2.created.astimezone(
                pytz.timezone("Africa/Nairobi")).isoformat(),
        )
        self.assertEqual(response.data[-1]["id"], project2.id)
Example #5
0
    def test_project_sorting(self):
        """
        Test that sorting works
        """
        user = mommy.make('auth.User')
        project1 = mommy.make('tasking.Project', name='Argicultural')
        project2 = mommy.make('tasking.Project', name='Racer')

        view = ProjectViewSet.as_view({'get': 'list'})

        # order by name descending
        request = self.factory.get('/projects', {'ordering': '-name'})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.data[0]['name'], project2.name)
        self.assertEqual(response.data[0]['id'], project2.id)
        self.assertEqual(response.data[-1]['name'], project1.name)
        self.assertEqual(response.data[-1]['id'], project1.id)

        # order by created ascending
        request = self.factory.get('/projects', {'ordering': 'created'})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(
            response.data[0]['created'],
            project1.created.astimezone(
                pytz.timezone('Africa/Nairobi')).isoformat())
        self.assertEqual(response.data[0]['id'], project1.id)
        self.assertEqual(
            response.data[-1]['created'],
            project2.created.astimezone(
                pytz.timezone('Africa/Nairobi')).isoformat())
        self.assertEqual(response.data[-1]['id'], project2.id)
Example #6
0
    def test_task_filter(self):
        """
        Test that you can filter by task
        """
        user = mommy.make('auth.User')
        project1 = mommy.make('tasking.Project', name='StarLord')
        project2 = mommy.make('tasking.Project', name='Local income')
        task1 = mommy.make('tasking.Task', name='Groot')
        for _ in range(0, 7):
            task = mommy.make('tasking.Task', name='Normal')
            project2.tasks.add(task)

        view = ProjectViewSet.as_view({'get': 'list'})

        # assert that there are no projects with Groot task
        request = self.factory.get('/projects?', {'tasks': task1.id})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 0)
        # pylint: disable=no-member
        self.assertEqual(Project.objects.filter(tasks=task1).count(), 0)

        # add Groot task to project1 and assert its there
        project1.tasks.add(task1)

        request = self.factory.get('/projects', {'tasks': task1.id})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 1)
        self.assertEqual(response.data[0]['name'], project1.name)
        self.assertEqual(Project.objects.filter(tasks=task1).count(), 1)
Example #7
0
    def test_create_with_bad_data(self):
        """
        Test that we get appropriate errors when trying to create a project
        with bad data
        """
        bob_user = mommy.make('auth.User')
        alice_user = mommy.make('auth.User')
        mocked_target_object = mommy.make('tasking.Task')

        # test bad target_id validation
        bad_target_id = {
            'name': "Livestock prices",
            'target_content_type': self.task_type.id,
            'target_id': 1337,
        }

        view1 = ProjectViewSet.as_view({'post': 'create'})
        request1 = self.factory.post('/projects', bad_target_id)
        # Need authenticated user
        force_authenticate(request1, user=bob_user)
        response1 = view1(request=request1)

        self.assertEqual(response1.status_code, 400)

        self.assertIn('target_id', response1.data.keys())
        self.assertEqual(TARGET_DOES_NOT_EXIST,
                         six.text_type(response1.data['target_id'][0]))

        # test bad content type validation
        bad_content_type = {
            'name': "Half Life Three",
            'target_content_type': 999,
            'target_id': mocked_target_object.id,
        }

        view2 = ProjectViewSet.as_view({'post': 'create'})
        request2 = self.factory.post('/projects', bad_content_type)
        # Need authenticated user
        force_authenticate(request2, user=alice_user)
        response2 = view2(request=request2)

        self.assertEqual(response2.status_code, 400)

        self.assertIn('target_content_type', response2.data.keys())
        self.assertEqual(
            'Invalid pk "999" - object does not exist.',
            six.text_type(response2.data['target_content_type'][0]))
Example #8
0
    def test_update_project(self):
        """
        Test UPDATE project
        """
        user = mommy.make("auth.User")
        user2 = mommy.make("auth.User")
        project_data = self._create_project()
        project_id = project_data["id"]
        project_data2 = self._create_project()
        project2_id = project_data2["id"]

        data = {
            "name": "project 36",
            "target_content_type": self.user_type.id,
            "target_id": user.id,
        }

        view = ProjectViewSet.as_view({"patch": "partial_update"})
        request = self.factory.patch(f"/projects/{project_id}", data=data)
        force_authenticate(request, user=user)
        response = view(request=request, pk=project_id)

        self.assertEqual(response.status_code, 200)
        self.assertEqual("project 36", response.data["name"])
        self.assertEqual(self.user_type.id,
                         response.data["target_content_type"])
        self.assertEqual(user.id, response.data["target_id"])

        some_task = mommy.make("tasking.task")

        data2 = {"name": "Mission 99", "tasks": [some_task.id]}

        view2 = ProjectViewSet.as_view({"patch": "partial_update"})
        request2 = self.factory.patch(f"/projects/{project2_id}", data=data2)
        force_authenticate(request2, user=user2)
        response2 = view2(request=request2, pk=project2_id)

        self.assertEqual(response2.status_code, 200)
        self.assertEqual("Mission 99", response2.data["name"])
        self.assertEqual([some_task.id], response2.data["tasks"])
Example #9
0
    def test_update_project(self):
        """
        Test UPDATE project
        """
        user = mommy.make('auth.User')
        user2 = mommy.make('auth.User')
        project_data = self._create_project()
        project_data2 = self._create_project()

        data = {
            'name': "project 36",
            'target_content_type': self.user_type.id,
            'target_id': user.id,
        }

        view = ProjectViewSet.as_view({'patch': 'partial_update'})
        request = self.factory.patch(
            '/projects/{id}'.format(id=project_data['id']), data=data)
        force_authenticate(request, user=user)
        response = view(request=request, pk=project_data['id'])

        self.assertEqual(response.status_code, 200)
        self.assertEqual('project 36', response.data['name'])
        self.assertEqual(self.user_type.id,
                         response.data['target_content_type'])
        self.assertEqual(user.id, response.data['target_id'])

        some_task = mommy.make('tasking.task')

        data2 = {'name': "Mission 99", 'tasks': [some_task.id]}

        view2 = ProjectViewSet.as_view({'patch': 'partial_update'})
        request2 = self.factory.patch(
            '/projects/{id}'.format(id=project_data2['id']), data=data2)
        force_authenticate(request2, user=user2)
        response2 = view2(request=request2, pk=project_data2['id'])

        self.assertEqual(response2.status_code, 200)
        self.assertEqual('Mission 99', response2.data['name'])
        self.assertEqual([some_task.id], response2.data['tasks'])
Example #10
0
    def test_list_projects(self):
        """
        Test GET /projects listing of projects
        """
        user = mommy.make('auth.User')
        project_data = self._create_project()
        view = ProjectViewSet.as_view({'get': 'list'})

        request = self.factory.get('/projects')
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.data.pop(), project_data)
Example #11
0
 def test_retrieve_project(self):
     """
     Test GET /projects/[pk] return a project matching pk.
     """
     user = mommy.make('auth.User')
     project_data = self._create_project()
     view = ProjectViewSet.as_view({'get': 'retrieve'})
     request = self.factory.get(
         '/projects/{id}'.format(id=project_data['id']))
     force_authenticate(request, user=user)
     response = view(request=request, pk=project_data['id'])
     self.assertEqual(response.status_code, 200)
     self.assertDictEqual(response.data, project_data)
Example #12
0
    def test_retrieve_project(self):
        """
        Test GET /projects/[pk] return a project matching pk.
        """
        user = mommy.make("auth.User")
        project_data = self._create_project()
        project_id = project_data["id"]

        view = ProjectViewSet.as_view({"get": "retrieve"})
        request = self.factory.get(f"/projects/{project_id}")
        force_authenticate(request, user=user)
        response = view(request=request, pk=project_id)
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.data, project_data)
Example #13
0
    def test_name_search(self):
        """
        Test that you can search by Name
        """
        user = mommy.make("auth.User")
        mommy.make("tasking.Project", name="Golden Goose")
        mommy.make("tasking.Project", name="Cattle", _quantity=7)

        view = ProjectViewSet.as_view({"get": "list"})
        request = self.factory.get("/projects", {"search": "Golden Goose"})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 1)
        # pylint: disable=no-member
        self.assertEqual(
            Project.objects.filter(name="Golden Goose").count(), 1)
Example #14
0
    def test_name_search(self):
        """
        Test that you can search by Name
        """
        user = mommy.make('auth.User')
        mommy.make('tasking.Project', name='Golden Goose')
        mommy.make('tasking.Project', name='Cattle', _quantity=7)

        view = ProjectViewSet.as_view({'get': 'list'})
        request = self.factory.get('/projects', {'search': 'Golden Goose'})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 1)
        # pylint: disable=no-member
        self.assertEqual(
            Project.objects.filter(name='Golden Goose').count(), 1)
Example #15
0
    def test_delete_project(self):
        """
        Test DELETE project.
        """
        user = mommy.make('auth.User')
        project = mommy.make('tasking.Project')

        # assert that project exists
        # pylint: disable=no-member
        self.assertTrue(Project.objects.filter(pk=project.id).exists())
        # delete project
        view = ProjectViewSet.as_view({'delete': 'destroy'})
        request = self.factory.delete('/projects/{id}'.format(id=project.id))
        force_authenticate(request, user=user)
        response = view(request=request, pk=project.id)
        # assert that task was deleted
        self.assertEqual(response.status_code, 204)
        self.assertFalse(Project.objects.filter(pk=project.id).exists())
Example #16
0
    def test_authentication_required(self):
        """
        Test that authentication is required for all viewset actions
        """
        mocked_target_object = mommy.make("tasking.Task")
        project_data = self._create_project()
        project_id = project_data["id"]
        project = mommy.make("tasking.Project")
        user = mommy.make("auth.User")

        # test that you need authentication for creating a project
        good_data = {
            "name": "Livestock prices",
            "target_content_type": self.task_type.id,
            "target_id": mocked_target_object.id,
        }
        view = ProjectViewSet.as_view({"post": "create"})
        request = self.factory.post("/projects", good_data)
        response = view(request=request)
        self.assertEqual(response.status_code, 403)
        self.assertEqual(
            "Authentication credentials were not provided.",
            str(response.data["detail"]),
        )

        # test that you need authentication for retrieving a project
        view2 = ProjectViewSet.as_view({"get": "retrieve"})
        request2 = self.factory.get(f"/projects/{project_id}")
        response2 = view2(request=request2, pk=project_id)
        self.assertEqual(response2.status_code, 403)
        self.assertEqual(
            "Authentication credentials were not provided.",
            str(response2.data["detail"]),
        )

        # test that you need authentication for listing projects
        view3 = ProjectViewSet.as_view({"get": "list"})
        request3 = self.factory.get("/projects")
        response3 = view3(request=request3)
        self.assertEqual(response3.status_code, 403)
        self.assertEqual(
            "Authentication credentials were not provided.",
            str(response3.data["detail"]),
        )

        # test that you need authentication for deleting a project
        # pylint: disable=no-member
        self.assertTrue(Project.objects.filter(pk=project.id).exists())

        view4 = ProjectViewSet.as_view({"delete": "destroy"})
        request4 = self.factory.delete(f"/projects/{project.id}")
        response4 = view4(request=request4, pk=project.id)

        self.assertEqual(response4.status_code, 403)
        self.assertEqual(
            "Authentication credentials were not provided.",
            str(response4.data["detail"]),
        )

        # test that you need authentication for updating a project
        data = {
            "name": "Milk Price",
            "target_content_type": self.user_type.id,
            "target_id": user.id,
        }

        view5 = ProjectViewSet.as_view({"patch": "partial_update"})
        request5 = self.factory.patch(f"/projects/{project_id}", data=data)
        response5 = view5(request=request5, pk=project_id)

        self.assertEqual(response5.status_code, 403)
        self.assertEqual(
            "Authentication credentials were not provided.",
            str(response5.data["detail"]),
        )
Example #17
0
    def test_authentication_required(self):
        """
        Test that authentication is required for all viewset actions
        """
        mocked_target_object = mommy.make('tasking.Task')
        project_data = self._create_project()
        project = mommy.make('tasking.Project')
        user = mommy.make('auth.User')

        # test that you need authentication for creating a project
        good_data = {
            'name': "Livestock prices",
            'target_content_type': self.task_type.id,
            'target_id': mocked_target_object.id,
        }
        view = ProjectViewSet.as_view({'post': 'create'})
        request = self.factory.post('/projects', good_data)
        response = view(request=request)
        self.assertEqual(response.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         six.text_type(response.data['detail']))

        # test that you need authentication for retrieving a project
        view2 = ProjectViewSet.as_view({'get': 'retrieve'})
        request2 = self.factory.get(
            '/projects/{id}'.format(id=project_data['id']))
        response2 = view2(request=request2, pk=project_data['id'])
        self.assertEqual(response2.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         six.text_type(response2.data['detail']))

        # test that you need authentication for listing projects
        view3 = ProjectViewSet.as_view({'get': 'list'})
        request3 = self.factory.get('/projects')
        response3 = view3(request=request3)
        self.assertEqual(response3.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         six.text_type(response3.data['detail']))

        # test that you need authentication for deleting a project
        # pylint: disable=no-member
        self.assertTrue(Project.objects.filter(pk=project.id).exists())

        view4 = ProjectViewSet.as_view({'delete': 'destroy'})
        request4 = self.factory.delete('/projects/{id}'.format(id=project.id))
        response4 = view4(request=request4, pk=project.id)

        self.assertEqual(response4.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         six.text_type(response4.data['detail']))

        # test that you need authentication for updating a project
        data = {
            'name': "Milk Price",
            'target_content_type': self.user_type.id,
            'target_id': user.id,
        }

        view5 = ProjectViewSet.as_view({'patch': 'partial_update'})
        request5 = self.factory.patch(
            '/projects/{id}'.format(id=project_data['id']), data=data)
        response5 = view5(request=request5, pk=project_data['id'])

        self.assertEqual(response5.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         six.text_type(response5.data['detail']))