From ead851893ad10aae01f4918faa565837c88ade9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sun, 17 May 2020 17:36:15 +0200 Subject: [PATCH] Test the logout view --- .../0002_casaccount_connected_to_cas.py | 6 +- authens/tests/test_views.py | 63 +++++++++++++++++++ tests/settings.py | 29 +++++++++ tests/urls.py | 4 ++ 4 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 authens/tests/test_views.py create mode 100644 tests/urls.py diff --git a/authens/migrations/0002_casaccount_connected_to_cas.py b/authens/migrations/0002_casaccount_connected_to_cas.py index 84910a3..9559757 100644 --- a/authens/migrations/0002_casaccount_connected_to_cas.py +++ b/authens/migrations/0002_casaccount_connected_to_cas.py @@ -6,13 +6,13 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('authens', '0001_initial'), + ("authens", "0001_initial"), ] operations = [ migrations.AddField( - model_name='casaccount', - name='connected_to_cas', + model_name="casaccount", + name="connected_to_cas", field=models.BooleanField(default=False, editable=False), ), ] diff --git a/authens/tests/test_views.py b/authens/tests/test_views.py new file mode 100644 index 0000000..4ad5176 --- /dev/null +++ b/authens/tests/test_views.py @@ -0,0 +1,63 @@ +from unittest.mock import patch + +from django.conf import settings +from django.contrib.auth import get_user_model +from django.contrib.sessions.models import Session +from django.test import Client, TestCase + +from authens.models import CASAccount +from authens.tests.cas_utils import FakeCASClient + +UserModel = get_user_model() + + +class TestLogoutView(TestCase): + def test_regular_logout(self): + # Regular user (without a CAS account) + user = UserModel.objects.create_user(username="johndoe") + + # Log the user in + client = Client() + client.force_login(user) + + self.assertEqual(Session.objects.count(), 1) + response = client.get("/authens/logout") + self.assertEqual(Session.objects.count(), 0) # User is actually logged out. + self.assertRedirects(response, settings.LOGOUT_REDIRECT_URL) + + @patch("authens.backends.get_cas_client") + def test_cas_logout(self, mock_cas_client): + # Make `get_cas_client` return a dummy CAS client that skips ticket verification + # and always log in a user with CAS login 'johndoe'. + # This is only used for login. + mock_cas_client.return_value = FakeCASClient("johndoe", 2019) + + # CAS user + user = UserModel.objects.create_user(username="johndoe") + CASAccount.objects.create(user=user, cas_login="johndoe", entrance_year=2019) + + # Log the user in via CAS + client = Client() + client.login(ticket="dummy ticket") + + self.assertEqual(Session.objects.count(), 1) + response = client.get("/authens/logout") + self.assertEqual(Session.objects.count(), 0) # User is logged out… + self.assertRedirects( # … and redirected to the CAS logout page. + response, "https://cas.eleves.ens.fr/logout", fetch_redirect_response=False + ) + + def test_regular_logout_on_cas_account(self): + # CAS user + user = UserModel.objects.create_user(username="johndoe", password="p4ssw0rd") + CASAccount.objects.create(user=user, cas_login="johndoe", entrance_year=2019) + + # Log the user in by password and *not* via CAS + client = Client() + client.login(username="johndoe", password="p4ssw0rd") + + self.assertEqual(Session.objects.count(), 1) + response = client.get("/authens/logout") + self.assertEqual(Session.objects.count(), 0) # User is logged out… + # … and not redirected to the CAS logout page. + self.assertRedirects(response, settings.LOGOUT_REDIRECT_URL) diff --git a/tests/settings.py b/tests/settings.py index 999e477..04168fd 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -8,6 +8,7 @@ SECRET_KEY = "dummy" INSTALLED_APPS = [ "django.contrib.contenttypes", "django.contrib.auth", + "django.contrib.sessions", "authens", "tests", ] @@ -17,6 +18,34 @@ AUTHENTICATION_BACKENDS = [ "authens.backends.ENSCASBackend", ] +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + }, +] + DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3"}} +ROOT_URLCONF = "tests.urls" LOGIN_URL = reverse_lazy("authens:login") +LOGOUT_REDIRECT_URL = reverse_lazy("authens:login") diff --git a/tests/urls.py b/tests/urls.py new file mode 100644 index 0000000..2b6ab10 --- /dev/null +++ b/tests/urls.py @@ -0,0 +1,4 @@ +from django.urls import include, path + + +urlpatterns = [path("authens/", include("authens.urls"))]