|
13 | 13 | from django.urls import reverse
|
14 | 14 | from django.utils import six
|
15 | 15 | from django.utils._os import upath
|
16 |
| -from django.utils.translation import LANGUAGE_SESSION_KEY, override |
| 16 | +from django.utils.translation import ( |
| 17 | + LANGUAGE_SESSION_KEY, get_language, override, |
| 18 | +) |
17 | 19 |
|
18 | 20 | from ..urls import locale_dir
|
19 | 21 |
|
|
22 | 24 | class I18NTests(TestCase):
|
23 | 25 | """ Tests django views in django/views/i18n.py """
|
24 | 26 |
|
| 27 | + def _get_inactive_language_code(self): |
| 28 | + """Return language code for a language which is not activated.""" |
| 29 | + current_language = get_language() |
| 30 | + return [code for code, name in settings.LANGUAGES if not code == current_language][0] |
| 31 | + |
25 | 32 | def test_setlang(self):
|
26 | 33 | """
|
27 | 34 | The set_language view can be used to change the session language.
|
28 | 35 |
|
29 | 36 | The user is redirected to the 'next' argument if provided.
|
30 | 37 | """
|
31 |
| - for lang_code, lang_name in settings.LANGUAGES: |
32 |
| - post_data = dict(language=lang_code, next='/') |
33 |
| - response = self.client.post('/i18n/setlang/', data=post_data) |
34 |
| - self.assertRedirects(response, '/') |
35 |
| - self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) |
| 38 | + lang_code = self._get_inactive_language_code() |
| 39 | + post_data = dict(language=lang_code, next='/') |
| 40 | + response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i_should_not_be_used/') |
| 41 | + self.assertRedirects(response, '/') |
| 42 | + self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) |
36 | 43 |
|
37 | 44 | def test_setlang_unsafe_next(self):
|
38 | 45 | """
|
39 | 46 | The set_language view only redirects to the 'next' argument if it is
|
40 | 47 | "safe".
|
41 | 48 | """
|
42 |
| - lang_code, lang_name = settings.LANGUAGES[0] |
| 49 | + lang_code = self._get_inactive_language_code() |
43 | 50 | post_data = dict(language=lang_code, next='//unsafe/redirection/')
|
44 | 51 | response = self.client.post('/i18n/setlang/', data=post_data)
|
45 | 52 | self.assertEqual(response.url, '/')
|
46 | 53 | self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
|
47 | 54 |
|
| 55 | + def test_setlang_redirect_to_referer(self): |
| 56 | + """ |
| 57 | + The set_language view redirects to the URL in the referer header when |
| 58 | + there isn't a "next" parameter. |
| 59 | + """ |
| 60 | + lang_code = self._get_inactive_language_code() |
| 61 | + post_data = dict(language=lang_code) |
| 62 | + response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i18n/') |
| 63 | + self.assertRedirects(response, '/i18n/', fetch_redirect_response=False) |
| 64 | + self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) |
| 65 | + |
| 66 | + def test_setlang_default_redirect(self): |
| 67 | + """ |
| 68 | + The set_language view redirects to '/' when there isn't a referer or |
| 69 | + "next" parameter. |
| 70 | + """ |
| 71 | + lang_code = self._get_inactive_language_code() |
| 72 | + post_data = dict(language=lang_code) |
| 73 | + response = self.client.post('/i18n/setlang/', post_data) |
| 74 | + self.assertRedirects(response, '/') |
| 75 | + self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) |
| 76 | + |
| 77 | + def test_setlang_performs_redirect_for_ajax_if_explicitly_requested(self): |
| 78 | + """ |
| 79 | + The set_language view redirects to the "next" parameter for AJAX calls. |
| 80 | + """ |
| 81 | + lang_code = self._get_inactive_language_code() |
| 82 | + post_data = dict(language=lang_code, next='/') |
| 83 | + response = self.client.post('/i18n/setlang/', post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') |
| 84 | + self.assertRedirects(response, '/') |
| 85 | + self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) |
| 86 | + |
| 87 | + def test_setlang_doesnt_perform_a_redirect_to_referer_for_ajax(self): |
| 88 | + """ |
| 89 | + The set_language view doesn't redirect to the HTTP referer header for |
| 90 | + AJAX calls. |
| 91 | + """ |
| 92 | + lang_code = self._get_inactive_language_code() |
| 93 | + post_data = dict(language=lang_code) |
| 94 | + headers = {'HTTP_REFERER': '/', 'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'} |
| 95 | + response = self.client.post('/i18n/setlang/', post_data, **headers) |
| 96 | + self.assertEqual(response.status_code, 204) |
| 97 | + self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) |
| 98 | + |
| 99 | + def test_setlang_doesnt_perform_a_default_redirect_for_ajax(self): |
| 100 | + """ |
| 101 | + The set_language view returns 204 for AJAX calls by default. |
| 102 | + """ |
| 103 | + lang_code = self._get_inactive_language_code() |
| 104 | + post_data = dict(language=lang_code) |
| 105 | + response = self.client.post('/i18n/setlang/', post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') |
| 106 | + self.assertEqual(response.status_code, 204) |
| 107 | + self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) |
| 108 | + |
| 109 | + def test_setlang_unsafe_next_for_ajax(self): |
| 110 | + """ |
| 111 | + The fallback to root URL for the set_language view works for AJAX calls. |
| 112 | + """ |
| 113 | + lang_code = self._get_inactive_language_code() |
| 114 | + post_data = dict(language=lang_code, next='//unsafe/redirection/') |
| 115 | + response = self.client.post('/i18n/setlang/', post_data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') |
| 116 | + self.assertEqual(response.url, '/') |
| 117 | + self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) |
| 118 | + |
48 | 119 | def test_setlang_reversal(self):
|
49 | 120 | self.assertEqual(reverse('set_language'), '/i18n/setlang/')
|
50 | 121 |
|
|
0 commit comments