Пример #1
0
    def test_national_id(self):
        """
        Ensure the national ID field is updated correctly
        """
        user_data = self._create()
        user = create_admin_user()

        with requests_mock.Mocker() as mocked:
            mocked.patch(
                urljoin(settings.ONA_BASE_URL,
                        f'api/v1/profiles/{user_data["ona_username"]}'),
                json=self.ona_json,
                status_code=200,
            )

            mocked.put(urljoin(settings.ONA_BASE_URL,
                               f'api/v1/orgs/{settings.ONA_ORG_NAME}/members'),
                       status_code=200)

            data = {
                'first_name': 'Bob',
                'national_id': '987654321',
            }

            view = UserProfileViewSet.as_view({'patch': 'partial_update'})
            request = self.factory.patch(f'/userprofiles/{user_data["id"]}',
                                         data=data)
            force_authenticate(request, user=user)
            response = view(request=request, pk=user_data['id'])
            self.assertEqual(response.status_code, 200)
            self.assertEqual("987654321", response.data['national_id'])
Пример #2
0
    def test_update(self):
        """
        Test that you can update userprofiles
        """
        user_data = self._create()
        user = create_admin_user()

        with requests_mock.Mocker() as mocked:
            mocked.patch(
                urljoin(settings.ONA_BASE_URL,
                        f'api/v1/profiles/{user_data["ona_username"]}'),
                json=self.ona_json,
                status_code=200,
            )

            mocked.put(urljoin(settings.ONA_BASE_URL,
                               f'api/v1/orgs/{settings.ONA_ORG_NAME}/members'),
                       status_code=200)

            data = {
                'first_name': 'Peter',
                'phone_number': '+254722111111',
                'role': UserProfile.CONTRIBUTOR
            }

            view = UserProfileViewSet.as_view({'patch': 'partial_update'})
            request = self.factory.patch(f'/userprofiles/{user_data["id"]}',
                                         data=data)
            force_authenticate(request, user=user)
            response = view(request=request, pk=user_data['id'])
            self.assertEqual(response.status_code, 200)
            self.assertEqual('Peter', response.data['first_name'])
            self.assertEqual('+254722111111', response.data['phone_number'])
            self.assertEqual(UserProfile.CONTRIBUTOR, response.data['role'])
Пример #3
0
    def test_list_ordering(self):
        """
        test that you can get and order a list of userprofiles
        """

        user = create_admin_user()  # ADMIN & EXPERT & First name == 'Ona'
        ben = mommy.make('auth.User', first_name='ben')
        mosh = mommy.make('auth.User', first_name='mosh')
        kyle = mommy.make('auth.User', first_name='kyle')

        mommy.make('main.Submission', user=ben, _quantity=7)
        mommy.make('main.Submission', user=kyle, _quantity=9)
        mommy.make('main.Submission', user=mosh, _quantity=17)

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

        # sort by submission count
        request1 = self.factory.get('/userprofiles',
                                    {'ordering': '-submission_count'})
        force_authenticate(request=request1, user=user)
        response1 = view(request=request1)
        self.assertEqual(response1.status_code, 200)
        self.assertEqual('mosh', response1.data['results'][0]['first_name'])
        self.assertEqual('kyle', response1.data['results'][1]['first_name'])
        self.assertEqual('ben', response1.data['results'][2]['first_name'])

        # sort by first_name
        request1 = self.factory.get('/userprofiles',
                                    {'ordering': 'user__first_name'})
        force_authenticate(request=request1, user=user)
        response1 = view(request=request1)
        self.assertEqual(response1.status_code, 200)
        self.assertEqual('ben', response1.data['results'][0]['first_name'])
        self.assertEqual('kyle', response1.data['results'][1]['first_name'])
        self.assertEqual('mosh', response1.data['results'][2]['first_name'])
Пример #4
0
    def test_list_searching(self):
        """
        test that you can get and search a list of userprofiles
        """
        user = create_admin_user()  # ADMIN & EXPERT
        ben = mommy.make('auth.User', first_name='ben')
        ben.userprofile.national_id = 123456
        ben.userprofile.save()

        alice = mommy.make('auth.User', first_name='alice')
        alice.userprofile.national_id = 89768
        alice.userprofile.save()

        joe = mommy.make('auth.User', first_name='joe')
        joe.userprofile.national_id = 1337
        joe.userprofile.save()

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

        # search by national_id
        request = self.factory.get('/userprofiles', {'search': 1337})
        force_authenticate(request=request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(1, len(response.data['results']))
        self.assertEqual('joe', response.data['results'][0]['first_name'])

        # search by last name
        request2 = self.factory.get('/userprofiles', {'search': 'alice'})
        force_authenticate(request=request2, user=user)
        response2 = view(request=request2)
        self.assertEqual(response2.status_code, 200)
        self.assertEqual(1, len(response2.data['results']))
        self.assertEqual('alice', response2.data['results'][0]['first_name'])
Пример #5
0
    def test_gender_and_gender_display(self):
        """
        Ensure gender and gender dispaly fields are updated correctly
        """
        user_data = self._create()
        user = create_admin_user()

        with requests_mock.Mocker() as mocked:
            mocked.patch(
                urljoin(settings.ONA_BASE_URL,
                        f'api/v1/profiles/{user_data["ona_username"]}'),
                json=self.ona_json,
                status_code=200,
            )

            mocked.put(urljoin(settings.ONA_BASE_URL,
                               f'api/v1/orgs/{settings.ONA_ORG_NAME}/members'),
                       status_code=200)

            data = {
                'first_name': 'Bob',
                'gender': UserProfile.OTHER,
            }

            view = UserProfileViewSet.as_view({'patch': 'partial_update'})
            request = self.factory.patch(f'/userprofiles/{user_data["id"]}',
                                         data=data)
            force_authenticate(request, user=user)
            response = view(request=request, pk=user_data['id'])
            self.assertEqual(response.status_code, 200)
            self.assertEqual(UserProfile.OTHER, response.data['gender'])
            self.assertEqual("Other", response.data["gender_display"])

            data = {
                'first_name': 'Bob',
                'gender': UserProfile.MALE,
            }

            view = UserProfileViewSet.as_view({'patch': 'partial_update'})
            request = self.factory.patch(f'/userprofiles/{user_data["id"]}',
                                         data=data)
            force_authenticate(request, user=user)
            response = view(request=request, pk=user_data['id'])
            self.assertEqual(response.status_code, 200)
            self.assertEqual(UserProfile.MALE, response.data["gender"])
            self.assertEqual("Male", response.data["gender_display"])
Пример #6
0
    def _create(self):
        """
        Helper to create userprofiles with viewset
        """
        with requests_mock.Mocker() as mocked:
            mocked.post(urljoin(settings.ONA_BASE_URL, 'api/v1/profiles'),
                        status_code=201,
                        json=self.ona_json)

            mocked.post(urljoin(
                settings.ONA_BASE_URL,
                f'api/v1/teams/{settings.ONA_MEMBERS_TEAM_ID}/members'),
                        status_code=201)

            mocked.put(urljoin(settings.ONA_BASE_URL,
                               f'api/v1/orgs/{settings.ONA_ORG_NAME}/members'),
                       status_code=200)

            user = create_admin_user()

            data = {
                'first_name': 'Bob',
                'last_name': 'Doe',
                'email': '*****@*****.**',
                'password': '******',
                'gender': UserProfile.MALE,
                'role': UserProfile.ADMIN,
                'expertise': UserProfile.EXPERT,
                'national_id': '123456789',
                'payment_number': '+254722222222',
                'phone_number': '+254722222222',
                'ona_pk': 1337,
                'ona_username': '******'
            }

            view = UserProfileViewSet.as_view({'post': 'create'})
            request = self.factory.post('/userprofiles', data)
            # need to authenticate
            force_authenticate(request, user=user)
            response = view(request=request)

            # assert that we get the right status_code and data back
            self.assertEqual(response.status_code, 201)

            # We remove password field since password is write-only
            data.pop('password')

            self.assertDictContainsSubset(data, response.data)

            return response.data
Пример #7
0
    def test_list(self):
        """
        test that you can get a list of userprofiles
        """
        user = create_admin_user()
        mommy.make('auth.User', _quantity=6)

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

        request = self.factory.get('/userprofiles')
        force_authenticate(request=request, user=user)

        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(7, len(response.data['results']))
Пример #8
0
    def test_profile(self):
        """
        Test that the profile endpoint returns authenticated
        users profile
        """
        user = create_admin_user()

        view = UserProfileViewSet.as_view({'get': 'profile'})

        request = self.factory.get('/userprofiles/profile')
        force_authenticate(request=request, user=user)

        response = view(request=request)

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['id'], user.userprofile.id)
Пример #9
0
    def test_retrieve(self):
        """
        Test that you can retrieve a userprofile object
        """
        user = create_admin_user()
        bob_user = mommy.make('auth.User', first_name='bob')
        bob_userprofile = bob_user.userprofile

        view = UserProfileViewSet.as_view({'get': 'retrieve'})

        request = self.factory.get(f'/userprofiles/{bob_userprofile.id}')
        force_authenticate(request=request, user=user)

        response = view(request=request, pk=bob_userprofile.id)

        self.assertEqual(response.status_code, 200)
        self.assertEqual('bob', response.data['first_name'])
        self.assertEqual(bob_userprofile.id, response.data['id'])
Пример #10
0
    def test_delete(self):
        """
        test that you can delete userprofiles
        """
        user = create_admin_user()
        bob_user = mommy.make('auth.User', first_name='bob')
        bob_userprofile = bob_user.userprofile

        view = UserProfileViewSet.as_view({'delete': 'destroy'})

        request = self.factory.delete(f'/userprofiles/{bob_userprofile.id}')
        force_authenticate(request=request, user=user)

        response = view(request=request, pk=bob_userprofile.id)

        self.assertEqual(response.status_code, 204)
        # pylint: disable=no-member
        self.assertFalse(
            UserProfile.objects.filter(id=bob_userprofile.id).exists())
Пример #11
0
    def test_avg_submissions(self):
        """
        Ensure that a request for avg_submissions returns the correct value
        """
        user = create_admin_user()
        bob_user = mommy.make('auth.User', first_name='bob')
        bob_userprofile = bob_user.userprofile

        generate_submissions(bob_userprofile, Submission.APPROVED)

        view = UserProfileViewSet.as_view({'get': 'retrieve'})

        request = self.factory.get(f'/userprofiles/{bob_userprofile.id}')
        force_authenticate(request=request, user=user)

        response = view(request=request, pk=bob_userprofile.id)

        self.assertEqual(response.status_code, 200)
        self.assertEqual(str(bob_userprofile.avg_submissions),
                         str(response.data["avg_submissions"]))
Пример #12
0
    def test_avg_amount_earned(self):
        """
        Ensure that a request for rejected submmissions returns correct value
        """
        user = create_admin_user()
        bob_user = mommy.make('auth.User', first_name='bob')
        bob_userprofile = bob_user.userprofile

        generate_submissions(bob_userprofile, Submission.APPROVED)

        view = UserProfileViewSet.as_view({'get': 'retrieve'})

        request = self.factory.get(f'/userprofiles/{bob_userprofile.id}')
        force_authenticate(request=request, user=user)

        response = view(request=request, pk=bob_userprofile.id)

        self.assertEqual(response.status_code, 200)
        space_index = response.data['avg_amount_earned'].index(' ')
        response_avg = response.data['avg_amount_earned'][:space_index]
        self.assertEqual(str(bob_userprofile.avg_amount_earned), response_avg)
Пример #13
0
    def test_permissions_required(self):
        """
        Test that a user must be an Admin to perform any Create, Delete
        or Update request
        """
        # cant create
        with requests_mock.Mocker() as mocked:
            data = {
                'first_name': 'Bob',
                'last_name': 'Doe',
                'email': '*****@*****.**',
                'gender': UserProfile.MALE,
                'role': UserProfile.ADMIN,
                'expertise': UserProfile.EXPERT,
                'national_id': '123456789',
                'payment_number': '+254722222222',
                'phone_number': '+254722222222',
                'ona_pk': 1337,
                'ona_username': '******'
            }

            mocked_user = mommy.make('auth.User')
            mocked_user2 = mommy.make('auth.User')
            userprofile = mocked_user2.userprofile

            view = UserProfileViewSet.as_view({'post': 'create'})
            request = self.factory.post('/userprofiles', data)
            force_authenticate(request, mocked_user)
            response = view(request=request)
            self.assertEqual(response.status_code, 403)
            self.assertEqual('You shall not pass.', response.data[0]['detail'])

            # cant update userprofile if Requester is not the User linked to it
            data = {
                'first_name': 'Peter',
                'phone_number': '+254722111111',
                'role': UserProfile.CONTRIBUTOR
            }

            mocked.patch(urljoin(
                settings.ONA_BASE_URL,
                f'api/v1/profiles/{userprofile.user.username}'),
                         status_code=200,
                         json=self.ona_json)

            view = UserProfileViewSet.as_view({'patch': 'partial_update'})
            request = self.factory.patch(f'/userprofiles/{userprofile.id}',
                                         data=data)
            force_authenticate(request, mocked_user)
            response = view(request=request, pk=userprofile.id)
            self.assertEqual(response.status_code, 403)
            self.assertEqual('You shall not pass.', response.data[0]['detail'])

            # cant delete
            view = UserProfileViewSet.as_view({'delete': 'destroy'})
            request = self.factory.delete(f'/userprofiles/{userprofile.id}')
            force_authenticate(request, mocked_user)
            response = view(request=request, pk=userprofile.id)
            self.assertEqual(response.status_code, 403)
            self.assertEqual('You shall not pass.', response.data[0]['detail'])

            # Cant delete own userprofile
            view = UserProfileViewSet.as_view({'delete': 'destroy'})
            request = self.factory.delete(f'/userprofiles/{userprofile.id}')
            force_authenticate(request, mocked_user2)
            response = view(request=request, pk=userprofile.id)
            self.assertEqual(response.status_code, 403)
            self.assertEqual('You shall not pass.', response.data[0]['detail'])

            # Can update userprofile if Requester is the User linked to it
            data = {
                'first_name': 'Peter',
                'phone_number': '+254722111111',
                'role': UserProfile.CONTRIBUTOR
            }
            view = UserProfileViewSet.as_view({'patch': 'partial_update'})
            request = self.factory.patch(f'/userprofiles/{userprofile.id}',
                                         data=data)
            force_authenticate(request, mocked_user2)
            response = view(request=request, pk=userprofile.id)
            self.assertEqual(response.status_code, 200)
            self.assertEqual('Peter', response.data['first_name'])
            self.assertEqual('+254722111111', response.data['phone_number'])
            self.assertEqual(UserProfile.CONTRIBUTOR, response.data['role'])
Пример #14
0
    def test_authentication_required(self):
        """
        Test that authentication is required for all endpoints
        """
        # cant create
        data = {
            'first_name': 'Bob',
            'last_name': 'Doe',
            'email': '*****@*****.**',
            'gender': UserProfile.MALE,
            'role': UserProfile.ADMIN,
            'expertise': UserProfile.EXPERT,
            'national_id': '123456789',
            'payment_number': '+254722222222',
            'phone_number': '+254722222222',
            'ona_pk': 1337,
            'ona_username': '******'
        }

        view = UserProfileViewSet.as_view({'post': 'create'})
        request = self.factory.post('/userprofiles', data)
        response = view(request=request)
        self.assertEqual(response.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         response.data[0]['detail'])

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

        # cant retrieve
        view = UserProfileViewSet.as_view({'get': 'retrieve'})
        request = self.factory.get(f'/userprofiles/{userprofile.id}')
        response = view(request=request, pk=userprofile.id)
        self.assertEqual(response.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         response.data[0]['detail'])

        # cant list
        view = UserProfileViewSet.as_view({'get': 'list'})
        request = self.factory.get(f'/userprofiles')
        response = view(request=request)
        self.assertEqual(response.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         response.data[0]['detail'])

        # cant update
        data = {
            'first_name': 'Peter',
            'phone_number': '+254722111111',
            'role': UserProfile.CONTRIBUTOR
        }
        view = UserProfileViewSet.as_view({'patch': 'partial_update'})
        request = self.factory.patch(f'/userprofiles/{userprofile.id}',
                                     data=data)
        response = view(request=request, pk=userprofile.id)
        self.assertEqual(response.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         response.data[0]['detail'])

        # cant delete
        view = UserProfileViewSet.as_view({'delete': 'destroy'})
        request = self.factory.delete(f'/userprofiles/{userprofile.id}')
        response = view(request=request, pk=userprofile.id)
        self.assertEqual(response.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         response.data[0]['detail'])

        # cant access profile endpoint
        view = UserProfileViewSet.as_view({'get': 'profile'})
        request = self.factory.get('/userprofiles/profile')
        response = view(request=request)
        self.assertEqual(response.status_code, 403)
        self.assertEqual('Authentication credentials were not provided.',
                         response.data[0]['detail'])
Пример #15
0
    def test_list_filtering(self):
        """
        test that you can get and filter a list of userprofiles
        """
        user = create_admin_user()  # ADMIN & EXPERT
        ben = mommy.make('auth.User', first_name='ben')
        ben.userprofile.role = UserProfile.CONTRIBUTOR
        ben.userprofile.expertise = UserProfile.ADVANCED
        ben.userprofile.ona_username = '******'
        ben.userprofile.save()

        alice = mommy.make('auth.User', first_name='alice')
        alice.userprofile.role = UserProfile.CONTRIBUTOR
        alice.userprofile.expertise = UserProfile.ADVANCED
        alice.userprofile.ona_username = '******'
        alice.userprofile.save()

        joe = mommy.make('auth.User', first_name='joe')
        joe.userprofile.role = UserProfile.CONTRIBUTOR
        joe.userprofile.expertise = UserProfile.BEGINNER
        joe.userprofile.ona_username = '******'
        joe.userprofile.save()

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

        request = self.factory.get('/userprofiles')
        force_authenticate(request=request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(4, len(response.data['results']))

        # role filter: there is only one admin
        request2 = self.factory.get('/userprofiles',
                                    {'role': UserProfile.ADMIN})
        force_authenticate(request=request2, user=user)
        response2 = view(request=request2)
        self.assertEqual(response2.status_code, 200)
        self.assertEqual(1, len(response2.data['results']))

        # expertise filter: there are two asvanced users
        request = self.factory.get('/userprofiles',
                                   {'expertise': UserProfile.ADVANCED})
        force_authenticate(request=request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(2, len(response.data['results']))

        # ona_username filter: test that we get correct profile
        request = self.factory.get('/userprofiles', {'ona_username': '******'})
        force_authenticate(request, user=user)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data['results']), 1)
        self.assertEqual(response.data['results'][0]['id'], joe.userprofile.id)

        # test joe can filter for his own profile
        request = self.factory.get('/userprofile', {'ona_username': '******'})
        force_authenticate(request, user=joe)
        response = view(request=request)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data['results']), 1)
        self.assertEqual(response.data['results'][0]['id'], joe.userprofile.id)

        # test random users can't filter for joes profile
        request = self.factory.get('/submissions', {'ona_username': '******'})
        force_authenticate(request, user=alice)
        response = view(request=request)
        self.assertEqual(response.status_code, 403)
        self.assertEqual(str(response.data[0]['detail']),
                         'You shall not pass.')