test login/logout redirection (#163)

this concludes Fediversity/Fediversity#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: Fediversity/Fediversity#163
Reviewed-by: kiara Grouwstra <kiara@procolix.eu>
This commit is contained in:
Valentin Gagarin 2025-02-19 23:07:51 +01:00
parent b6e11c893b
commit 92563d387a
4 changed files with 106 additions and 2 deletions

View file

@ -26,7 +26,7 @@ lib.mapAttrs (name: test: pkgs.testers.runNixOSTest (test // { inherit name; }))
# run all application-level tests managed by Django # run all application-level tests managed by Django
# https://docs.djangoproject.com/en/5.0/topics/testing/overview/ # https://docs.djangoproject.com/en/5.0/topics/testing/overview/
testScript = '' testScript = ''
server.succeed("manage test") server.succeed("manage test ${name}")
''; '';
}; };
admin = { admin = {

View file

@ -30,7 +30,7 @@
{% load custom_tags %} {% load custom_tags %}
<li> <li>
{% if user.is_authenticated %} {% if user.is_authenticated %}
Welcome, {{ user.username }}! <a id="logout" href="{% auth_url 'logout' %}">Logout</a> Welcome, <a href="{% url 'account_detail' %}">{{ user.username }}</a>! <a id="logout" href="{% auth_url 'logout' %}">Logout</a>
{% else %} {% else %}
<a id="login" href="{% auth_url 'login' %}">Login</a> <a id="login" href="{% auth_url 'login' %}">Login</a>
{% endif %} {% endif %}

View file

View file

@ -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)