test_i18n.py 8.69 KB
Newer Older
1 2 3
"""
Tests i18n in courseware
"""
4

5
import json
6
import re
7

8
from django.conf import settings
9
from django.contrib.auth.models import User
10
from django.core.urlresolvers import reverse, reverse_lazy
11
from django.test import TestCase
12
from django.test.client import Client
13
from django.utils import translation
14
from nose.plugins.attrib import attr
15

16 17
from openedx.core.djangoapps.dark_lang.models import DarkLangConfig
from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY
18
from student.tests.factories import UserFactory
19

20 21

class BaseI18nTestCase(TestCase):
22
    """
23
    Base utilities for i18n test classes to derive from
24
    """
25 26 27
    preview_language_url = '/update_lang/'
    site_lang = settings.LANGUAGE_CODE
    pwd = 'test_password'
28
    url = reverse_lazy('dashboard')
29

30 31 32
    def setUp(self):
        super(BaseI18nTestCase, self).setUp()
        self.addCleanup(translation.deactivate)
33 34
        self.client = Client()
        self.create_user()
35

36 37
    def assert_tag_has_attr(self, content, tag, attname, value):
        """Assert that a tag in `content` has a certain value in a certain attribute."""
38
        regex = r"""<{tag} [^>]*\b{attname}=['"]([\w\d\- ]+)['"][^>]*>""".format(tag=tag, attname=attname)
39
        match = re.search(regex, content)
40
        self.assertTrue(match, "Couldn't find desired tag '%s' with attr '%s' in %r" % (tag, attname, content))
41 42 43
        attvalues = match.group(1).split()
        self.assertIn(value, attvalues)

44 45 46 47 48 49 50 51 52 53 54 55 56
    def release_languages(self, languages):
        """
        Release a set of languages using the dark lang interface.
        languages is a list of comma-separated lang codes, eg, 'ar, es-419'
        """
        user = User()
        user.save()
        DarkLangConfig(
            released_languages=languages,
            changed_by=user,
            enabled=True
        ).save()

57 58 59 60 61 62
    def create_user(self):
        """
        Creates the user log in
        """
        # Create one user and save it to the database
        email = 'test@edx.org'
63
        self.user = UserFactory.create(username='test', email=email, password=self.pwd)
64 65 66 67 68 69 70 71

    def user_login(self):
        """
        Log the user in
        """
        # Get the login url & log in our user
        self.client.login(username=self.user.username, password=self.pwd)

72

73
@attr(shard=1)
74 75 76 77
class I18nTestCase(BaseI18nTestCase):
    """
    Tests for i18n
    """
78
    def test_default_is_en(self):
79
        self.release_languages('fr')
80
        response = self.client.get('/')
81
        self.assert_tag_has_attr(response.content, "html", "lang", "en")
82
        self.assertEqual(response['Content-Language'], 'en')
83
        self.assert_tag_has_attr(response.content, "body", "class", "lang_en")
84

85
    def test_esperanto(self):
86
        self.release_languages('fr, eo')
87
        response = self.client.get('/', HTTP_ACCEPT_LANGUAGE='eo')
88
        self.assert_tag_has_attr(response.content, "html", "lang", "eo")
89
        self.assertEqual(response['Content-Language'], 'eo')
90 91 92
        self.assert_tag_has_attr(response.content, "body", "class", "lang_eo")

    def test_switching_languages_bidi(self):
93
        self.release_languages('ar, eo')
94 95 96 97 98 99 100 101 102 103 104
        response = self.client.get('/')
        self.assert_tag_has_attr(response.content, "html", "lang", "en")
        self.assertEqual(response['Content-Language'], 'en')
        self.assert_tag_has_attr(response.content, "body", "class", "lang_en")
        self.assert_tag_has_attr(response.content, "body", "class", "ltr")

        response = self.client.get('/', HTTP_ACCEPT_LANGUAGE='ar')
        self.assert_tag_has_attr(response.content, "html", "lang", "ar")
        self.assertEqual(response['Content-Language'], 'ar')
        self.assert_tag_has_attr(response.content, "body", "class", "lang_ar")
        self.assert_tag_has_attr(response.content, "body", "class", "rtl")
105 106


107
@attr(shard=1)
108 109 110 111 112 113 114 115 116 117 118 119 120
class I18nRegressionTests(BaseI18nTestCase):
    """
    Tests for i18n
    """
    def test_es419_acceptance(self):
        # Regression test; LOC-72, and an issue with Django
        self.release_languages('es-419')
        response = self.client.get('/', HTTP_ACCEPT_LANGUAGE='es-419')
        self.assert_tag_has_attr(response.content, "html", "lang", "es-419")

    def test_unreleased_lang_resolution(self):
        # Regression test; LOC-85
        self.release_languages('fa')
121
        self.user_login()
122 123 124 125 126

        # We've released 'fa', AND we have language files for 'fa-ir' but
        # we want to keep 'fa-ir' as a dark language. Requesting 'fa-ir'
        # in the http request (NOT with the ?preview-lang query param) should
        # receive files for 'fa'
127
        response = self.client.get(self.url, HTTP_ACCEPT_LANGUAGE='fa-ir')
128
        self.assert_tag_has_attr(response.content, "html", "lang", "fa")
129 130

        # Now try to access with dark lang
131
        self.client.post(self.preview_language_url, {'preview_language': 'fa-ir', 'action': 'set_preview_language'})
132
        response = self.client.get(self.url)
133 134 135
        self.assert_tag_has_attr(response.content, "html", "lang", "fa-ir")

    def test_preview_lang(self):
136 137
        self.user_login()

138 139 140 141
        # Regression test; LOC-87
        self.release_languages('es-419')
        site_lang = settings.LANGUAGE_CODE
        # Visit the front page; verify we see site default lang
142
        response = self.client.get(self.url)
143 144 145
        self.assert_tag_has_attr(response.content, "html", "lang", site_lang)

        # Verify we can switch language using the preview-lang query param
146
        # Set the language
147
        self.client.post(self.preview_language_url, {'preview_language': 'eo', 'action': 'set_preview_language'})
148 149

        response = self.client.get(self.url)
150 151
        self.assert_tag_has_attr(response.content, "html", "lang", "eo")
        # We should be able to see released languages using preview-lang, too
152
        self.client.post(self.preview_language_url, {'preview_language': 'es-419', 'action': 'set_preview_language'})
153
        response = self.client.get(self.url)
154 155 156
        self.assert_tag_has_attr(response.content, "html", "lang", "es-419")

        # Clearing the language should go back to site default
157
        self.client.post(self.preview_language_url, {'action': 'reset_preview_language'})
158
        response = self.client.get(self.url)
159 160 161
        self.assert_tag_has_attr(response.content, "html", "lang", site_lang)


162
@attr(shard=1)
163 164 165 166 167 168 169 170
class I18nLangPrefTests(BaseI18nTestCase):
    """
    Regression tests of language presented to the user, when they
    choose a language preference, and when they have a preference
    and use the dark lang preview functionality.
    """
    def setUp(self):
        super(I18nLangPrefTests, self).setUp()
171
        self.user_login()
172

173
    def set_lang_preference(self, language):
174 175 176
        """
        Sets the user's language preference, allowing the LangPref middleware to operate to set the preference cookie.
        """
177 178 179 180 181 182 183
        response = self.client.patch(
            reverse('preferences_api', args=[self.user.username]),
            json.dumps({LANGUAGE_KEY: language}),
            content_type="application/merge-patch+json"
        )
        self.assertEqual(response.status_code, 204)

184 185 186 187 188 189 190 191 192
    def test_lang_preference(self):
        # Regression test; LOC-87
        self.release_languages('ar, es-419')

        # Visit the front page; verify we see site default lang
        response = self.client.get(self.url)
        self.assert_tag_has_attr(response.content, "html", "lang", self.site_lang)

        # Set user language preference
193
        self.set_lang_preference('ar')
194 195 196 197 198
        # and verify we now get an ar response
        response = self.client.get(self.url)
        self.assert_tag_has_attr(response.content, "html", "lang", 'ar')

        # Verify that switching language preference gives the right language
199
        self.set_lang_preference('es-419')
200 201 202 203 204 205 206 207
        response = self.client.get(self.url)
        self.assert_tag_has_attr(response.content, "html", "lang", 'es-419')

    def test_preview_precedence(self):
        # Regression test; LOC-87
        self.release_languages('ar, es-419')

        # Set user language preference
208
        self.set_lang_preference('ar')
209
        # Verify preview-lang takes precedence
210
        self.client.post(self.preview_language_url, {'preview_language': 'eo', 'action': 'set_preview_language'})
211 212
        response = self.client.get(self.url)

213
        self.assert_tag_has_attr(response.content, "html", "lang", 'eo')
214 215 216
        # Hitting another page should keep the dark language set.
        response = self.client.get(reverse('courses'))
        self.assert_tag_has_attr(response.content, "html", "lang", "eo")
217 218

        # Clearing language must set language back to preference language
219
        self.client.post(self.preview_language_url, {'action': 'reset_preview_language'})
220 221
        response = self.client.get(self.url)

222
        self.assert_tag_has_attr(response.content, "html", "lang", 'ar')