Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
3deb3a3c
Commit
3deb3a3c
authored
May 01, 2017
by
Calen Pennington
Committed by
GitHub
May 01, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #14977 from cpennington/cale/fix-learner-542
Cale/fix learner 542
parents
09593998
2ca367a1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
191 additions
and
100 deletions
+191
-100
cms/envs/aws.py
+2
-0
cms/envs/common.py
+2
-0
common/djangoapps/student/cookies.py
+3
-3
lms/djangoapps/ccx/tests/test_field_override_performance.py
+27
-27
lms/djangoapps/courseware/tests/test_course_info.py
+2
-2
lms/djangoapps/courseware/tests/test_i18n.py
+14
-10
lms/djangoapps/courseware/tests/test_views.py
+5
-5
lms/djangoapps/django_comment_client/base/tests.py
+4
-4
lms/envs/aws.py
+2
-0
lms/envs/common.py
+2
-0
lms/envs/devstack_docker.py
+1
-0
openedx/core/djangoapps/bookmarks/tests/test_views.py
+1
-1
openedx/core/djangoapps/lang_pref/__init__.py
+4
-0
openedx/core/djangoapps/lang_pref/middleware.py
+46
-12
openedx/core/djangoapps/lang_pref/tests/test_middleware.py
+0
-0
openedx/core/djangoapps/lang_pref/views.py
+9
-2
openedx/core/djangoapps/user_api/accounts/tests/test_views.py
+7
-7
openedx/core/djangoapps/user_api/errors.py
+2
-0
openedx/core/djangoapps/user_api/helpers.py
+16
-2
openedx/core/djangoapps/user_api/preferences/api.py
+19
-9
openedx/core/djangoapps/user_api/preferences/tests/test_api.py
+2
-3
openedx/core/djangoapps/user_api/serializers.py
+1
-6
openedx/core/djangoapps/user_api/tests/test_helpers.py
+17
-4
openedx/core/djangoapps/user_api/views.py
+3
-3
No files found.
cms/envs/aws.py
View file @
3deb3a3c
...
@@ -221,6 +221,8 @@ GIT_REPO_EXPORT_DIR = ENV_TOKENS.get('GIT_REPO_EXPORT_DIR', '/edx/var/edxapp/exp
...
@@ -221,6 +221,8 @@ GIT_REPO_EXPORT_DIR = ENV_TOKENS.get('GIT_REPO_EXPORT_DIR', '/edx/var/edxapp/exp
# Translation overrides
# Translation overrides
LANGUAGES
=
ENV_TOKENS
.
get
(
'LANGUAGES'
,
LANGUAGES
)
LANGUAGES
=
ENV_TOKENS
.
get
(
'LANGUAGES'
,
LANGUAGES
)
LANGUAGE_CODE
=
ENV_TOKENS
.
get
(
'LANGUAGE_CODE'
,
LANGUAGE_CODE
)
LANGUAGE_CODE
=
ENV_TOKENS
.
get
(
'LANGUAGE_CODE'
,
LANGUAGE_CODE
)
LANGUAGE_COOKIE
=
ENV_TOKENS
.
get
(
'LANGUAGE_COOKIE'
,
LANGUAGE_COOKIE
)
USE_I18N
=
ENV_TOKENS
.
get
(
'USE_I18N'
,
USE_I18N
)
USE_I18N
=
ENV_TOKENS
.
get
(
'USE_I18N'
,
USE_I18N
)
ENV_FEATURES
=
ENV_TOKENS
.
get
(
'FEATURES'
,
{})
ENV_FEATURES
=
ENV_TOKENS
.
get
(
'FEATURES'
,
{})
...
...
cms/envs/common.py
View file @
3deb3a3c
...
@@ -547,6 +547,8 @@ TIME_ZONE = 'America/New_York' # http://en.wikipedia.org/wiki/List_of_tz_zones_
...
@@ -547,6 +547,8 @@ TIME_ZONE = 'America/New_York' # http://en.wikipedia.org/wiki/List_of_tz_zones_
LANGUAGE_CODE
=
'en'
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE
=
'en'
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGES_BIDI
=
lms
.
envs
.
common
.
LANGUAGES_BIDI
LANGUAGES_BIDI
=
lms
.
envs
.
common
.
LANGUAGES_BIDI
LANGUAGE_COOKIE
=
lms
.
envs
.
common
.
LANGUAGE_COOKIE
LANGUAGES
=
lms
.
envs
.
common
.
LANGUAGES
LANGUAGES
=
lms
.
envs
.
common
.
LANGUAGES
LANGUAGE_DICT
=
dict
(
LANGUAGES
)
LANGUAGE_DICT
=
dict
(
LANGUAGES
)
...
...
common/djangoapps/student/cookies.py
View file @
3deb3a3c
...
@@ -17,7 +17,7 @@ from student.models import CourseEnrollment
...
@@ -17,7 +17,7 @@ from student.models import CourseEnrollment
CREATE_LOGON_COOKIE
=
Signal
(
providing_args
=
[
'user'
,
'response'
])
CREATE_LOGON_COOKIE
=
Signal
(
providing_args
=
[
'user'
,
'response'
])
def
_get
_cookie_settings
(
request
):
def
standard
_cookie_settings
(
request
):
""" Returns the common cookie settings (e.g. expiration time). """
""" Returns the common cookie settings (e.g. expiration time). """
if
request
.
session
.
get_expire_at_browser_close
():
if
request
.
session
.
get_expire_at_browser_close
():
...
@@ -73,7 +73,7 @@ def set_logged_in_cookies(request, response, user):
...
@@ -73,7 +73,7 @@ def set_logged_in_cookies(request, response, user):
HttpResponse
HttpResponse
"""
"""
cookie_settings
=
_get
_cookie_settings
(
request
)
cookie_settings
=
standard
_cookie_settings
(
request
)
# Backwards compatibility: set the cookie indicating that the user
# Backwards compatibility: set the cookie indicating that the user
# is logged in. This is just a boolean value, so it's not very useful.
# is logged in. This is just a boolean value, so it's not very useful.
...
@@ -96,7 +96,7 @@ def set_logged_in_cookies(request, response, user):
...
@@ -96,7 +96,7 @@ def set_logged_in_cookies(request, response, user):
def
set_user_info_cookie
(
response
,
request
):
def
set_user_info_cookie
(
response
,
request
):
""" Sets the user info cookie on the response. """
""" Sets the user info cookie on the response. """
cookie_settings
=
_get
_cookie_settings
(
request
)
cookie_settings
=
standard
_cookie_settings
(
request
)
# In production, TLS should be enabled so that this cookie is encrypted
# In production, TLS should be enabled so that this cookie is encrypted
# when we send it. We also need to set "secure" to True so that the browser
# when we send it. We also need to set "secure" to True so that the browser
...
...
lms/djangoapps/ccx/tests/test_field_override_performance.py
View file @
3deb3a3c
...
@@ -231,18 +231,18 @@ class TestFieldOverrideMongoPerformance(FieldOverridePerformanceTestCase):
...
@@ -231,18 +231,18 @@ class TestFieldOverrideMongoPerformance(FieldOverridePerformanceTestCase):
# # of sql queries to default,
# # of sql queries to default,
# # of mongo queries,
# # of mongo queries,
# )
# )
(
'no_overrides'
,
1
,
True
,
False
):
(
2
5
,
1
),
(
'no_overrides'
,
1
,
True
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
2
,
True
,
False
):
(
2
5
,
1
),
(
'no_overrides'
,
2
,
True
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
3
,
True
,
False
):
(
2
5
,
1
),
(
'no_overrides'
,
3
,
True
,
False
):
(
2
3
,
1
),
(
'ccx'
,
1
,
True
,
False
):
(
2
5
,
1
),
(
'ccx'
,
1
,
True
,
False
):
(
2
3
,
1
),
(
'ccx'
,
2
,
True
,
False
):
(
2
5
,
1
),
(
'ccx'
,
2
,
True
,
False
):
(
2
3
,
1
),
(
'ccx'
,
3
,
True
,
False
):
(
2
5
,
1
),
(
'ccx'
,
3
,
True
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
1
,
False
,
False
):
(
2
5
,
1
),
(
'no_overrides'
,
1
,
False
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
2
,
False
,
False
):
(
2
5
,
1
),
(
'no_overrides'
,
2
,
False
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
3
,
False
,
False
):
(
2
5
,
1
),
(
'no_overrides'
,
3
,
False
,
False
):
(
2
3
,
1
),
(
'ccx'
,
1
,
False
,
False
):
(
2
5
,
1
),
(
'ccx'
,
1
,
False
,
False
):
(
2
3
,
1
),
(
'ccx'
,
2
,
False
,
False
):
(
2
5
,
1
),
(
'ccx'
,
2
,
False
,
False
):
(
2
3
,
1
),
(
'ccx'
,
3
,
False
,
False
):
(
2
5
,
1
),
(
'ccx'
,
3
,
False
,
False
):
(
2
3
,
1
),
}
}
...
@@ -254,19 +254,19 @@ class TestFieldOverrideSplitPerformance(FieldOverridePerformanceTestCase):
...
@@ -254,19 +254,19 @@ class TestFieldOverrideSplitPerformance(FieldOverridePerformanceTestCase):
__test__
=
True
__test__
=
True
TEST_DATA
=
{
TEST_DATA
=
{
(
'no_overrides'
,
1
,
True
,
False
):
(
2
5
,
3
),
(
'no_overrides'
,
1
,
True
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
2
,
True
,
False
):
(
2
5
,
3
),
(
'no_overrides'
,
2
,
True
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
3
,
True
,
False
):
(
2
5
,
3
),
(
'no_overrides'
,
3
,
True
,
False
):
(
2
3
,
3
),
(
'ccx'
,
1
,
True
,
False
):
(
2
5
,
3
),
(
'ccx'
,
1
,
True
,
False
):
(
2
3
,
3
),
(
'ccx'
,
2
,
True
,
False
):
(
2
5
,
3
),
(
'ccx'
,
2
,
True
,
False
):
(
2
3
,
3
),
(
'ccx'
,
3
,
True
,
False
):
(
2
5
,
3
),
(
'ccx'
,
3
,
True
,
False
):
(
2
3
,
3
),
(
'ccx'
,
1
,
True
,
True
):
(
2
6
,
3
),
(
'ccx'
,
1
,
True
,
True
):
(
2
4
,
3
),
(
'ccx'
,
2
,
True
,
True
):
(
2
6
,
3
),
(
'ccx'
,
2
,
True
,
True
):
(
2
4
,
3
),
(
'ccx'
,
3
,
True
,
True
):
(
2
6
,
3
),
(
'ccx'
,
3
,
True
,
True
):
(
2
4
,
3
),
(
'no_overrides'
,
1
,
False
,
False
):
(
2
5
,
3
),
(
'no_overrides'
,
1
,
False
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
2
,
False
,
False
):
(
2
5
,
3
),
(
'no_overrides'
,
2
,
False
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
3
,
False
,
False
):
(
2
5
,
3
),
(
'no_overrides'
,
3
,
False
,
False
):
(
2
3
,
3
),
(
'ccx'
,
1
,
False
,
False
):
(
2
5
,
3
),
(
'ccx'
,
1
,
False
,
False
):
(
2
3
,
3
),
(
'ccx'
,
2
,
False
,
False
):
(
2
5
,
3
),
(
'ccx'
,
2
,
False
,
False
):
(
2
3
,
3
),
(
'ccx'
,
3
,
False
,
False
):
(
2
5
,
3
),
(
'ccx'
,
3
,
False
,
False
):
(
2
3
,
3
),
}
}
lms/djangoapps/courseware/tests/test_course_info.py
View file @
3deb3a3c
...
@@ -367,7 +367,7 @@ class SelfPacedCourseInfoTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
...
@@ -367,7 +367,7 @@ class SelfPacedCourseInfoTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
def
test_num_queries_instructor_paced
(
self
):
def
test_num_queries_instructor_paced
(
self
):
self
.
fetch_course_info_with_queries
(
self
.
instructor_paced_course
,
21
,
4
)
self
.
fetch_course_info_with_queries
(
self
.
instructor_paced_course
,
18
,
4
)
def
test_num_queries_self_paced
(
self
):
def
test_num_queries_self_paced
(
self
):
self
.
fetch_course_info_with_queries
(
self
.
self_paced_course
,
21
,
4
)
self
.
fetch_course_info_with_queries
(
self
.
self_paced_course
,
18
,
4
)
lms/djangoapps/courseware/tests/test_i18n.py
View file @
3deb3a3c
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
Tests i18n in courseware
Tests i18n in courseware
"""
"""
import
json
import
re
import
re
from
django.conf
import
settings
from
django.conf
import
settings
...
@@ -14,8 +15,6 @@ from nose.plugins.attrib import attr
...
@@ -14,8 +15,6 @@ from nose.plugins.attrib import attr
from
openedx.core.djangoapps.dark_lang.models
import
DarkLangConfig
from
openedx.core.djangoapps.dark_lang.models
import
DarkLangConfig
from
openedx.core.djangoapps.lang_pref
import
LANGUAGE_KEY
from
openedx.core.djangoapps.lang_pref
import
LANGUAGE_KEY
from
openedx.core.djangoapps.user_api.preferences.api
import
set_user_preference
from
student.models
import
UserProfile
from
student.tests.factories
import
UserFactory
from
student.tests.factories
import
UserFactory
...
@@ -61,8 +60,7 @@ class BaseI18nTestCase(TestCase):
...
@@ -61,8 +60,7 @@ class BaseI18nTestCase(TestCase):
"""
"""
# Create one user and save it to the database
# Create one user and save it to the database
email
=
'test@edx.org'
email
=
'test@edx.org'
self
.
user
=
UserFactory
.
build
(
username
=
'test'
,
email
=
email
,
password
=
self
.
pwd
)
self
.
user
=
UserFactory
.
create
(
username
=
'test'
,
email
=
email
,
password
=
self
.
pwd
)
self
.
user
.
save
()
def
user_login
(
self
):
def
user_login
(
self
):
"""
"""
...
@@ -119,7 +117,6 @@ class I18nRegressionTests(BaseI18nTestCase):
...
@@ -119,7 +117,6 @@ class I18nRegressionTests(BaseI18nTestCase):
def
test_unreleased_lang_resolution
(
self
):
def
test_unreleased_lang_resolution
(
self
):
# Regression test; LOC-85
# Regression test; LOC-85
UserProfile
.
objects
.
create
(
user
=
self
.
user
)
self
.
release_languages
(
'fa'
)
self
.
release_languages
(
'fa'
)
self
.
user_login
()
self
.
user_login
()
...
@@ -136,7 +133,6 @@ class I18nRegressionTests(BaseI18nTestCase):
...
@@ -136,7 +133,6 @@ class I18nRegressionTests(BaseI18nTestCase):
self
.
assert_tag_has_attr
(
response
.
content
,
"html"
,
"lang"
,
"fa-ir"
)
self
.
assert_tag_has_attr
(
response
.
content
,
"html"
,
"lang"
,
"fa-ir"
)
def
test_preview_lang
(
self
):
def
test_preview_lang
(
self
):
UserProfile
.
objects
.
create
(
user
=
self
.
user
)
self
.
user_login
()
self
.
user_login
()
# Regression test; LOC-87
# Regression test; LOC-87
...
@@ -172,9 +168,17 @@ class I18nLangPrefTests(BaseI18nTestCase):
...
@@ -172,9 +168,17 @@ class I18nLangPrefTests(BaseI18nTestCase):
"""
"""
def
setUp
(
self
):
def
setUp
(
self
):
super
(
I18nLangPrefTests
,
self
)
.
setUp
()
super
(
I18nLangPrefTests
,
self
)
.
setUp
()
UserProfile
.
objects
.
create
(
user
=
self
.
user
)
self
.
user_login
()
self
.
user_login
()
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
)
def
test_lang_preference
(
self
):
def
test_lang_preference
(
self
):
# Regression test; LOC-87
# Regression test; LOC-87
self
.
release_languages
(
'ar, es-419'
)
self
.
release_languages
(
'ar, es-419'
)
...
@@ -184,13 +188,13 @@ class I18nLangPrefTests(BaseI18nTestCase):
...
@@ -184,13 +188,13 @@ class I18nLangPrefTests(BaseI18nTestCase):
self
.
assert_tag_has_attr
(
response
.
content
,
"html"
,
"lang"
,
self
.
site_lang
)
self
.
assert_tag_has_attr
(
response
.
content
,
"html"
,
"lang"
,
self
.
site_lang
)
# Set user language preference
# Set user language preference
se
t_user_preference
(
self
.
user
,
LANGUAGE_KEY
,
'ar'
)
se
lf
.
set_lang_preference
(
'ar'
)
# and verify we now get an ar response
# and verify we now get an ar response
response
=
self
.
client
.
get
(
self
.
url
)
response
=
self
.
client
.
get
(
self
.
url
)
self
.
assert_tag_has_attr
(
response
.
content
,
"html"
,
"lang"
,
'ar'
)
self
.
assert_tag_has_attr
(
response
.
content
,
"html"
,
"lang"
,
'ar'
)
# Verify that switching language preference gives the right language
# Verify that switching language preference gives the right language
se
t_user_preference
(
self
.
user
,
LANGUAGE_KEY
,
'es-419'
)
se
lf
.
set_lang_preference
(
'es-419'
)
response
=
self
.
client
.
get
(
self
.
url
)
response
=
self
.
client
.
get
(
self
.
url
)
self
.
assert_tag_has_attr
(
response
.
content
,
"html"
,
"lang"
,
'es-419'
)
self
.
assert_tag_has_attr
(
response
.
content
,
"html"
,
"lang"
,
'es-419'
)
...
@@ -199,7 +203,7 @@ class I18nLangPrefTests(BaseI18nTestCase):
...
@@ -199,7 +203,7 @@ class I18nLangPrefTests(BaseI18nTestCase):
self
.
release_languages
(
'ar, es-419'
)
self
.
release_languages
(
'ar, es-419'
)
# Set user language preference
# Set user language preference
se
t_user_preference
(
self
.
user
,
LANGUAGE_KEY
,
'ar'
)
se
lf
.
set_lang_preference
(
'ar'
)
# Verify preview-lang takes precedence
# Verify preview-lang takes precedence
self
.
client
.
post
(
self
.
preview_language_url
,
{
'preview_lang'
:
'eo'
,
'set_language'
:
'set_language'
})
self
.
client
.
post
(
self
.
preview_language_url
,
{
'preview_lang'
:
'eo'
,
'set_language'
:
'set_language'
})
response
=
self
.
client
.
get
(
self
.
url
)
response
=
self
.
client
.
get
(
self
.
url
)
...
...
lms/djangoapps/courseware/tests/test_views.py
View file @
3deb3a3c
...
@@ -206,8 +206,8 @@ class IndexQueryTestCase(ModuleStoreTestCase):
...
@@ -206,8 +206,8 @@ class IndexQueryTestCase(ModuleStoreTestCase):
NUM_PROBLEMS
=
20
NUM_PROBLEMS
=
20
@ddt.data
(
@ddt.data
(
(
ModuleStoreEnum
.
Type
.
mongo
,
10
,
14
7
),
(
ModuleStoreEnum
.
Type
.
mongo
,
10
,
14
1
),
(
ModuleStoreEnum
.
Type
.
split
,
4
,
14
7
),
(
ModuleStoreEnum
.
Type
.
split
,
4
,
14
1
),
)
)
@ddt.unpack
@ddt.unpack
def
test_index_query_counts
(
self
,
store_type
,
expected_mongo_query_count
,
expected_mysql_query_count
):
def
test_index_query_counts
(
self
,
store_type
,
expected_mongo_query_count
,
expected_mysql_query_count
):
...
@@ -1408,12 +1408,12 @@ class ProgressPageTests(ModuleStoreTestCase):
...
@@ -1408,12 +1408,12 @@ class ProgressPageTests(ModuleStoreTestCase):
"""Test that query counts remain the same for self-paced and instructor-paced courses."""
"""Test that query counts remain the same for self-paced and instructor-paced courses."""
SelfPacedConfiguration
(
enabled
=
self_paced_enabled
)
.
save
()
SelfPacedConfiguration
(
enabled
=
self_paced_enabled
)
.
save
()
self
.
setup_course
(
self_paced
=
self_paced
)
self
.
setup_course
(
self_paced
=
self_paced
)
with
self
.
assertNumQueries
(
42
),
check_mongo_calls
(
1
):
with
self
.
assertNumQueries
(
39
),
check_mongo_calls
(
1
):
self
.
_get_progress_page
()
self
.
_get_progress_page
()
@ddt.data
(
@ddt.data
(
(
False
,
42
,
28
),
(
False
,
39
,
25
),
(
True
,
3
5
,
24
)
(
True
,
3
2
,
21
)
)
)
@ddt.unpack
@ddt.unpack
def
test_progress_queries
(
self
,
enable_waffle
,
initial
,
subsequent
):
def
test_progress_queries
(
self
,
enable_waffle
,
initial
,
subsequent
):
...
...
lms/djangoapps/django_comment_client/base/tests.py
View file @
3deb3a3c
...
@@ -377,8 +377,8 @@ class ViewsQueryCountTestCase(
...
@@ -377,8 +377,8 @@ class ViewsQueryCountTestCase(
return
inner
return
inner
@ddt.data
(
@ddt.data
(
(
ModuleStoreEnum
.
Type
.
mongo
,
3
,
4
,
3
1
),
(
ModuleStoreEnum
.
Type
.
mongo
,
3
,
4
,
3
0
),
(
ModuleStoreEnum
.
Type
.
split
,
3
,
13
,
3
1
),
(
ModuleStoreEnum
.
Type
.
split
,
3
,
13
,
3
0
),
)
)
@ddt.unpack
@ddt.unpack
@count_queries
@count_queries
...
@@ -386,8 +386,8 @@ class ViewsQueryCountTestCase(
...
@@ -386,8 +386,8 @@ class ViewsQueryCountTestCase(
self
.
create_thread_helper
(
mock_request
)
self
.
create_thread_helper
(
mock_request
)
@ddt.data
(
@ddt.data
(
(
ModuleStoreEnum
.
Type
.
mongo
,
3
,
3
,
2
7
),
(
ModuleStoreEnum
.
Type
.
mongo
,
3
,
3
,
2
6
),
(
ModuleStoreEnum
.
Type
.
split
,
3
,
10
,
2
7
),
(
ModuleStoreEnum
.
Type
.
split
,
3
,
10
,
2
6
),
)
)
@ddt.unpack
@ddt.unpack
@count_queries
@count_queries
...
...
lms/envs/aws.py
View file @
3deb3a3c
...
@@ -315,6 +315,8 @@ TIME_ZONE = ENV_TOKENS.get('TIME_ZONE', TIME_ZONE)
...
@@ -315,6 +315,8 @@ TIME_ZONE = ENV_TOKENS.get('TIME_ZONE', TIME_ZONE)
LANGUAGES
=
ENV_TOKENS
.
get
(
'LANGUAGES'
,
LANGUAGES
)
LANGUAGES
=
ENV_TOKENS
.
get
(
'LANGUAGES'
,
LANGUAGES
)
LANGUAGE_DICT
=
dict
(
LANGUAGES
)
LANGUAGE_DICT
=
dict
(
LANGUAGES
)
LANGUAGE_CODE
=
ENV_TOKENS
.
get
(
'LANGUAGE_CODE'
,
LANGUAGE_CODE
)
LANGUAGE_CODE
=
ENV_TOKENS
.
get
(
'LANGUAGE_CODE'
,
LANGUAGE_CODE
)
LANGUAGE_COOKIE
=
ENV_TOKENS
.
get
(
'LANGUAGE_COOKIE'
,
LANGUAGE_COOKIE
)
USE_I18N
=
ENV_TOKENS
.
get
(
'USE_I18N'
,
USE_I18N
)
USE_I18N
=
ENV_TOKENS
.
get
(
'USE_I18N'
,
USE_I18N
)
# Additional installed apps
# Additional installed apps
...
...
lms/envs/common.py
View file @
3deb3a3c
...
@@ -863,6 +863,8 @@ LANGUAGE_CODE = 'en' # http://www.i18nguy.com/unicode/language-identifiers.html
...
@@ -863,6 +863,8 @@ LANGUAGE_CODE = 'en' # http://www.i18nguy.com/unicode/language-identifiers.html
# these languages display right to left
# these languages display right to left
LANGUAGES_BIDI
=
(
"he"
,
"ar"
,
"fa"
,
"ur"
,
"fa-ir"
,
"rtl"
)
LANGUAGES_BIDI
=
(
"he"
,
"ar"
,
"fa"
,
"ur"
,
"fa-ir"
,
"rtl"
)
LANGUAGE_COOKIE
=
"openedx-language-preference"
# Sourced from http://www.localeplanet.com/icu/ and wikipedia
# Sourced from http://www.localeplanet.com/icu/ and wikipedia
LANGUAGES
=
(
LANGUAGES
=
(
(
'en'
,
u'English'
),
(
'en'
,
u'English'
),
...
...
lms/envs/devstack_docker.py
View file @
3deb3a3c
...
@@ -30,6 +30,7 @@ FEATURES.update({
...
@@ -30,6 +30,7 @@ FEATURES.update({
'ENABLE_COURSEWARE_SEARCH'
:
False
,
'ENABLE_COURSEWARE_SEARCH'
:
False
,
'ENABLE_COURSE_DISCOVERY'
:
False
,
'ENABLE_COURSE_DISCOVERY'
:
False
,
'ENABLE_DASHBOARD_SEARCH'
:
False
,
'ENABLE_DASHBOARD_SEARCH'
:
False
,
'SHOW_LANGUAGE_SELECTOR'
:
True
})
})
ENABLE_MKTG_SITE
=
os
.
environ
.
get
(
'ENABLE_MARKETING_SITE'
,
False
)
ENABLE_MKTG_SITE
=
os
.
environ
.
get
(
'ENABLE_MARKETING_SITE'
,
False
)
...
...
openedx/core/djangoapps/bookmarks/tests/test_views.py
View file @
3deb3a3c
...
@@ -268,7 +268,7 @@ class BookmarksListViewTests(BookmarksViewsTestsBase):
...
@@ -268,7 +268,7 @@ class BookmarksListViewTests(BookmarksViewsTestsBase):
self
.
assertEqual
(
response
.
data
[
'developer_message'
],
u'Parameter usage_id not provided.'
)
self
.
assertEqual
(
response
.
data
[
'developer_message'
],
u'Parameter usage_id not provided.'
)
# Send empty data dictionary.
# Send empty data dictionary.
with
self
.
assertNumQueries
(
8
):
# No queries for bookmark table.
with
self
.
assertNumQueries
(
7
):
# No queries for bookmark table.
response
=
self
.
send_post
(
response
=
self
.
send_post
(
client
=
self
.
client
,
client
=
self
.
client
,
url
=
reverse
(
'bookmarks'
),
url
=
reverse
(
'bookmarks'
),
...
...
openedx/core/djangoapps/lang_pref/__init__.py
View file @
3deb3a3c
...
@@ -4,3 +4,7 @@ Useful information for setting the language preference
...
@@ -4,3 +4,7 @@ Useful information for setting the language preference
# this is the UserPreference key for the user's preferred language
# this is the UserPreference key for the user's preferred language
LANGUAGE_KEY
=
'pref-lang'
LANGUAGE_KEY
=
'pref-lang'
LANGUAGE_HEADER
=
'HTTP_ACCEPT_LANGUAGE'
COOKIE_DURATION
=
14
*
24
*
60
*
60
# 14 days in seconds
openedx/core/djangoapps/lang_pref/middleware.py
View file @
3deb3a3c
...
@@ -2,12 +2,17 @@
...
@@ -2,12 +2,17 @@
Middleware for Language Preferences
Middleware for Language Preferences
"""
"""
from
django.conf
import
settings
from
django.utils.translation
import
LANGUAGE_SESSION_KEY
from
django.utils.translation
import
LANGUAGE_SESSION_KEY
from
django.utils.translation.trans_real
import
parse_accept_lang_header
from
django.utils.translation.trans_real
import
parse_accept_lang_header
from
openedx.core.djangoapps.lang_pref
import
LANGUAGE_KEY
from
openedx.core.djangoapps.lang_pref
import
(
from
openedx.core.djangoapps.lang_pref.api
import
released_languages
LANGUAGE_KEY
,
LANGUAGE_HEADER
,
COOKIE_DURATION
from
openedx.core.djangoapps.user_api.preferences.api
import
get_user_preference
,
delete_user_preference
)
from
openedx.core.djangoapps.user_api.preferences.api
import
(
get_user_preference
,
delete_user_preference
,
set_user_preference
)
from
openedx.core.djangoapps.user_api.errors
import
UserAPIInternalError
,
UserAPIRequestError
class
LanguagePreferenceMiddleware
(
object
):
class
LanguagePreferenceMiddleware
(
object
):
...
@@ -21,17 +26,46 @@ class LanguagePreferenceMiddleware(object):
...
@@ -21,17 +26,46 @@ class LanguagePreferenceMiddleware(object):
def
process_request
(
self
,
request
):
def
process_request
(
self
,
request
):
"""
"""
If a user's UserPreference contains a language preference, use the user's preference.
If a user's UserPreference contains a language preference, use the user's preference.
Save the current language preference cookie as the user's preferred language.
"""
"""
languages
=
released_languages
()
cookie_lang
=
request
.
COOKIES
.
get
(
settings
.
LANGUAGE_COOKIE
,
None
)
system_released_languages
=
[
seq
[
0
]
for
seq
in
languages
]
if
cookie_lang
:
if
request
.
user
.
is_authenticated
():
set_user_preference
(
request
.
user
,
LANGUAGE_KEY
,
cookie_lang
)
accept_header
=
request
.
META
.
get
(
LANGUAGE_HEADER
,
None
)
if
accept_header
:
current_langs
=
parse_accept_lang_header
(
accept_header
)
# Promote the cookie_lang over any language currently in the accept header
current_langs
=
[(
lang
,
qvalue
)
for
(
lang
,
qvalue
)
in
current_langs
if
lang
!=
cookie_lang
]
current_langs
.
insert
(
0
,
(
cookie_lang
,
1
))
accept_header
=
","
.
join
(
"{};q={}"
.
format
(
lang
,
qvalue
)
for
(
lang
,
qvalue
)
in
current_langs
)
else
:
accept_header
=
cookie_lang
request
.
META
[
LANGUAGE_HEADER
]
=
accept_header
def
process_response
(
self
,
request
,
response
):
# If the user is logged in, check for their language preference
# If the user is logged in, check for their language preference
if
request
.
user
.
is_authenticated
():
if
getattr
(
request
,
'user'
,
None
)
and
request
.
user
.
is_authenticated
():
# Get the user's language preference
# Get the user's language preference
user_pref
=
get_user_preference
(
request
.
user
,
LANGUAGE_KEY
)
try
:
# Set it to the LANGUAGE_SESSION_KEY (Django-specific session setting governing language pref)
user_pref
=
get_user_preference
(
request
.
user
,
LANGUAGE_KEY
)
if
user_pref
:
except
(
UserAPIRequestError
,
UserAPIInternalError
):
if
user_pref
in
system_released_languages
:
# If we can't find the user preferences, then don't modify the cookie
request
.
session
[
LANGUAGE_SESSION_KEY
]
=
user_pref
pass
else
:
# Set it in the LANGUAGE_COOKIE
if
user_pref
:
response
.
set_cookie
(
settings
.
LANGUAGE_COOKIE
,
value
=
user_pref
,
domain
=
settings
.
SESSION_COOKIE_DOMAIN
,
max_age
=
COOKIE_DURATION
,
)
else
:
else
:
delete_user_preference
(
request
.
user
,
LANGUAGE_KEY
)
response
.
delete_cookie
(
settings
.
LANGUAGE_COOKIE
,
domain
=
settings
.
SESSION_COOKIE_DOMAIN
)
return
response
openedx/core/djangoapps/lang_pref/tests/test_middleware.py
View file @
3deb3a3c
This diff is collapsed.
Click to expand it.
openedx/core/djangoapps/lang_pref/views.py
View file @
3deb3a3c
...
@@ -9,7 +9,7 @@ from django.http import HttpResponse
...
@@ -9,7 +9,7 @@ from django.http import HttpResponse
from
django.views.decorators.csrf
import
ensure_csrf_cookie
from
django.views.decorators.csrf
import
ensure_csrf_cookie
from
django.utils.translation
import
LANGUAGE_SESSION_KEY
from
django.utils.translation
import
LANGUAGE_SESSION_KEY
from
openedx.core.djangoapps.lang_pref
import
LANGUAGE_KEY
from
openedx.core.djangoapps.lang_pref
import
LANGUAGE_KEY
,
COOKIE_DURATION
@ensure_csrf_cookie
@ensure_csrf_cookie
...
@@ -17,9 +17,16 @@ def update_session_language(request):
...
@@ -17,9 +17,16 @@ def update_session_language(request):
"""
"""
Update the language session key.
Update the language session key.
"""
"""
response
=
HttpResponse
(
200
)
if
request
.
method
==
'PATCH'
:
if
request
.
method
==
'PATCH'
:
data
=
json
.
loads
(
request
.
body
)
data
=
json
.
loads
(
request
.
body
)
language
=
data
.
get
(
LANGUAGE_KEY
,
settings
.
LANGUAGE_CODE
)
language
=
data
.
get
(
LANGUAGE_KEY
,
settings
.
LANGUAGE_CODE
)
if
request
.
session
.
get
(
LANGUAGE_SESSION_KEY
,
None
)
!=
language
:
if
request
.
session
.
get
(
LANGUAGE_SESSION_KEY
,
None
)
!=
language
:
request
.
session
[
LANGUAGE_SESSION_KEY
]
=
unicode
(
language
)
request
.
session
[
LANGUAGE_SESSION_KEY
]
=
unicode
(
language
)
return
HttpResponse
(
200
)
response
.
set_cookie
(
settings
.
LANGUAGE_COOKIE
,
language
,
domain
=
settings
.
SESSION_COOKIE_DOMAIN
,
max_age
=
COOKIE_DURATION
)
return
response
openedx/core/djangoapps/user_api/accounts/tests/test_views.py
View file @
3deb3a3c
...
@@ -174,7 +174,7 @@ class TestOwnUsernameAPI(CacheIsolationTestCase, UserAPITestCase):
...
@@ -174,7 +174,7 @@ class TestOwnUsernameAPI(CacheIsolationTestCase, UserAPITestCase):
Test that a client (logged in) can get her own username.
Test that a client (logged in) can get her own username.
"""
"""
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
TEST_PASSWORD
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
TEST_PASSWORD
)
self
.
_verify_get_own_username
(
1
5
)
self
.
_verify_get_own_username
(
1
4
)
def
test_get_username_inactive
(
self
):
def
test_get_username_inactive
(
self
):
"""
"""
...
@@ -184,7 +184,7 @@ class TestOwnUsernameAPI(CacheIsolationTestCase, UserAPITestCase):
...
@@ -184,7 +184,7 @@ class TestOwnUsernameAPI(CacheIsolationTestCase, UserAPITestCase):
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
TEST_PASSWORD
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
TEST_PASSWORD
)
self
.
user
.
is_active
=
False
self
.
user
.
is_active
=
False
self
.
user
.
save
()
self
.
user
.
save
()
self
.
_verify_get_own_username
(
1
5
)
self
.
_verify_get_own_username
(
1
4
)
def
test_get_username_not_logged_in
(
self
):
def
test_get_username_not_logged_in
(
self
):
"""
"""
...
@@ -305,7 +305,7 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase):
...
@@ -305,7 +305,7 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase):
"""
"""
self
.
different_client
.
login
(
username
=
self
.
different_user
.
username
,
password
=
TEST_PASSWORD
)
self
.
different_client
.
login
(
username
=
self
.
different_user
.
username
,
password
=
TEST_PASSWORD
)
self
.
create_mock_profile
(
self
.
user
)
self
.
create_mock_profile
(
self
.
user
)
with
self
.
assertNumQueries
(
1
9
):
with
self
.
assertNumQueries
(
1
8
):
response
=
self
.
send_get
(
self
.
different_client
)
response
=
self
.
send_get
(
self
.
different_client
)
self
.
_verify_full_shareable_account_response
(
response
,
account_privacy
=
ALL_USERS_VISIBILITY
)
self
.
_verify_full_shareable_account_response
(
response
,
account_privacy
=
ALL_USERS_VISIBILITY
)
...
@@ -320,7 +320,7 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase):
...
@@ -320,7 +320,7 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase):
"""
"""
self
.
different_client
.
login
(
username
=
self
.
different_user
.
username
,
password
=
TEST_PASSWORD
)
self
.
different_client
.
login
(
username
=
self
.
different_user
.
username
,
password
=
TEST_PASSWORD
)
self
.
create_mock_profile
(
self
.
user
)
self
.
create_mock_profile
(
self
.
user
)
with
self
.
assertNumQueries
(
1
9
):
with
self
.
assertNumQueries
(
1
8
):
response
=
self
.
send_get
(
self
.
different_client
)
response
=
self
.
send_get
(
self
.
different_client
)
self
.
_verify_private_account_response
(
response
,
account_privacy
=
PRIVATE_VISIBILITY
)
self
.
_verify_private_account_response
(
response
,
account_privacy
=
PRIVATE_VISIBILITY
)
...
@@ -395,12 +395,12 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase):
...
@@ -395,12 +395,12 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase):
self
.
assertEqual
(
False
,
data
[
"accomplishments_shared"
])
self
.
assertEqual
(
False
,
data
[
"accomplishments_shared"
])
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
TEST_PASSWORD
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
TEST_PASSWORD
)
verify_get_own_information
(
1
7
)
verify_get_own_information
(
1
6
)
# Now make sure that the user can get the same information, even if not active
# Now make sure that the user can get the same information, even if not active
self
.
user
.
is_active
=
False
self
.
user
.
is_active
=
False
self
.
user
.
save
()
self
.
user
.
save
()
verify_get_own_information
(
1
1
)
verify_get_own_information
(
1
0
)
def
test_get_account_empty_string
(
self
):
def
test_get_account_empty_string
(
self
):
"""
"""
...
@@ -414,7 +414,7 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase):
...
@@ -414,7 +414,7 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase):
legacy_profile
.
save
()
legacy_profile
.
save
()
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
TEST_PASSWORD
)
self
.
client
.
login
(
username
=
self
.
user
.
username
,
password
=
TEST_PASSWORD
)
with
self
.
assertNumQueries
(
1
7
):
with
self
.
assertNumQueries
(
1
6
):
response
=
self
.
send_get
(
self
.
client
)
response
=
self
.
send_get
(
self
.
client
)
for
empty_field
in
(
"level_of_education"
,
"gender"
,
"country"
,
"bio"
):
for
empty_field
in
(
"level_of_education"
,
"gender"
,
"country"
,
"bio"
):
self
.
assertIsNone
(
response
.
data
[
empty_field
])
self
.
assertIsNone
(
response
.
data
[
empty_field
])
...
...
openedx/core/djangoapps/user_api/errors.py
View file @
3deb3a3c
...
@@ -83,6 +83,7 @@ class PreferenceValidationError(PreferenceRequestError):
...
@@ -83,6 +83,7 @@ class PreferenceValidationError(PreferenceRequestError):
"""
"""
def
__init__
(
self
,
preference_errors
):
def
__init__
(
self
,
preference_errors
):
self
.
preference_errors
=
preference_errors
self
.
preference_errors
=
preference_errors
super
(
PreferenceValidationError
,
self
)
.
__init__
(
preference_errors
)
class
PreferenceUpdateError
(
PreferenceRequestError
):
class
PreferenceUpdateError
(
PreferenceRequestError
):
...
@@ -93,6 +94,7 @@ class PreferenceUpdateError(PreferenceRequestError):
...
@@ -93,6 +94,7 @@ class PreferenceUpdateError(PreferenceRequestError):
def
__init__
(
self
,
developer_message
,
user_message
=
None
):
def
__init__
(
self
,
developer_message
,
user_message
=
None
):
self
.
developer_message
=
developer_message
self
.
developer_message
=
developer_message
self
.
user_message
=
user_message
self
.
user_message
=
user_message
super
(
PreferenceUpdateError
,
self
)
.
__init__
(
developer_message
)
class
CountryCodeError
(
ValueError
):
class
CountryCodeError
(
ValueError
):
...
...
openedx/core/djangoapps/user_api/helpers.py
View file @
3deb3a3c
...
@@ -6,6 +6,7 @@ from collections import defaultdict
...
@@ -6,6 +6,7 @@ from collections import defaultdict
from
functools
import
wraps
from
functools
import
wraps
import
logging
import
logging
import
json
import
json
import
traceback
from
django
import
forms
from
django
import
forms
from
django.core.serializers.json
import
DjangoJSONEncoder
from
django.core.serializers.json
import
DjangoJSONEncoder
...
@@ -65,16 +66,19 @@ def intercept_errors(api_error, ignore_errors=None):
...
@@ -65,16 +66,19 @@ def intercept_errors(api_error, ignore_errors=None):
LOGGER
.
warning
(
msg
)
LOGGER
.
warning
(
msg
)
raise
raise
caller
=
traceback
.
format_stack
(
limit
=
2
)[
0
]
# Otherwise, log the error and raise the API-specific error
# Otherwise, log the error and raise the API-specific error
msg
=
(
msg
=
(
u"An unexpected error occurred when calling '{func_name}' "
u"An unexpected error occurred when calling '{func_name}' "
u"with arguments '{args}' and keyword arguments '{kwargs}': "
u"with arguments '{args}' and keyword arguments '{kwargs}'
from {caller}
: "
u"{exception}"
u"{exception}"
)
.
format
(
)
.
format
(
func_name
=
func
.
func_name
,
func_name
=
func
.
func_name
,
args
=
args
,
args
=
args
,
kwargs
=
kwargs
,
kwargs
=
kwargs
,
exception
=
ex
.
developer_message
if
hasattr
(
ex
,
'developer_message'
)
else
repr
(
ex
)
exception
=
ex
.
developer_message
if
hasattr
(
ex
,
'developer_message'
)
else
repr
(
ex
),
caller
=
caller
.
strip
(),
)
)
LOGGER
.
exception
(
msg
)
LOGGER
.
exception
(
msg
)
raise
api_error
(
msg
)
raise
api_error
(
msg
)
...
@@ -502,3 +506,13 @@ def shim_student_view(view_func, check_logged_in=False):
...
@@ -502,3 +506,13 @@ def shim_student_view(view_func, check_logged_in=False):
return
response
return
response
return
_inner
return
_inner
def
serializer_is_dirty
(
preference_serializer
):
"""
Return True if saving the supplied (Raw)UserPreferenceSerializer would change the database.
"""
return
(
preference_serializer
.
instance
is
None
or
preference_serializer
.
instance
.
value
!=
preference_serializer
.
validated_data
[
'value'
]
)
openedx/core/djangoapps/user_api/preferences/api.py
View file @
3deb3a3c
...
@@ -20,7 +20,7 @@ from ..errors import (
...
@@ -20,7 +20,7 @@ from ..errors import (
UserAPIInternalError
,
UserAPIRequestError
,
UserNotFound
,
UserNotAuthorized
,
UserAPIInternalError
,
UserAPIRequestError
,
UserNotFound
,
UserNotAuthorized
,
PreferenceValidationError
,
PreferenceUpdateError
,
CountryCodeError
PreferenceValidationError
,
PreferenceUpdateError
,
CountryCodeError
)
)
from
..helpers
import
intercept_errors
from
..helpers
import
intercept_errors
,
serializer_is_dirty
from
..models
import
UserOrgTag
,
UserPreference
from
..models
import
UserOrgTag
,
UserPreference
from
..serializers
import
UserSerializer
,
RawUserPreferenceSerializer
from
..serializers
import
UserSerializer
,
RawUserPreferenceSerializer
...
@@ -142,7 +142,9 @@ def update_user_preferences(requesting_user, update, user=None):
...
@@ -142,7 +142,9 @@ def update_user_preferences(requesting_user, update, user=None):
if
preference_value
is
not
None
:
if
preference_value
is
not
None
:
try
:
try
:
serializer
=
serializers
[
preference_key
]
serializer
=
serializers
[
preference_key
]
serializer
.
save
()
if
serializer_is_dirty
(
serializer
):
serializer
.
save
()
except
Exception
as
error
:
except
Exception
as
error
:
raise
_create_preference_update_error
(
preference_key
,
preference_value
,
error
)
raise
_create_preference_update_error
(
preference_key
,
preference_value
,
error
)
else
:
else
:
...
@@ -177,10 +179,12 @@ def set_user_preference(requesting_user, preference_key, preference_value, usern
...
@@ -177,10 +179,12 @@ def set_user_preference(requesting_user, preference_key, preference_value, usern
existing_user
=
_get_authorized_user
(
requesting_user
,
username
)
existing_user
=
_get_authorized_user
(
requesting_user
,
username
)
serializer
=
create_user_preference_serializer
(
existing_user
,
preference_key
,
preference_value
)
serializer
=
create_user_preference_serializer
(
existing_user
,
preference_key
,
preference_value
)
validate_user_preference_serializer
(
serializer
,
preference_key
,
preference_value
)
validate_user_preference_serializer
(
serializer
,
preference_key
,
preference_value
)
try
:
serializer
.
save
()
if
serializer_is_dirty
(
serializer
):
except
Exception
as
error
:
try
:
raise
_create_preference_update_error
(
preference_key
,
preference_value
,
error
)
serializer
.
save
()
except
Exception
as
error
:
raise
_create_preference_update_error
(
preference_key
,
preference_value
,
error
)
@intercept_errors
(
UserAPIInternalError
,
ignore_errors
=
[
UserAPIRequestError
])
@intercept_errors
(
UserAPIInternalError
,
ignore_errors
=
[
UserAPIRequestError
])
...
@@ -310,7 +314,13 @@ def _get_authorized_user(requesting_user, username=None, allow_staff=False):
...
@@ -310,7 +314,13 @@ def _get_authorized_user(requesting_user, username=None, allow_staff=False):
If username is not provided, requesting_user.username is assumed.
If username is not provided, requesting_user.username is assumed.
"""
"""
if
username
is
None
:
if
username
is
None
:
username
=
requesting_user
.
username
# If the user is one that has already been stored to the database, use that
if
requesting_user
.
pk
:
return
requesting_user
else
:
# Otherwise, treat this as a request against a separate user
username
=
requesting_user
.
username
try
:
try
:
existing_user
=
User
.
objects
.
get
(
username
=
username
)
existing_user
=
User
.
objects
.
get
(
username
=
username
)
except
ObjectDoesNotExist
:
except
ObjectDoesNotExist
:
...
@@ -347,13 +357,13 @@ def create_user_preference_serializer(user, preference_key, preference_value):
...
@@ -347,13 +357,13 @@ def create_user_preference_serializer(user, preference_key, preference_value):
except
ObjectDoesNotExist
:
except
ObjectDoesNotExist
:
existing_user_preference
=
None
existing_user_preference
=
None
new_data
=
{
new_data
=
{
"user"
:
user
.
id
,
"key"
:
preference_key
,
"key"
:
preference_key
,
"value"
:
preference_value
,
"value"
:
preference_value
,
}
}
if
existing_user_preference
:
if
existing_user_preference
:
serializer
=
RawUserPreferenceSerializer
(
existing_user_preference
,
data
=
new_data
)
serializer
=
RawUserPreferenceSerializer
(
existing_user_preference
,
data
=
new_data
,
partial
=
True
)
else
:
else
:
new_data
[
'user'
]
=
user
.
id
serializer
=
RawUserPreferenceSerializer
(
data
=
new_data
)
serializer
=
RawUserPreferenceSerializer
(
data
=
new_data
)
return
serializer
return
serializer
...
...
openedx/core/djangoapps/user_api/preferences/tests/test_api.py
View file @
3deb3a3c
...
@@ -53,9 +53,8 @@ class TestPreferenceAPI(CacheIsolationTestCase):
...
@@ -53,9 +53,8 @@ class TestPreferenceAPI(CacheIsolationTestCase):
super
(
TestPreferenceAPI
,
self
)
.
setUp
()
super
(
TestPreferenceAPI
,
self
)
.
setUp
()
self
.
user
=
UserFactory
.
create
(
password
=
self
.
password
)
self
.
user
=
UserFactory
.
create
(
password
=
self
.
password
)
self
.
different_user
=
UserFactory
.
create
(
password
=
self
.
password
)
self
.
different_user
=
UserFactory
.
create
(
password
=
self
.
password
)
self
.
staff_user
=
UserFactory
(
is_staff
=
True
,
password
=
self
.
password
)
self
.
staff_user
=
UserFactory
.
create
(
is_staff
=
True
,
password
=
self
.
password
)
self
.
no_such_user
=
UserFactory
.
create
(
password
=
self
.
password
)
self
.
no_such_user
=
UserFactory
.
build
(
password
=
self
.
password
,
username
=
"no_such_user"
)
self
.
no_such_user
.
username
=
"no_such_user"
self
.
test_preference_key
=
"test_key"
self
.
test_preference_key
=
"test_key"
self
.
test_preference_value
=
"test_value"
self
.
test_preference_value
=
"test_value"
set_user_preference
(
self
.
user
,
self
.
test_preference_key
,
self
.
test_preference_value
)
set_user_preference
(
self
.
user
,
self
.
test_preference_key
,
self
.
test_preference_value
)
...
...
openedx/core/djangoapps/user_api/serializers.py
View file @
3deb3a3c
...
@@ -22,12 +22,7 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
...
@@ -22,12 +22,7 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
"""
"""
Return the name attribute from the user profile object if profile exists else none
Return the name attribute from the user profile object if profile exists else none
"""
"""
try
:
return
user
.
profile
.
name
profile
=
UserProfile
.
objects
.
get
(
user
=
user
)
except
UserProfile
.
DoesNotExist
:
return
None
return
profile
.
name
def
get_preferences
(
self
,
user
):
def
get_preferences
(
self
,
user
):
"""
"""
...
...
openedx/core/djangoapps/user_api/tests/test_helpers.py
View file @
3deb3a3c
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
Tests for helper functions.
Tests for helper functions.
"""
"""
import
json
import
json
import
re
import
mock
import
mock
import
ddt
import
ddt
from
django
import
forms
from
django
import
forms
...
@@ -55,19 +56,31 @@ class InterceptErrorsTest(TestCase):
...
@@ -55,19 +56,31 @@ class InterceptErrorsTest(TestCase):
exception
=
'openedx.core.djangoapps.user_api.tests.test_helpers.FakeInputException'
exception
=
'openedx.core.djangoapps.user_api.tests.test_helpers.FakeInputException'
expected_log_msg
=
(
expected_log_msg
=
(
u"An unexpected error occurred when calling 'intercepted_function' with arguments '()' and "
u"An unexpected error occurred when calling 'intercepted_function' with arguments '()' and "
u"keyword arguments '{'raise_error': <class '"
+
exception
+
u"'>}': FakeInputException()"
u"keyword arguments '{{'raise_error': <class '{}'>}}' "
)
u"from File
\"
{}
\"
, line XXX, in test_logs_errors
\n
"
u" intercepted_function(raise_error=FakeInputException): FakeInputException()"
)
.
format
(
exception
,
__file__
)
# Verify that the raised exception has the error message
# Verify that the raised exception has the error message
try
:
try
:
intercepted_function
(
raise_error
=
FakeInputException
)
intercepted_function
(
raise_error
=
FakeInputException
)
except
FakeOutputException
as
ex
:
except
FakeOutputException
as
ex
:
self
.
assertEqual
(
ex
.
message
,
expected_log_msg
)
actual_message
=
re
.
sub
(
r'line \d+'
,
'line XXX'
,
ex
.
message
,
flags
=
re
.
MULTILINE
)
self
.
assertEqual
(
actual_message
,
expected_log_msg
)
# Verify that the error logger is called
# Verify that the error logger is called
# This will include the stack trace for the original exception
# This will include the stack trace for the original exception
# because it's called with log level "ERROR"
# because it's called with log level "ERROR"
mock_logger
.
exception
.
assert_called_once_with
(
expected_log_msg
)
calls
=
mock_logger
.
exception
.
mock_calls
self
.
assertEqual
(
len
(
calls
),
1
)
name
,
args
,
kwargs
=
calls
[
0
]
self
.
assertEqual
(
name
,
''
)
self
.
assertEqual
(
len
(
args
),
1
)
self
.
assertEqual
(
kwargs
,
{})
actual_message
=
re
.
sub
(
r'line \d+'
,
'line XXX'
,
args
[
0
],
flags
=
re
.
MULTILINE
)
self
.
assertEqual
(
actual_message
,
expected_log_msg
)
class
FormDescriptionTest
(
TestCase
):
class
FormDescriptionTest
(
TestCase
):
...
...
openedx/core/djangoapps/user_api/views.py
View file @
3deb3a3c
...
@@ -1002,7 +1002,7 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet):
...
@@ -1002,7 +1002,7 @@ class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
"""
authentication_classes
=
(
authentication
.
SessionAuthentication
,)
authentication_classes
=
(
authentication
.
SessionAuthentication
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
queryset
=
User
.
objects
.
all
()
.
prefetch_related
(
"preferences"
)
queryset
=
User
.
objects
.
all
()
.
prefetch_related
(
"preferences"
)
.
select_related
(
"profile"
)
serializer_class
=
UserSerializer
serializer_class
=
UserSerializer
paginate_by
=
10
paginate_by
=
10
paginate_by_param
=
"page_size"
paginate_by_param
=
"page_size"
...
@@ -1028,7 +1028,7 @@ class ForumRoleUsersListView(generics.ListAPIView):
...
@@ -1028,7 +1028,7 @@ class ForumRoleUsersListView(generics.ListAPIView):
raise
ParseError
(
'course_id must be specified'
)
raise
ParseError
(
'course_id must be specified'
)
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id_string
)
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id_string
)
role
=
Role
.
objects
.
get_or_create
(
course_id
=
course_id
,
name
=
name
)[
0
]
role
=
Role
.
objects
.
get_or_create
(
course_id
=
course_id
,
name
=
name
)[
0
]
users
=
role
.
users
.
all
()
users
=
role
.
users
.
prefetch_related
(
"preferences"
)
.
select_related
(
"profile"
)
.
all
()
return
users
return
users
...
@@ -1057,7 +1057,7 @@ class PreferenceUsersListView(generics.ListAPIView):
...
@@ -1057,7 +1057,7 @@ class PreferenceUsersListView(generics.ListAPIView):
paginate_by_param
=
"page_size"
paginate_by_param
=
"page_size"
def
get_queryset
(
self
):
def
get_queryset
(
self
):
return
User
.
objects
.
filter
(
preferences__key
=
self
.
kwargs
[
"pref_key"
])
.
prefetch_related
(
"preferences"
)
return
User
.
objects
.
filter
(
preferences__key
=
self
.
kwargs
[
"pref_key"
])
.
prefetch_related
(
"preferences"
)
.
select_related
(
"profile"
)
class
UpdateEmailOptInPreference
(
APIView
):
class
UpdateEmailOptInPreference
(
APIView
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment