From b8b2cb4299b1c76000b02e7e2a34fc0fc9012911 Mon Sep 17 00:00:00 2001 From: Thomas McKennon Date: Thu, 18 Feb 2021 21:18:06 -0800 Subject: [PATCH] Added backend unit tests to tests.py for the request account approval workflow in order to track down a bug occurring when users attempt to approve multiple accounts that are a mix of new and existing accounts (#76). --- accounts/fixtures/fixtures.json | 28 ++++++++- accounts/tests.py | 105 ++++++++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 5 deletions(-) diff --git a/accounts/fixtures/fixtures.json b/accounts/fixtures/fixtures.json index 1298079..64e4db6 100644 --- a/accounts/fixtures/fixtures.json +++ b/accounts/fixtures/fixtures.json @@ -5,7 +5,7 @@ "fields": { "password": "secret password", "last_login": "2020-05-06T21:22:04.324Z", - "is_superuser": true, + "is_superuser": false, "username": "aname", "first_name": "a", "last_name": "name", @@ -43,6 +43,32 @@ "response": 1 } }, + { + "model": "accounts.accountrequests", + "pk": 2, + "fields": { + "first_name": "Joe", + "last_name": "Smith", + "email": "Smith.Joe@epa.gov", + "possible_existing_account": "", + "organization": "Org", + "username": "Smith.Joe_EPAEXT", + "username_valid": true, + "user_type": "user_type", + "role": "specialid", + "sponsor": 1, + "sponsor_notified": false, + "reason": "Emergency Response", + "recaptcha": "supersecret", + "submitted": "2021-01-19T14:35:39.647Z", + "approved": "2021-01-19T14:35:39.647Z", + "created": "2021-01-19T14:35:39.647Z", + "agol_id": "69ac034ef09e4abca2fe67fda9cf6bda", + "groups": ["000b6ee1-21bb-4739-a502-1e0f0241ff01"], + "auth_group": "00237b67-4c33-47a1-8e0f-b2bfcdb248e1", + "response": 1 + } + }, { "model": "accounts.agol", "pk": 1, diff --git a/accounts/tests.py b/accounts/tests.py index 3b21e55..1b583e7 100644 --- a/accounts/tests.py +++ b/accounts/tests.py @@ -1,10 +1,15 @@ -from django.test import TestCase +from django.test import RequestFactory, TestCase from unittest.mock import patch, MagicMock -from .models import AGOL, AccountRequests +from django.shortcuts import get_list_or_404 from django.contrib.auth.models import User -from .views import format_username +from django.utils.timezone import now + import json +from .models import AGOL, AGOLUserFields, AccountRequests +from .views import format_username, SponsorsViewSet +from .permissions import IsSponsor + def mock_check_username_empty(*args, **kwargs): class MockResponse: @@ -79,9 +84,30 @@ def json(self): return MockResponse() +def mock_add_to_group(*args, **kwargs): + class MockRequest: + body = 'nothing' + + class MockResponse: + status_code = 200 + + def json(self): + return { + "notAdded": [""] + } + return MockResponse() + + class TestAccounts(TestCase): fixtures = ['fixtures.json'] + def setUp(self): + self.factory = RequestFactory() + agol_user = AGOLUserFields.objects.first() + self.user = agol_user.user + self.account_requests = None + self.is_sponsor = IsSponsor() + def test_username_formatting(self): data = {'email': 'myname@epa.gov', 'first_name': 'Joe', 'last_name': 'Smo'} username = format_username(data) @@ -127,7 +153,6 @@ def test_account_rejection(self, mock_post, mock_get): exists = AccountRequests.objects.filter(agol_id='ffffffff-ffff-ffff-ffff-ffffffffffff').exists() self.assertFalse(exists) - @patch('accounts.models.requests.post', side_effect=mock_create_user) @patch('accounts.models.requests.get', side_effect=mock_get_user) def test_create_account(self, mock_post, mock_get): @@ -139,6 +164,33 @@ def test_create_account(self, mock_post, mock_get): exists = AccountRequests.objects.filter(agol_id='ffffffff-ffff-ffff-ffff-ffffffffffff').exists() self.assertTrue(exists) + @patch('accounts.models.requests.post', side_effect=mock_create_user) + @patch('accounts.models.requests.get', side_effect=mock_get_user) + def test_create_accounts(self, mock_post, mock_get): + agol = AGOL.objects.get(pk=1) + agol.get_token = MagicMock(return_value='token') + success = [] + + account_requests = self.account_requests + if account_requests is None: + account_requests = get_list_or_404(AccountRequests) + + AccountRequests.objects.all().update(approved=now()) + create_accounts = [x for x in account_requests if x.agol_id is None] + create_success = len(create_accounts) == 0 + if len(create_accounts) > 0: + success += agol.create_users_accounts(account_requests, 'password') + if len(success) == len(create_accounts): + create_success = True + else: + create_success = True + + if not create_success: + self.assertFalse("Error creating and updating accounts") + else: + self.assertTrue(True) + return success + def test_invitations(self): agol = AGOL.objects.get(pk=1) agol.get_token = MagicMock(return_value='token') @@ -147,3 +199,48 @@ def test_invitations(self): self.assertTrue('000b6ee121bb4739a5021e0f0241ff01' in invitations[0]["groups"]) self.assertTrue('00237b674c3347a18e0fb2bfcdb248e1' in invitations[0]["groups"]) + def test_user_has_account_request_permission(self, account_requests=None): + request = self.factory.get('/account/approvals') + request.user = self.user + if account_requests is None: + account_requests = get_list_or_404(AccountRequests) + for ac in account_requests: + self.is_sponsor.has_object_permission(request, SponsorsViewSet, ac) + self.assertTrue(1) + + @patch('accounts.models.requests.post', side_effect=mock_add_to_group) + def test_user_approvals(self, mock_post): + agol = AGOL.objects.get(pk=1) + agol.get_token = MagicMock(return_value='token') + + self.account_requests = get_list_or_404(AccountRequests) + account_requests = self.account_requests + success = [] + + # verify user has permission on each request + self.test_user_has_account_request_permission(account_requests) + + create_success = False + created_accounts = self.test_create_accounts() + if len(created_accounts) > 0: + success.extend(created_accounts) + create_success = True + + # add users to groups for either existing or newly created + group_requests = [x for x in AccountRequests.objects.filter(agol_id__isnull=False)] + group_success = len(group_requests) == 0 + for g in group_requests: + if g.groups.count() > 0: + group_success = agol.add_to_group([g.username], [str(x) for x in g.groups.values_list('id', flat=True)]) + if group_success: + success.append(g.pk) + else: + group_success = True + + AccountRequests.objects.filter(pk__in=success).update(created=now()) + if create_success and group_success: + self.assertTrue(1) + if not create_success: + self.assertFalse("Error creating and updating accounts") + if not group_success: + self.assertFalse("Accounts created. Existing account NOT updated.")