From 0d4dca1460db3cfc01b07ddb90b5bb84712ceaf4 Mon Sep 17 00:00:00 2001 From: Michael Collins <15347726+michaeljcollinsuk@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:46:58 +0100 Subject: [PATCH] Add tests for changes to the indexview --- controlpanel/frontend/views/__init__.py | 3 - controlpanel/frontend/views/auth.py | 4 +- tests/frontend/views/test_auth.py | 43 +++++++++++++ tests/frontend/views/test_index.py | 85 +++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 tests/frontend/views/test_auth.py create mode 100644 tests/frontend/views/test_index.py diff --git a/controlpanel/frontend/views/__init__.py b/controlpanel/frontend/views/__init__.py index 355944bea..ef1f21b65 100644 --- a/controlpanel/frontend/views/__init__.py +++ b/controlpanel/frontend/views/__init__.py @@ -1,13 +1,10 @@ # Standard library -import base64 -import hashlib # Third-party from django.http import HttpResponseRedirect from django.urls import reverse from django.views.generic.base import TemplateView from mozilla_django_oidc.views import OIDCLogoutView -from oauthlib.common import generate_token # First-party/Local from controlpanel.frontend.views.accessibility import Accessibility diff --git a/controlpanel/frontend/views/auth.py b/controlpanel/frontend/views/auth.py index 38e7961c0..2c2125333 100644 --- a/controlpanel/frontend/views/auth.py +++ b/controlpanel/frontend/views/auth.py @@ -19,7 +19,7 @@ class EntraIdAuthView(OIDCLoginRequiredMixin, View): """ http_method_names = ["get"] - def _authorize_token(self): + def _get_access_token(self): """ Attempts to valiate and return the access token """ @@ -34,7 +34,7 @@ def get(self, request, *args, **kwargs): """ Attempts to retrieve the auth token, and update the user. """ - token = self._authorize_token() + token = self._get_access_token() if not token: messages.error(request, "Something went wrong, please try again") return HttpResponseRedirect(reverse("index")) diff --git a/tests/frontend/views/test_auth.py b/tests/frontend/views/test_auth.py new file mode 100644 index 000000000..97dfa54b8 --- /dev/null +++ b/tests/frontend/views/test_auth.py @@ -0,0 +1,43 @@ +# Third-party +import pytest +from authlib.integrations.base_client import OAuthError +from django.urls import reverse, reverse_lazy +from mock import patch +from pytest_django.asserts import assertContains + + +class TestEntraIdAuthView: + url = reverse_lazy("entraid-auth") + + def test_unauthorised(self, client): + response = client.get(self.url) + + assert response.status_code == 302 + + @patch("controlpanel.frontend.views.auth.oauth") + def test_success(self, oauth, client, users): + oauth.azure.authorize_access_token.return_value = { + "userinfo": {"email": "email@example.com"}, + } + user = users["normal_user"] + assert user.justice_email is None + + client.force_login(user) + response = client.get(self.url, follow=True) + + user.refresh_from_db() + assert user.justice_email == "email@example.com" + assertContains(response, "Successfully authenticated with your email email@example.com") + + @patch("controlpanel.frontend.views.auth.oauth") + def test_failure(self, oauth, client, users): + oauth.azure.authorize_access_token.side_effect = OAuthError() + user = users["normal_user"] + assert user.justice_email is None + + client.force_login(user) + response = client.get(self.url, follow=True) + + user.refresh_from_db() + assert user.justice_email is None + assertContains(response, "Something went wrong, please try again") diff --git a/tests/frontend/views/test_index.py b/tests/frontend/views/test_index.py new file mode 100644 index 000000000..e917528ab --- /dev/null +++ b/tests/frontend/views/test_index.py @@ -0,0 +1,85 @@ +# Third-party +import pytest +from django.http import HttpResponse +from django.urls import reverse +from mock import MagicMock, patch + + +class TestAccess: + + @pytest.mark.parametrize("method, status_code", [ + ("get", 302), + ("post", 302), + + ]) + def test_not_logged_in_redirects(self, method, status_code, client): + response = getattr(client, method)("/") + assert response.status_code == status_code + + +class TestGetAsSuperuser: + + def test_without_justice_email(self, client, superuser): + client.force_login(superuser) + assert superuser.justice_email is None + + response = client.get("/") + + assert response.status_code == 200 + assert response.template_name == ["justice_email.html"] + + def test_with_justice_email(self, client, superuser): + superuser.justice_email = "email@example.com" + superuser.save() + client.force_login(superuser) + + response = client.get("/") + + assert response.status_code == 200 + assert response.template_name == ["home.html"] + + +class TestGetAsNormalUser: + + def test_without_justice_email(self, client, users): + user = users["normal_user"] + client.force_login(user) + assert user.justice_email is None + + response = client.get("/") + + assert response.status_code == 200 + assert response.template_name == ["justice_email.html"] + + def test_with_justice_email(self, client, users): + user = users["normal_user"] + user.justice_email = "email@example.com" + user.save() + client.force_login(user) + + response = client.get("/") + + assert response.status_code == 302 + assert response.url == reverse("list-tools") + + +class TestPost: + + @patch("controlpanel.frontend.views.get_code_challenge", new=MagicMock(return_value="codeabc")) + @pytest.mark.parametrize("user", [ + "superuser", + "normal_user" + ]) + def test_superuser_authorize_redirect_called(self, user, client, users): + user = users[user] + client.force_login(user) + with patch("controlpanel.frontend.views.oauth") as oauth: + oauth.azure.authorize_redirect.return_value = HttpResponse() + + response = client.post("/") + + oauth.azure.authorize_redirect.assert_called_once_with( + response.wsgi_request, + f"http://testserver{reverse('entraid-auth')}", + code_challenge="codeabc", + )