WL-272
This commit is contained in:
@@ -76,7 +76,8 @@
|
||||
"PREVIEW_LMS_BASE": "localhost:8003",
|
||||
"ALLOW_ALL_ADVANCED_COMPONENTS": true,
|
||||
"ENABLE_CONTENT_LIBRARIES": true,
|
||||
"ENABLE_SPECIAL_EXAMS": true
|
||||
"ENABLE_SPECIAL_EXAMS": true,
|
||||
"SHOW_LANGUAGE_SELECTOR": true
|
||||
},
|
||||
"FEEDBACK_SUBMISSION_EMAIL": "",
|
||||
"GITHUB_REPO_ROOT": "** OVERRIDDEN **",
|
||||
|
||||
@@ -190,6 +190,9 @@ FEATURES = {
|
||||
'ENABLE_SPECIAL_EXAMS': False,
|
||||
|
||||
'ORGANIZATIONS_APP': False,
|
||||
|
||||
# Show Language selector
|
||||
'SHOW_LANGUAGE_SELECTOR': False,
|
||||
}
|
||||
|
||||
ENABLE_JASMINE = False
|
||||
@@ -328,6 +331,9 @@ MIDDLEWARE_CLASSES = (
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'track.middleware.TrackMiddleware',
|
||||
|
||||
# This is used to set or update the user language preferences.
|
||||
'lang_pref.middleware.LanguagePreferenceMiddleware',
|
||||
|
||||
# Allows us to dark-launch particular languages
|
||||
'dark_lang.middleware.DarkLangMiddleware',
|
||||
|
||||
@@ -1111,6 +1117,8 @@ OAUTH_OIDC_ISSUER = 'https://www.example.com/oauth2'
|
||||
# 5 minute expiration time for JWT id tokens issued for external API requests.
|
||||
OAUTH_ID_TOKEN_EXPIRATION = 5 * 60
|
||||
|
||||
USERNAME_PATTERN = r'(?P<username>[\w.@+-]+)'
|
||||
|
||||
# Partner support link for CMS footer
|
||||
PARTNER_SUPPORT_EMAIL = ''
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
"ova": 'js/vendor/ova/ova',
|
||||
"catch": 'js/vendor/ova/catch/js/catch',
|
||||
"handlebars": 'js/vendor/ova/catch/js/handlebars-1.1.2',
|
||||
"lang_edx": "js/src/lang_edx",
|
||||
// end of Annotation tool files
|
||||
|
||||
// externally hosted files
|
||||
@@ -196,6 +197,9 @@
|
||||
"tinymce": {
|
||||
exports: "tinymce"
|
||||
},
|
||||
"lang_edx": {
|
||||
deps: ["jquery"]
|
||||
},
|
||||
"mathjax": {
|
||||
exports: "MathJax",
|
||||
init: function() {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
define(['js/base', 'coffee/src/main', 'js/src/logger', 'datepair', 'accessibility',
|
||||
'ieshim', 'tooltip_manager']);
|
||||
'ieshim', 'tooltip_manager', 'lang_edx']);
|
||||
|
||||
@@ -43,8 +43,19 @@
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.user-language-selector {
|
||||
width: 120px;
|
||||
display: inline-block;
|
||||
margin: 0 10px 0 5px;
|
||||
vertical-align: sub;
|
||||
|
||||
.language-selector {
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-account {
|
||||
width: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
// basic layout - nav items
|
||||
@@ -208,6 +219,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.settings-language-form {
|
||||
margin-top: 4px;
|
||||
.language-selector {
|
||||
width: 130px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ====================
|
||||
@@ -229,11 +247,11 @@
|
||||
.is-signedin {
|
||||
|
||||
.wrapper-l {
|
||||
width: flex-grid(9,12);
|
||||
width: flex-grid(8,12);
|
||||
}
|
||||
|
||||
.wrapper-r {
|
||||
width: flex-grid(3,12);
|
||||
width: flex-grid(4,12);
|
||||
}
|
||||
|
||||
.branding {
|
||||
@@ -253,11 +271,11 @@
|
||||
.wrapper-header {
|
||||
|
||||
.wrapper-l {
|
||||
width: flex-grid(9,12);
|
||||
width: flex-grid(8,12);
|
||||
}
|
||||
|
||||
.wrapper-r {
|
||||
width: flex-grid(3,12);
|
||||
width: flex-grid(4,12);
|
||||
}
|
||||
|
||||
.branding {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
from contentstore.context_processors import doc_url
|
||||
%>
|
||||
<%page args="online_help_token"/>
|
||||
|
||||
<div class="wrapper-header wrapper" id="view-top">
|
||||
<header class="primary" role="banner">
|
||||
|
||||
@@ -188,6 +187,32 @@
|
||||
</div>
|
||||
|
||||
<div class="wrapper wrapper-r">
|
||||
% if static.show_language_selector():
|
||||
<% languages = static.get_released_languages() %>
|
||||
% if len(languages) > 1:
|
||||
<nav class="user-language-selector">
|
||||
<form action="/i18n/setlang/" method="post" class="settings-language-form" id="language-settings-form">
|
||||
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="${csrf_token}">
|
||||
% if user.is_authenticated():
|
||||
<input title="preference api" type="hidden" id="preference-api-url" class="url-endpoint" value="${reverse('preferences_api', kwargs={'username': user.username})}" data-user-is-authenticated="true">
|
||||
% else:
|
||||
<input title="session update url" type="hidden" id="update-session-url" class="url-endpoint" value="${reverse('session_language')}" data-user-is-authenticated="false">
|
||||
% endif
|
||||
<label><span class="sr">${_("Choose Language")}</span>
|
||||
<select class="input select language-selector" id="settings-language-value" name="language">
|
||||
% for language in languages:
|
||||
% if language[0] == LANGUAGE_CODE:
|
||||
<option value="${language[0]}" selected="selected">${language[1]}</option>
|
||||
% else:
|
||||
<option value="${language[0]}" >${language[1]}</option>
|
||||
% endif
|
||||
% endfor
|
||||
</select>
|
||||
</label>
|
||||
</form>
|
||||
</nav>
|
||||
% endif
|
||||
% endif
|
||||
% if user.is_authenticated():
|
||||
<nav class="nav-account nav-is-signedin nav-dd ui-right" aria-label="${_('Account')}">
|
||||
<h2 class="sr">${_("Account Navigation")}</h2>
|
||||
@@ -195,7 +220,6 @@
|
||||
<li class="nav-item nav-account-help">
|
||||
<h3 class="title"><span class="label"><a href="${get_online_help_info(online_help_token)['doc_url']}" title="${_("Contextual Online Help")}" target="_blank">${_("Help")}</a></span></h3>
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-account-user">
|
||||
<h3 class="title"><span class="label"><span class="label-prefix sr">${_("Currently signed in as:")}</span><span class="account-username" title="${ user.username }">${ user.username }</span></span> <i class="icon fa fa-caret-down ui-toggle-dd"></i></h3>
|
||||
|
||||
|
||||
@@ -52,6 +52,14 @@ urlpatterns = patterns(
|
||||
url(r'^heartbeat$', include('heartbeat.urls')),
|
||||
|
||||
url(r'^user_api/', include('openedx.core.djangoapps.user_api.legacy_urls')),
|
||||
|
||||
url(r'^i18n/', include('django.conf.urls.i18n')),
|
||||
|
||||
# User API endpoints
|
||||
url(r'^api/user/', include('openedx.core.djangoapps.user_api.urls')),
|
||||
|
||||
# Update session view
|
||||
url(r'^lang_pref/session_language', 'lang_pref.views.update_session_language', name='session_language'),
|
||||
)
|
||||
|
||||
# User creation and updating views
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
Middleware for Language Preferences
|
||||
"""
|
||||
|
||||
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
|
||||
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference, delete_user_preference
|
||||
from lang_pref import LANGUAGE_KEY
|
||||
from django.utils.translation import LANGUAGE_SESSION_KEY
|
||||
from django.utils.translation.trans_real import parse_accept_lang_header
|
||||
@@ -21,20 +21,26 @@ class LanguagePreferenceMiddleware(object):
|
||||
"""
|
||||
If a user's UserPreference contains a language preference, use the user's preference.
|
||||
"""
|
||||
languages = released_languages()
|
||||
system_released_languages = [seq[0] for seq in languages]
|
||||
|
||||
# If the user is logged in, check for their language preference
|
||||
if request.user.is_authenticated():
|
||||
# Get the user's language preference
|
||||
user_pref = get_user_preference(request.user, LANGUAGE_KEY)
|
||||
# Set it to the LANGUAGE_SESSION_KEY (Django-specific session setting governing language pref)
|
||||
if user_pref:
|
||||
request.session[LANGUAGE_SESSION_KEY] = user_pref
|
||||
else:
|
||||
# Setting the session language to the browser language, if it is supported.
|
||||
preferred_language = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
|
||||
lang_headers = [seq[0] for seq in parse_accept_lang_header(preferred_language)]
|
||||
languages = released_languages()
|
||||
for browser_lang in lang_headers:
|
||||
if browser_lang in [seq[0] for seq in languages]:
|
||||
if request.session.get(LANGUAGE_SESSION_KEY, None) != browser_lang:
|
||||
request.session[LANGUAGE_SESSION_KEY] = unicode(browser_lang)
|
||||
break
|
||||
if user_pref in system_released_languages:
|
||||
request.session[LANGUAGE_SESSION_KEY] = user_pref
|
||||
else:
|
||||
delete_user_preference(request.user, LANGUAGE_KEY)
|
||||
else:
|
||||
preferred_language = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
|
||||
lang_headers = [seq[0] for seq in parse_accept_lang_header(preferred_language)]
|
||||
|
||||
# Setting the session language to the browser language, if it is supported.
|
||||
for browser_lang in lang_headers:
|
||||
if browser_lang in system_released_languages:
|
||||
if request.session.get(LANGUAGE_SESSION_KEY, None) is None:
|
||||
request.session[LANGUAGE_SESSION_KEY] = unicode(browser_lang)
|
||||
break
|
||||
|
||||
@@ -7,6 +7,7 @@ from lang_pref.middleware import LanguagePreferenceMiddleware
|
||||
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference, get_user_preference
|
||||
from lang_pref import LANGUAGE_KEY
|
||||
from student.tests.factories import UserFactory
|
||||
from student.tests.factories import AnonymousUserFactory
|
||||
import mock
|
||||
|
||||
|
||||
@@ -20,6 +21,7 @@ class TestUserPreferenceMiddleware(TestCase):
|
||||
self.middleware = LanguagePreferenceMiddleware()
|
||||
self.session_middleware = SessionMiddleware()
|
||||
self.user = UserFactory.create()
|
||||
self.anonymous_user = AnonymousUserFactory()
|
||||
self.request = RequestFactory().get('/somewhere')
|
||||
self.request.user = self.user
|
||||
self.request.META['HTTP_ACCEPT_LANGUAGE'] = 'ar;q=1.0' # pylint: disable=no-member
|
||||
@@ -30,12 +32,16 @@ class TestUserPreferenceMiddleware(TestCase):
|
||||
self.middleware.process_request(self.request)
|
||||
self.assertNotIn(LANGUAGE_SESSION_KEY, self.request.session)
|
||||
|
||||
@mock.patch('lang_pref.middleware.released_languages', mock.Mock(return_value=[('eo', 'esperanto')]))
|
||||
def test_language_in_user_prefs(self):
|
||||
# language set in the user preferences and not the session
|
||||
set_user_preference(self.user, LANGUAGE_KEY, 'eo')
|
||||
self.middleware.process_request(self.request)
|
||||
self.assertEquals(self.request.session[LANGUAGE_SESSION_KEY], 'eo')
|
||||
|
||||
@mock.patch('lang_pref.middleware.released_languages', mock.Mock(
|
||||
return_value=[('en', 'english'), ('eo', 'esperanto')]
|
||||
))
|
||||
def test_language_in_session(self):
|
||||
# language set in both the user preferences and session,
|
||||
# preference should get precedence. The session will hold the last value,
|
||||
@@ -53,16 +59,29 @@ class TestUserPreferenceMiddleware(TestCase):
|
||||
mock.Mock(return_value=[('eo', 'dummy Esperanto'), ('ar', 'arabic')]))
|
||||
def test_supported_browser_language_in_session(self):
|
||||
"""
|
||||
test: browser language should be set in user preferences if it is supported by system.
|
||||
test: browser language should be set in user session if it is supported by system for unauthenticated user.
|
||||
"""
|
||||
self.assertEquals(get_user_preference(self.request.user, LANGUAGE_KEY), None)
|
||||
self.request.user = self.anonymous_user
|
||||
self.middleware.process_request(self.request)
|
||||
self.assertEqual(self.request.session[LANGUAGE_SESSION_KEY], 'ar') # pylint: disable=no-member
|
||||
|
||||
@mock.patch('lang_pref.middleware.released_languages', mock.Mock(return_value=[('en', 'english')]))
|
||||
def test_browser_language_not_be_in_session(self):
|
||||
"""
|
||||
test: browser language should not be set in user preferences if it is not supported by system.
|
||||
test: browser language should not be set in user session if it is not supported by system.
|
||||
"""
|
||||
self.request.user = self.anonymous_user
|
||||
self.middleware.process_request(self.request)
|
||||
self.assertNotEqual(self.request.session.get(LANGUAGE_SESSION_KEY), 'ar') # pylint: disable=no-member
|
||||
|
||||
@mock.patch('lang_pref.middleware.released_languages', mock.Mock(
|
||||
return_value=[('en', 'english'), ('ar', 'arabic')]
|
||||
))
|
||||
def test_delete_user_lang_preference_not_supported_by_system(self):
|
||||
"""
|
||||
test: user preferred language has been removed from user preferences model if it is not supported by system
|
||||
for authenticated users.
|
||||
"""
|
||||
set_user_preference(self.user, LANGUAGE_KEY, 'eo')
|
||||
self.middleware.process_request(self.request)
|
||||
self.assertEqual(get_user_preference(self.request.user, LANGUAGE_KEY), None)
|
||||
|
||||
38
common/djangoapps/lang_pref/tests/test_views.py
Normal file
38
common/djangoapps/lang_pref/tests/test_views.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
Tests: lang pref views
|
||||
"""
|
||||
import json
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
from django.core.urlresolvers import reverse
|
||||
from student.tests.factories import UserFactory
|
||||
from django.utils.translation import LANGUAGE_SESSION_KEY
|
||||
from django.contrib.sessions.middleware import SessionMiddleware
|
||||
from django.utils.translation import get_language
|
||||
|
||||
|
||||
class TestLangPrefView(TestCase):
|
||||
"""
|
||||
Language preference view tests.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestLangPrefView, self).setUp()
|
||||
self.session_middleware = SessionMiddleware()
|
||||
self.user = UserFactory.create()
|
||||
self.request = RequestFactory().get('/somewhere')
|
||||
self.request.user = self.user
|
||||
self.session_middleware.process_request(self.request)
|
||||
|
||||
def test_language_session_update(self):
|
||||
# test language session updating correctly.
|
||||
self.request.session[LANGUAGE_SESSION_KEY] = 'ar' # pylint: disable=no-member
|
||||
response = self.client.patch(reverse("session_language"), json.dumps({'pref-lang': 'eo'}))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.client.get('/')
|
||||
self.assertEquals(get_language(), 'eo')
|
||||
|
||||
response = self.client.patch(reverse("session_language"), json.dumps({'pref-lang': 'en'}))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.client.get('/')
|
||||
self.assertEquals(get_language(), 'en')
|
||||
22
common/djangoapps/lang_pref/views.py
Normal file
22
common/djangoapps/lang_pref/views.py
Normal file
@@ -0,0 +1,22 @@
|
||||
"""
|
||||
Language Preference Views
|
||||
"""
|
||||
import json
|
||||
from django.conf import settings
|
||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||
from django.utils.translation import LANGUAGE_SESSION_KEY
|
||||
from lang_pref import LANGUAGE_KEY
|
||||
from django.http import HttpResponse
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
def update_session_language(request):
|
||||
"""
|
||||
Update the language session key.
|
||||
"""
|
||||
if request.method == 'PATCH':
|
||||
data = json.loads(request.body)
|
||||
language = data.get(LANGUAGE_KEY, settings.LANGUAGE_CODE)
|
||||
if request.session.get(LANGUAGE_SESSION_KEY, None) != language:
|
||||
request.session[LANGUAGE_SESSION_KEY] = unicode(language)
|
||||
return HttpResponse(200)
|
||||
@@ -6,6 +6,7 @@ from mako.exceptions import TemplateLookupException
|
||||
|
||||
from openedx.core.djangoapps.theming.helpers import get_page_title_breadcrumbs, get_value, get_template_path, get_themed_template_path, is_request_in_themed_site
|
||||
from certificates.api import get_asset_url_by_slug
|
||||
from lang_pref.api import released_languages
|
||||
%>
|
||||
|
||||
<%def name='url(file, raw=False)'><%
|
||||
@@ -132,3 +133,7 @@ else:
|
||||
<%def name="show_language_selector()"><%
|
||||
return settings.FEATURES.get('SHOW_LANGUAGE_SELECTOR', False)
|
||||
%></%def>
|
||||
|
||||
<%def name="get_released_languages()"><%
|
||||
return released_languages()
|
||||
%></%def>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<form action="/i18n/setlang/" method="post" class="settings-language-form" id="language-settings-form">
|
||||
<input title="preference api" type="hidden" id="preference-api-url" value="/api/user/v1/preferences/test1/">
|
||||
<input title="preference api" class="url-endpoint" type="hidden" id="preference-api-url" value="/api/user/v1/preferences/test1/" data-user-is-authenticated="true">
|
||||
<label><span class="sr">Choose Language</span>
|
||||
<select class="input select" id="settings-language-value" name="language">
|
||||
<option value="en" selected="selected">English</option>
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
var edx = edx || {},
|
||||
Language = (function() {
|
||||
var Language = (function() {
|
||||
'use strict';
|
||||
var preference_api_url,
|
||||
settings_language_selector,
|
||||
var settings_language_selector,
|
||||
self = null;
|
||||
return {
|
||||
init: function() {
|
||||
preference_api_url = $('#preference-api-url').val();
|
||||
settings_language_selector = $('#settings-language-value');
|
||||
self = this;
|
||||
this.listenForLanguagePreferenceChange();
|
||||
@@ -18,32 +15,49 @@ var edx = edx || {},
|
||||
*/
|
||||
listenForLanguagePreferenceChange: function() {
|
||||
settings_language_selector.change(function(event) {
|
||||
var language = this.value;
|
||||
var language = this.value,
|
||||
url = $('.url-endpoint').val(),
|
||||
is_user_authenticated = JSON.parse($('.url-endpoint').data('user-is-authenticated'));
|
||||
event.preventDefault();
|
||||
$.ajax({
|
||||
type: 'PATCH',
|
||||
data: JSON.stringify({'pref-lang': language}) ,
|
||||
url: preference_api_url,
|
||||
dataType: 'json',
|
||||
contentType: "application/merge-patch+json",
|
||||
beforeSend: function (xhr) {
|
||||
xhr.setRequestHeader("X-CSRFToken", $('#csrf_token').val());
|
||||
self.submitAjaxRequest(language, url, function() {
|
||||
if (is_user_authenticated) {
|
||||
// User language preference has been set successfully
|
||||
// Now submit the form in success callback.
|
||||
$('#language-settings-form').submit();
|
||||
} else {
|
||||
self.refresh();
|
||||
}
|
||||
}).done(function () {
|
||||
// User language preference has been set successfully
|
||||
// Now submit the form in success callback.
|
||||
$("#language-settings-form").submit();
|
||||
}).fail(function() {
|
||||
self.refresh();
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Send an ajax request to set user language preferences.
|
||||
*/
|
||||
submitAjaxRequest: function(language, url, callback) {
|
||||
|
||||
$.ajax({
|
||||
type: 'PATCH',
|
||||
data: JSON.stringify({'pref-lang': language}) ,
|
||||
url: url,
|
||||
dataType: 'json',
|
||||
contentType: 'application/merge-patch+json',
|
||||
notifyOnError: false,
|
||||
beforeSend: function (xhr) {
|
||||
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
|
||||
}
|
||||
}).done(function () {
|
||||
callback();
|
||||
}).fail(function() {
|
||||
self.refresh();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* refresh the page.
|
||||
*/
|
||||
refresh: function () {
|
||||
// reloading the page so we can get the latest state of realsesd languages from model
|
||||
// reloading the page so we can get the latest state of released languages from model
|
||||
location.reload();
|
||||
}
|
||||
|
||||
|
||||
@@ -225,6 +225,17 @@ class DashboardPage(PageObject):
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
def language_selector(self):
|
||||
"""
|
||||
return language selector
|
||||
"""
|
||||
self.wait_for_element_visibility(
|
||||
'#settings-language-value',
|
||||
'Language selector element is available'
|
||||
)
|
||||
return self.q(css='#settings-language-value')
|
||||
|
||||
|
||||
class DashboardPageWithPrograms(DashboardPage):
|
||||
"""
|
||||
|
||||
@@ -10,6 +10,11 @@ from ...fixtures.programs import ProgramsFixture
|
||||
from ...pages.studio.auto_auth import AutoAuthPage
|
||||
from ...pages.studio.library import LibraryEditPage
|
||||
from ...pages.studio.index import DashboardPage, DashboardPageWithPrograms
|
||||
from ...pages.lms.account_settings import AccountSettingsPage
|
||||
from ..helpers import (
|
||||
select_option_by_text,
|
||||
get_selected_option_text
|
||||
)
|
||||
|
||||
|
||||
class CreateLibraryTest(WebAppTest):
|
||||
@@ -139,3 +144,37 @@ class DashboardProgramsTabTest(WebAppTest):
|
||||
self.dashboard_page.visit()
|
||||
self.assertFalse(self.dashboard_page.is_programs_tab_present())
|
||||
self.assertFalse(self.dashboard_page.is_new_program_button_present())
|
||||
|
||||
|
||||
class StudioLanguageTest(WebAppTest):
|
||||
""" Test suite for the Studio Language """
|
||||
def setUp(self):
|
||||
super(StudioLanguageTest, self).setUp()
|
||||
self.dashboard_page = DashboardPage(self.browser)
|
||||
self.account_settings = AccountSettingsPage(self.browser)
|
||||
AutoAuthPage(self.browser).visit()
|
||||
|
||||
def test_studio_language_change(self):
|
||||
"""
|
||||
Scenario: Ensure that language selection is working fine.
|
||||
First I go to the user dashboard page in studio. I can see 'English' is selected by default.
|
||||
Then I choose 'Dummy Language' from drop down (at top of the page).
|
||||
Then I visit the student account settings page and I can see the language has been updated to 'Dummy Language'
|
||||
in both drop downs.
|
||||
"""
|
||||
dummy_language = u'Dummy Language (Esperanto)'
|
||||
self.dashboard_page.visit()
|
||||
language_selector = self.dashboard_page.language_selector
|
||||
self.assertEqual(
|
||||
get_selected_option_text(language_selector),
|
||||
u'English'
|
||||
)
|
||||
|
||||
select_option_by_text(language_selector, dummy_language)
|
||||
self.dashboard_page.wait_for_ajax()
|
||||
self.account_settings.visit()
|
||||
self.assertEqual(self.account_settings.value_for_dropdown_field('pref-lang'), dummy_language)
|
||||
self.assertEqual(
|
||||
get_selected_option_text(language_selector),
|
||||
u'Dummy Language (Esperanto)'
|
||||
)
|
||||
|
||||
@@ -365,7 +365,7 @@ FEATURES = {
|
||||
# Enable LTI Provider feature.
|
||||
'ENABLE_LTI_PROVIDER': False,
|
||||
|
||||
# Show LMS Language selector
|
||||
# Show Language selector.
|
||||
'SHOW_LANGUAGE_SELECTOR': False,
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,10 @@ header.global {
|
||||
margin: 0;
|
||||
|
||||
.settings-language-form {
|
||||
margin-top: 4px;
|
||||
margin: 4px;
|
||||
.language-selector {
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
> .primary {
|
||||
|
||||
@@ -14,7 +14,6 @@ from openedx.core.djangoapps.user_api.accounts.image_helpers import get_profile_
|
||||
from branding import api as branding_api
|
||||
# app that handles site status messages
|
||||
from status.status import get_site_status_msg
|
||||
from lang_pref.api import released_languages
|
||||
%>
|
||||
|
||||
## Provide a hook for themes to inject branding on top.
|
||||
@@ -38,7 +37,6 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
</div>
|
||||
% endif
|
||||
</%block>
|
||||
|
||||
<header id="global-navigation" class="global ${"slim" if course else ""}" >
|
||||
<nav class="nav-wrapper" aria-label="${_('Global')}">
|
||||
<h1 class="logo">
|
||||
@@ -79,28 +77,6 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
</%block>
|
||||
</ol>
|
||||
<ol class="user">
|
||||
% if static.show_language_selector():
|
||||
<% languages = released_languages() %>
|
||||
% if len(languages) > 1:
|
||||
<li class="primary">
|
||||
<form action="/i18n/setlang/" method="post" class="settings-language-form" id="language-settings-form">
|
||||
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="${csrf_token}">
|
||||
<input title="preference api" type="hidden" id="preference-api-url" value="${reverse('preferences_api', kwargs={'username': user.username})}">
|
||||
<label><span class="sr">${_("Choose Language")}</span>
|
||||
<select class="input select" id="settings-language-value" name="language">
|
||||
% for language in languages:
|
||||
% if language[0] == LANGUAGE_CODE:
|
||||
<option value="${language[0]}" selected="selected">${language[1]}</option>
|
||||
% else:
|
||||
<option value="${language[0]}" >${language[1]}</option>
|
||||
% endif
|
||||
% endfor
|
||||
</select>
|
||||
</label>
|
||||
</form>
|
||||
</li>
|
||||
% endif
|
||||
% endif
|
||||
<li class="primary">
|
||||
<a href="${reverse('dashboard')}" class="user-link">
|
||||
<span class="sr">${_("Dashboard for:")}</span>
|
||||
@@ -186,7 +162,35 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
</%block>
|
||||
</ol>
|
||||
% endif
|
||||
</nav>
|
||||
% if static.show_language_selector():
|
||||
<% languages = static.get_released_languages() %>
|
||||
% if len(languages) > 1:
|
||||
<ol class="user">
|
||||
<li class="primary">
|
||||
<form action="/i18n/setlang/" method="post" class="settings-language-form" id="language-settings-form">
|
||||
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="${csrf_token}">
|
||||
% if user.is_authenticated():
|
||||
<input title="preference api" type="hidden" class="url-endpoint" value="${reverse('preferences_api', kwargs={'username': user.username})}" data-user-is-authenticated="true">
|
||||
% else:
|
||||
<input title="session update url" type="hidden" class="url-endpoint" value="${reverse('session_language')}" data-user-is-authenticated="false">
|
||||
% endif
|
||||
<label><span class="sr">${_("Choose Language")}</span>
|
||||
<select class="input select language-selector" id="settings-language-value" name="language">
|
||||
% for language in languages:
|
||||
% if language[0] == LANGUAGE_CODE:
|
||||
<option value="${language[0]}" selected="selected">${language[1]}</option>
|
||||
% else:
|
||||
<option value="${language[0]}" >${language[1]}</option>
|
||||
% endif
|
||||
% endfor
|
||||
</select>
|
||||
</label>
|
||||
</form>
|
||||
</li>
|
||||
</ol>
|
||||
% endif
|
||||
% endif
|
||||
</nav>
|
||||
</header>
|
||||
% if course:
|
||||
<!--[if lte IE 9]>
|
||||
|
||||
@@ -103,6 +103,9 @@ urlpatterns = (
|
||||
url(r'^rss_proxy/', include('rss_proxy.urls', namespace='rss_proxy')),
|
||||
url(r'^api/organizations/', include('organizations.urls', namespace='organizations')),
|
||||
|
||||
# Update session view
|
||||
url(r'^lang_pref/session_language', 'lang_pref.views.update_session_language', name='session_language'),
|
||||
|
||||
# Multiple course modes and identity verification
|
||||
# TODO Namespace these!
|
||||
url(r'^course_modes/', include('course_modes.urls')),
|
||||
|
||||
Reference in New Issue
Block a user