mirror of
https://github.com/django/django.git
synced 2025-11-02 04:48:33 +00:00
Fixed #21446 -- Allowed not performing redirect in set_language view
Thanks Claude Paroz and Tim Graham for polishing the patch.
This commit is contained in:
parent
12ba20d83c
commit
940b7fd5cb
4 changed files with 105 additions and 19 deletions
|
|
@ -13,7 +13,9 @@ from django.test.selenium import SeleniumTestCase
|
|||
from django.urls import reverse
|
||||
from django.utils import six
|
||||
from django.utils._os import upath
|
||||
from django.utils.translation import LANGUAGE_SESSION_KEY, override
|
||||
from django.utils.translation import (
|
||||
LANGUAGE_SESSION_KEY, get_language, override,
|
||||
)
|
||||
|
||||
from ..urls import locale_dir
|
||||
|
||||
|
|
@ -22,29 +24,98 @@ from ..urls import locale_dir
|
|||
class I18NTests(TestCase):
|
||||
""" Tests django views in django/views/i18n.py """
|
||||
|
||||
def _get_inactive_language_code(self):
|
||||
"""Return language code for a language which is not activated."""
|
||||
current_language = get_language()
|
||||
return [code for code, name in settings.LANGUAGES if not code == current_language][0]
|
||||
|
||||
def test_setlang(self):
|
||||
"""
|
||||
The set_language view can be used to change the session language.
|
||||
|
||||
The user is redirected to the 'next' argument if provided.
|
||||
"""
|
||||
for lang_code, lang_name in settings.LANGUAGES:
|
||||
post_data = dict(language=lang_code, next='/')
|
||||
response = self.client.post('/i18n/setlang/', data=post_data)
|
||||
self.assertRedirects(response, '/')
|
||||
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
||||
lang_code = self._get_inactive_language_code()
|
||||
post_data = dict(language=lang_code, next='/')
|
||||
response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i_should_not_be_used/')
|
||||
self.assertRedirects(response, '/')
|
||||
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
||||
|
||||
def test_setlang_unsafe_next(self):
|
||||
"""
|
||||
The set_language view only redirects to the 'next' argument if it is
|
||||
"safe".
|
||||
"""
|
||||
lang_code, lang_name = settings.LANGUAGES[0]
|
||||
lang_code = self._get_inactive_language_code()
|
||||
post_data = dict(language=lang_code, next='//unsafe/redirection/')
|
||||
response = self.client.post('/i18n/setlang/', data=post_data)
|
||||
self.assertEqual(response.url, '/')
|
||||
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
||||
|
||||
def test_setlang_redirect_to_referer(self):
|
||||
"""
|
||||
The set_language view redirects to the URL in the referer header when
|
||||
there isn't a "next" parameter.
|
||||
"""
|
||||
lang_code = self._get_inactive_language_code()
|
||||
post_data = dict(language=lang_code)
|
||||
response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i18n/')
|
||||
self.assertRedirects(response, '/i18n/', fetch_redirect_response=False)
|
||||
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
||||
|
||||
def test_setlang_default_redirect(self):
|
||||
"""
|
||||
The set_language view redirects to '/' when there isn't a referer or
|
||||
"next" parameter.
|
||||
"""
|
||||
lang_code = self._get_inactive_language_code()
|
||||
post_data = dict(language=lang_code)
|
||||
response = self.client.post('/i18n/setlang/', post_data)
|
||||
self.assertRedirects(response, '/')
|
||||
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
||||
|
||||
def test_setlang_performs_redirect_for_ajax_if_explicitly_requested(self):
|
||||
"""
|
||||
The set_language view redirects to the "next" parameter for AJAX calls.
|
||||
"""
|
||||
lang_code = self._get_inactive_language_code()
|
||||
post_data = dict(language=lang_code, next='/')
|
||||
response = self.client.post('/i18n/setlang/', post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertRedirects(response, '/')
|
||||
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
||||
|
||||
def test_setlang_doesnt_perform_a_redirect_to_referer_for_ajax(self):
|
||||
"""
|
||||
The set_language view doesn't redirect to the HTTP referer header for
|
||||
AJAX calls.
|
||||
"""
|
||||
lang_code = self._get_inactive_language_code()
|
||||
post_data = dict(language=lang_code)
|
||||
headers = {'HTTP_REFERER': '/', 'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'}
|
||||
response = self.client.post('/i18n/setlang/', post_data, **headers)
|
||||
self.assertEqual(response.status_code, 204)
|
||||
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
||||
|
||||
def test_setlang_doesnt_perform_a_default_redirect_for_ajax(self):
|
||||
"""
|
||||
The set_language view returns 204 for AJAX calls by default.
|
||||
"""
|
||||
lang_code = self._get_inactive_language_code()
|
||||
post_data = dict(language=lang_code)
|
||||
response = self.client.post('/i18n/setlang/', post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertEqual(response.status_code, 204)
|
||||
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
||||
|
||||
def test_setlang_unsafe_next_for_ajax(self):
|
||||
"""
|
||||
The fallback to root URL for the set_language view works for AJAX calls.
|
||||
"""
|
||||
lang_code = self._get_inactive_language_code()
|
||||
post_data = dict(language=lang_code, next='//unsafe/redirection/')
|
||||
response = self.client.post('/i18n/setlang/', post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertEqual(response.url, '/')
|
||||
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
||||
|
||||
def test_setlang_reversal(self):
|
||||
self.assertEqual(reverse('set_language'), '/i18n/setlang/')
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue