test_i18n.py 8.65 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
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 28
    preview_language_url = '/update_lang/'
    url = reverse('dashboard')
    site_lang = settings.LANGUAGE_CODE
    pwd = 'test_password'
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 174 175 176 177 178 179 180 181
    def set_lang_preference(self, language):
        """Sets the user's language preference, allowing the LangPref middleware to operate to set the preference cookie."""
        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)

182 183 184 185 186 187 188 189 190
    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
191
        self.set_lang_preference('ar')
192 193 194 195 196
        # 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
197
        self.set_lang_preference('es-419')
198 199 200 201 202 203 204 205
        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
206
        self.set_lang_preference('ar')
207
        # Verify preview-lang takes precedence
208
        self.client.post(self.preview_language_url, {'preview_language': 'eo', 'action': 'set_preview_language'})
209 210
        response = self.client.get(self.url)

211
        self.assert_tag_has_attr(response.content, "html", "lang", 'eo')
212 213 214
        # 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")
215 216

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

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