This abstract class contains most of the fields (aside from the id and foreign key to StudentModule that the subclasses need to manage). It also provides a get_history method that abstracts searching across multiple backends. Move router code to openedx/core We need to use it from cms and lms. Ensure aws_migrate can be used for migrating both the lms and cms. Handle queries directed to student_module_history vs default and the extra queries generated by Django 1.8 (SAVEPOINTS, etc). Additionally, flag testing classes as multi_db so that Django will flush the non-default database between unit tests. Further decouple the foreignkey relation between csm and csmhe When calling StudentModule().delete() Django will try to delete CSMHE objects, but naively does so in the database, not by consulting the database router. Instead, we disable django cascading deletes and listen for post_delete signals and clean up CSMHE by hand. Add feature flags for CSMHE One to turn it on/off so we can control the deploy. The other will control whether or not we read from two database tables or one when searching. Update tests to explicitly use this get_history method rather than looking directly into StudentModuleHistory or StudentModuleHistoryExtended. Inform lettuce to avoid the coursewarehistoryextended app Otherwise it fails when it can't find features/ in that app. Add Pg support, this is not tested automatically.
197 lines
7.8 KiB
Python
197 lines
7.8 KiB
Python
"""
|
|
Tests i18n in courseware
|
|
"""
|
|
import re
|
|
from nose.plugins.attrib import attr
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth.models import User
|
|
from django.core.urlresolvers import reverse, NoReverseMatch
|
|
from django.test import TestCase
|
|
from django.test.client import Client
|
|
|
|
from dark_lang.models import DarkLangConfig
|
|
from lang_pref import LANGUAGE_KEY
|
|
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
|
|
from student.tests.factories import UserFactory, RegistrationFactory, UserProfileFactory
|
|
|
|
|
|
class BaseI18nTestCase(TestCase):
|
|
"""
|
|
Base utilities for i18n test classes to derive from
|
|
"""
|
|
|
|
def assert_tag_has_attr(self, content, tag, attname, value):
|
|
"""Assert that a tag in `content` has a certain value in a certain attribute."""
|
|
regex = r"""<{tag} [^>]*\b{attname}=['"]([\w\d\- ]+)['"][^>]*>""".format(tag=tag, attname=attname)
|
|
match = re.search(regex, content)
|
|
self.assertTrue(match, "Couldn't find desired tag '%s' with attr '%s' in %r" % (tag, attname, content))
|
|
attvalues = match.group(1).split()
|
|
self.assertIn(value, attvalues)
|
|
|
|
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()
|
|
|
|
|
|
@attr('shard_1')
|
|
class I18nTestCase(BaseI18nTestCase):
|
|
"""
|
|
Tests for i18n
|
|
"""
|
|
def test_default_is_en(self):
|
|
self.release_languages('fr')
|
|
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")
|
|
|
|
def test_esperanto(self):
|
|
self.release_languages('fr, eo')
|
|
response = self.client.get('/', HTTP_ACCEPT_LANGUAGE='eo')
|
|
self.assert_tag_has_attr(response.content, "html", "lang", "eo")
|
|
self.assertEqual(response['Content-Language'], 'eo')
|
|
self.assert_tag_has_attr(response.content, "body", "class", "lang_eo")
|
|
|
|
def test_switching_languages_bidi(self):
|
|
self.release_languages('ar, eo')
|
|
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")
|
|
|
|
|
|
@attr('shard_1')
|
|
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')
|
|
|
|
# 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'
|
|
response = self.client.get('/', HTTP_ACCEPT_LANGUAGE='fa-ir')
|
|
self.assert_tag_has_attr(response.content, "html", "lang", "fa")
|
|
|
|
# Now try to access with dark lang
|
|
response = self.client.get('/?preview-lang=fa-ir')
|
|
self.assert_tag_has_attr(response.content, "html", "lang", "fa-ir")
|
|
|
|
def test_preview_lang(self):
|
|
# Regression test; LOC-87
|
|
self.release_languages('es-419')
|
|
site_lang = settings.LANGUAGE_CODE
|
|
# Visit the front page; verify we see site default lang
|
|
response = self.client.get('/')
|
|
self.assert_tag_has_attr(response.content, "html", "lang", site_lang)
|
|
|
|
# Verify we can switch language using the preview-lang query param
|
|
response = self.client.get('/?preview-lang=eo')
|
|
self.assert_tag_has_attr(response.content, "html", "lang", "eo")
|
|
# We should be able to see released languages using preview-lang, too
|
|
response = self.client.get('/?preview-lang=es-419')
|
|
self.assert_tag_has_attr(response.content, "html", "lang", "es-419")
|
|
|
|
# Clearing the language should go back to site default
|
|
response = self.client.get('/?clear-lang')
|
|
self.assert_tag_has_attr(response.content, "html", "lang", site_lang)
|
|
|
|
|
|
@attr('shard_1')
|
|
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()
|
|
# Create one user and save it to the database
|
|
email = 'test@edx.org'
|
|
pwd = 'test_password'
|
|
self.user = UserFactory.build(username='test', email=email)
|
|
self.user.set_password(pwd)
|
|
self.user.save()
|
|
|
|
# Create a registration for the user
|
|
RegistrationFactory(user=self.user)
|
|
|
|
# Create a profile for the user
|
|
UserProfileFactory(user=self.user)
|
|
|
|
# Create the test client
|
|
self.client = Client()
|
|
|
|
# Get the login url & log in our user
|
|
try:
|
|
login_url = reverse('login_post')
|
|
except NoReverseMatch:
|
|
login_url = reverse('login')
|
|
self.client.post(login_url, {'email': email, 'password': pwd})
|
|
|
|
# Url and site lang vars for tests to use
|
|
self.url = reverse('dashboard')
|
|
self.site_lang = settings.LANGUAGE_CODE
|
|
|
|
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
|
|
set_user_preference(self.user, LANGUAGE_KEY, 'ar')
|
|
# 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
|
|
set_user_preference(self.user, LANGUAGE_KEY, 'es-419')
|
|
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
|
|
set_user_preference(self.user, LANGUAGE_KEY, 'ar')
|
|
# Verify preview-lang takes precedence
|
|
response = self.client.get('{}?preview-lang=eo'.format(self.url))
|
|
self.assert_tag_has_attr(response.content, "html", "lang", 'eo')
|
|
# 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")
|
|
|
|
# Clearing language must set language back to preference language
|
|
response = self.client.get('{}?clear-lang'.format(self.url))
|
|
self.assert_tag_has_attr(response.content, "html", "lang", 'ar')
|