From 92563d387a858d97467b1f257454354f9fc7e3b2 Mon Sep 17 00:00:00 2001 From: Valentin Gagarin Date: Wed, 19 Feb 2025 23:07:51 +0100 Subject: [PATCH] test login/logout redirection (#163) this concludes https://git.fediversity.eu/Fediversity/Fediversity/issues/72 with a test covering most of the user story. test in the devshell: ``` manage test panel ``` test in full isolation: ``` nix-build -A tests ``` Reviewed-on: https://git.fediversity.eu/Fediversity/Fediversity/pulls/163 Reviewed-by: kiara Grouwstra --- panel/nix/tests.nix | 2 +- panel/src/panel/templates/base.html | 2 +- panel/src/panel/tests/__init__.py | 0 panel/src/panel/tests/test_user_stories.py | 104 +++++++++++++++++++++ 4 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 panel/src/panel/tests/__init__.py create mode 100644 panel/src/panel/tests/test_user_stories.py diff --git a/panel/nix/tests.nix b/panel/nix/tests.nix index eaa9068..a825938 100644 --- a/panel/nix/tests.nix +++ b/panel/nix/tests.nix @@ -26,7 +26,7 @@ lib.mapAttrs (name: test: pkgs.testers.runNixOSTest (test // { inherit name; })) # run all application-level tests managed by Django # https://docs.djangoproject.com/en/5.0/topics/testing/overview/ testScript = '' - server.succeed("manage test") + server.succeed("manage test ${name}") ''; }; admin = { diff --git a/panel/src/panel/templates/base.html b/panel/src/panel/templates/base.html index 7f8b2e1..aa29745 100644 --- a/panel/src/panel/templates/base.html +++ b/panel/src/panel/templates/base.html @@ -30,7 +30,7 @@ {% load custom_tags %}
  • {% if user.is_authenticated %} - Welcome, {{ user.username }}! Logout + Welcome, {{ user.username }}! Logout {% else %} Login {% endif %} diff --git a/panel/src/panel/tests/__init__.py b/panel/src/panel/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/panel/src/panel/tests/test_user_stories.py b/panel/src/panel/tests/test_user_stories.py new file mode 100644 index 0000000..8f45ae4 --- /dev/null +++ b/panel/src/panel/tests/test_user_stories.py @@ -0,0 +1,104 @@ +from django.test import TestCase +from django.urls import reverse +from django.contrib.auth.models import User +from django.template import Template, Context +from urllib.parse import unquote + +class Login(TestCase): + def setUp(self): + self.username = 'testuser' + self.password = 'securepassword123' + self.user = User.objects.create_user( + username=self.username, + email='test@example.com', + password=self.password + ) + + self.login = reverse('login') + self.logout = reverse('logout') + self.required_login = reverse('account_detail') + self.optional_login = reverse('service_list') + + def test_optional_login_redirects_back_to_original_page(self): + # go to a view where authentication is optional + response = self.client.get(self.optional_login) + self.assertEqual(response.status_code, 200) + self.assertFalse(response.context['user'].is_authenticated) + + # check that the expected login URL is in the response + context = response.context[0] + template = Template("{% load custom_tags %}{% auth_url 'login' %}") + login_url = template.render(context) + self.assertIn(login_url, response.content.decode('utf-8')) + + # log in + response = self.client.get(login_url) + self.assertEqual(response.status_code, 200) + + login_data = { + 'username': self.username, + 'password': self.password, + } + response = self.client.post(login_url, login_data, follow=True) + + # check that we're back at the desired view and authenticated + self.assertEqual(response.status_code, 200) + self.assertTrue(response.context['user'].is_authenticated) + location, status = response.redirect_chain[-1] + self.assertEqual(location, self.optional_login) + + # check that the expected logout URL is present + context = response.context[0] + template = Template("{% load custom_tags %}{% auth_url 'logout' %}") + logout_url = template.render(context) + self.assertIn(logout_url, response.content.decode('utf-8')) + + # log out again + response = self.client.get(logout_url, follow=True) + + # check that we're back at the view and logged out + self.assertEqual(response.status_code, 200) + location, status = response.redirect_chain[-1] + self.assertEqual(location, self.optional_login) + self.assertFalse(response.context['user'].is_authenticated) + + def test_required_login_redirects_back_login(self): + # go to a view that requires authentication + response = self.client.get(self.required_login) + + # check that we're redirected to the login view + self.assertEqual(response.status_code, 302) + redirect = response.url + self.assertTrue(redirect.startswith(self.login)) + + # log in + response = self.client.get(redirect) + self.assertEqual(response.status_code, 200) + login_data = { + 'username': self.username, + 'password': self.password, + } + response = self.client.post(redirect, login_data, follow=True) + + # check that we reached the desired view, authenticated + self.assertEqual(response.status_code, 200) + location, status = response.redirect_chain[-1] + self.assertEqual(location, self.required_login) + self.assertTrue(response.context['user'].is_authenticated) + + # check that the expected logout URL is present + context = response.context[0] + template = Template("{% load custom_tags %}{% auth_url 'logout' %}") + logout_url = template.render(context) + self.assertIn(logout_url, response.content.decode('utf-8')) + + # log out + response = self.client.get(logout_url, follow=True) + + # check that we're at the expected location, logged out + self.assertEqual(response.status_code, 200) + template = Template("{% load custom_tags %}{% auth_url 'login' %}") + login_url = template.render(context) + location, status = response.redirect_chain[-1] + self.assertEqual(location, unquote(login_url)) + self.assertFalse(response.context['user'].is_authenticated)