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
be189e60
Commit
be189e60
authored
Feb 11, 2014
by
Diana Huang
Committed by
Julia Hansbrough
Feb 14, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Store user preferences for languages
Also, refactor tests such that we're not deleting users or prefs
parent
77cce3aa
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
183 additions
and
57 deletions
+183
-57
common/djangoapps/user_api/middleware.py
+6
-9
common/djangoapps/user_api/models.py
+25
-0
common/djangoapps/user_api/tests/test_middleware.py
+42
-0
common/djangoapps/user_api/tests/test_models.py
+16
-0
common/djangoapps/user_api/tests/test_views.py
+60
-35
common/djangoapps/user_api/urls.py
+1
-0
common/djangoapps/user_api/views.py
+18
-1
lms/envs/common.py
+4
-0
lms/templates/dashboard.html
+11
-9
lms/templates/dashboard/_dashboard_info_language.html
+0
-3
No files found.
common/djangoapps/user_api/middleware.py
View file @
be189e60
...
@@ -2,8 +2,6 @@
...
@@ -2,8 +2,6 @@
Middleware for UserPreferences
Middleware for UserPreferences
"""
"""
from
django.utils.translation.trans_real
import
parse_accept_lang_header
from
user_api.models
import
UserPreference
,
LANGUAGE_KEY
from
user_api.models
import
UserPreference
,
LANGUAGE_KEY
...
@@ -17,11 +15,10 @@ class UserPreferenceMiddleware(object):
...
@@ -17,11 +15,10 @@ class UserPreferenceMiddleware(object):
def
process_request
(
self
,
request
):
def
process_request
(
self
,
request
):
"""
"""
If a user's UserPreference contains a language preference
,
If a user's UserPreference contains a language preference
and there is
stick that preference in the session
.
no language set on the session, use the user's preference
.
"""
"""
if
'django_language'
not
in
request
.
session
and
request
.
user
.
is_authenticated
():
query
=
UserPreference
.
objects
.
filter
(
user
=
request
.
user
,
key
=
LANGUAGE_KEY
)
user_pref
=
UserPreference
.
get_preference
(
request
.
user
,
LANGUAGE_KEY
)
if
query
.
exists
():
if
user_pref
:
# there should only be one result for query
request
.
session
[
'django_language'
]
=
user_pref
request
.
session
[
'django_language'
]
=
query
[
0
]
.
value
common/djangoapps/user_api/models.py
View file @
be189e60
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.db
import
models
from
django.db
import
models
LANGUAGE_KEY
=
'pref-lang'
class
UserPreference
(
models
.
Model
):
class
UserPreference
(
models
.
Model
):
"""A user's preference, stored as generic text to be processed by client"""
"""A user's preference, stored as generic text to be processed by client"""
...
@@ -10,3 +12,26 @@ class UserPreference(models.Model):
...
@@ -10,3 +12,26 @@ class UserPreference(models.Model):
class
Meta
:
class
Meta
:
unique_together
=
(
"user"
,
"key"
)
unique_together
=
(
"user"
,
"key"
)
@classmethod
def
set_preference
(
cls
,
user
,
preference_key
,
preference_value
):
"""
Sets the user preference for a given key
"""
user_pref
,
_
=
cls
.
objects
.
get_or_create
(
user
=
user
,
key
=
preference_key
)
user_pref
.
value
=
preference_value
user_pref
.
save
()
@classmethod
def
get_preference
(
cls
,
user
,
preference_key
):
"""
Gets the user preference value for a given key
Returns None if there isn't a preference for the given key
"""
try
:
user_pref
=
cls
.
objects
.
get
(
user
=
user
,
key
=
preference_key
)
return
user_pref
.
value
except
cls
.
DoesNotExist
:
return
None
common/djangoapps/user_api/tests/test_middleware.py
0 → 100644
View file @
be189e60
from
django.test
import
TestCase
from
django.test.client
import
RequestFactory
from
django.contrib.sessions.middleware
import
SessionMiddleware
from
user_api.middleware
import
UserPreferenceMiddleware
from
user_api.models
import
UserPreference
,
LANGUAGE_KEY
from
student.tests.factories
import
UserFactory
class
TestUserPreferenceMiddleware
(
TestCase
):
"""
Tests to make sure user preferences are getting properly set in the middleware
"""
def
setUp
(
self
):
self
.
middleware
=
UserPreferenceMiddleware
()
self
.
request_factory
=
RequestFactory
()
self
.
session_middleware
=
SessionMiddleware
()
self
.
user
=
UserFactory
.
create
()
self
.
request
=
self
.
request_factory
.
get
(
'/somewhere'
)
self
.
request
.
user
=
self
.
user
self
.
session_middleware
.
process_request
(
self
.
request
)
def
test_no_language_set_in_session_or_prefs
(
self
):
# nothing set in the session or the prefs
self
.
middleware
.
process_request
(
self
.
request
)
self
.
assertNotIn
(
'django_language'
,
self
.
request
.
session
)
def
test_language_in_user_prefs
(
self
):
# language set in the user preferences and not the session
UserPreference
.
set_preference
(
self
.
user
,
LANGUAGE_KEY
,
'eo'
)
self
.
middleware
.
process_request
(
self
.
request
)
self
.
assertEquals
(
self
.
request
.
session
[
'django_language'
],
'eo'
)
def
test_language_in_session
(
self
):
# language set in both the user preferences and session,
# session should get precedence
self
.
request
.
session
[
'django_language'
]
=
'en'
UserPreference
.
set_preference
(
self
.
user
,
LANGUAGE_KEY
,
'eo'
)
self
.
middleware
.
process_request
(
self
.
request
)
self
.
assertEquals
(
self
.
request
.
session
[
'django_language'
],
'en'
)
common/djangoapps/user_api/tests/test_models.py
View file @
be189e60
...
@@ -2,6 +2,7 @@ from django.db import IntegrityError
...
@@ -2,6 +2,7 @@ from django.db import IntegrityError
from
django.test
import
TestCase
from
django.test
import
TestCase
from
student.tests.factories
import
UserFactory
from
student.tests.factories
import
UserFactory
from
user_api.tests.factories
import
UserPreferenceFactory
from
user_api.tests.factories
import
UserPreferenceFactory
from
user_api.models
import
UserPreference
class
UserPreferenceModelTest
(
TestCase
):
class
UserPreferenceModelTest
(
TestCase
):
...
@@ -26,3 +27,18 @@ class UserPreferenceModelTest(TestCase):
...
@@ -26,3 +27,18 @@ class UserPreferenceModelTest(TestCase):
key
=
"testkey3"
,
key
=
"testkey3"
,
value
=
"
\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\xad\xe5\x9b\xbd\xe6\x96\x87\xe5\xad\x97
'"
value
=
"
\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\xad\xe5\x9b\xbd\xe6\x96\x87\xe5\xad\x97
'"
)
)
def
test_get_set_preference
(
self
):
user
=
UserFactory
.
create
()
key
=
'testkey'
value
=
'testvalue'
# does a round trip
UserPreference
.
set_preference
(
user
,
key
,
value
)
pref
=
UserPreference
.
get_preference
(
user
,
key
)
self
.
assertEqual
(
pref
,
value
)
# get preference for key that doesn't exist for user
pref
=
UserPreference
.
get_preference
(
user
,
'testkey_none'
)
self
.
assertIsNone
(
pref
)
common/djangoapps/user_api/tests/test_views.py
View file @
be189e60
import
base64
import
base64
from
django.contrib.auth.models
import
User
from
django.test
import
TestCase
from
django.test
import
TestCase
from
django.test.utils
import
override_settings
from
django.test.utils
import
override_settings
from
django.core.urlresolvers
import
reverse
import
json
import
json
import
re
import
re
from
student.tests.factories
import
UserFactory
from
student.tests.factories
import
UserFactory
from
unittest
import
SkipTest
from
unittest
import
SkipTest
from
user_api.models
import
UserPreference
from
user_api.models
import
UserPreference
,
LANGUAGE_KEY
from
user_api.tests.factories
import
UserPreferenceFactory
from
user_api.tests.factories
import
UserPreferenceFactory
...
@@ -17,21 +17,9 @@ USER_PREFERENCE_LIST_URI = "/user_api/v1/user_prefs/"
...
@@ -17,21 +17,9 @@ USER_PREFERENCE_LIST_URI = "/user_api/v1/user_prefs/"
@override_settings
(
EDX_API_KEY
=
TEST_API_KEY
)
@override_settings
(
EDX_API_KEY
=
TEST_API_KEY
)
class
UserApiTestCase
(
TestCase
):
class
ApiTestCase
(
TestCase
):
def
setUp
(
self
):
super
(
UserApiTestCase
,
self
)
.
setUp
()
LIST_URI
=
USER_LIST_URI
self
.
users
=
[
UserFactory
.
create
(
email
=
"test{0}@test.org"
.
format
(
i
),
profile__name
=
"Test {0}"
.
format
(
i
)
)
for
i
in
range
(
5
)
]
self
.
prefs
=
[
UserPreferenceFactory
.
create
(
user
=
self
.
users
[
0
],
key
=
"key0"
),
UserPreferenceFactory
.
create
(
user
=
self
.
users
[
0
],
key
=
"key1"
),
UserPreferenceFactory
.
create
(
user
=
self
.
users
[
1
],
key
=
"key0"
)
]
def
basic_auth
(
self
,
username
,
password
):
def
basic_auth
(
self
,
username
,
password
):
return
{
'HTTP_AUTHORIZATION'
:
'Basic '
+
base64
.
b64encode
(
'
%
s:
%
s'
%
(
username
,
password
))}
return
{
'HTTP_AUTHORIZATION'
:
'Basic '
+
base64
.
b64encode
(
'
%
s:
%
s'
%
(
username
,
password
))}
...
@@ -100,6 +88,32 @@ class UserApiTestCase(TestCase):
...
@@ -100,6 +88,32 @@ class UserApiTestCase(TestCase):
self
.
assertEqual
(
response
.
status_code
,
405
)
self
.
assertEqual
(
response
.
status_code
,
405
)
class
NoUserApiTestCase
(
ApiTestCase
):
def
test_get_list_empty
(
self
):
result
=
self
.
get_json
(
self
.
LIST_URI
)
self
.
assertEqual
(
result
[
"count"
],
0
)
self
.
assertIsNone
(
result
[
"next"
])
self
.
assertIsNone
(
result
[
"previous"
])
self
.
assertEqual
(
result
[
"results"
],
[])
class
UserApiTestCase
(
ApiTestCase
):
def
setUp
(
self
):
super
(
UserApiTestCase
,
self
)
.
setUp
()
self
.
users
=
[
UserFactory
.
create
(
email
=
"test{0}@test.org"
.
format
(
i
),
profile__name
=
"Test {0}"
.
format
(
i
)
)
for
i
in
range
(
5
)
]
self
.
prefs
=
[
UserPreferenceFactory
.
create
(
user
=
self
.
users
[
0
],
key
=
"key0"
),
UserPreferenceFactory
.
create
(
user
=
self
.
users
[
0
],
key
=
"key1"
),
UserPreferenceFactory
.
create
(
user
=
self
.
users
[
1
],
key
=
"key0"
)
]
class
UserViewSetTest
(
UserApiTestCase
):
class
UserViewSetTest
(
UserApiTestCase
):
LIST_URI
=
USER_LIST_URI
LIST_URI
=
USER_LIST_URI
...
@@ -137,17 +151,10 @@ class UserViewSetTest(UserApiTestCase):
...
@@ -137,17 +151,10 @@ class UserViewSetTest(UserApiTestCase):
def
test_basic_auth
(
self
):
def
test_basic_auth
(
self
):
# ensure that having basic auth headers in the mix does not break anything
# ensure that having basic auth headers in the mix does not break anything
self
.
assertHttpOK
(
self
.
assertHttpOK
(
self
.
request_with_auth
(
"get"
,
self
.
LIST_URI
,
**
self
.
basic_auth
(
'someuser'
,
'somepass'
)))
self
.
request_with_auth
(
"get"
,
self
.
LIST_URI
,
**
self
.
basic_auth
(
'someuser'
,
'somepass'
)))
self
.
assertHttpForbidden
(
self
.
assertHttpForbidden
(
self
.
client
.
get
(
self
.
LIST_URI
,
**
self
.
basic_auth
(
'someuser'
,
'somepass'
)))
self
.
client
.
get
(
self
.
LIST_URI
,
**
self
.
basic_auth
(
'someuser'
,
'somepass'
)))
def
test_get_list_empty
(
self
):
User
.
objects
.
all
()
.
delete
()
result
=
self
.
get_json
(
self
.
LIST_URI
)
self
.
assertEqual
(
result
[
"count"
],
0
)
self
.
assertIsNone
(
result
[
"next"
])
self
.
assertIsNone
(
result
[
"previous"
])
self
.
assertEqual
(
result
[
"results"
],
[])
def
test_get_list_nonempty
(
self
):
def
test_get_list_nonempty
(
self
):
result
=
self
.
get_json
(
self
.
LIST_URI
)
result
=
self
.
get_json
(
self
.
LIST_URI
)
...
@@ -245,14 +252,6 @@ class UserPreferenceViewSetTest(UserApiTestCase):
...
@@ -245,14 +252,6 @@ class UserPreferenceViewSetTest(UserApiTestCase):
def
test_debug_auth
(
self
):
def
test_debug_auth
(
self
):
self
.
assertHttpOK
(
self
.
client
.
get
(
self
.
LIST_URI
))
self
.
assertHttpOK
(
self
.
client
.
get
(
self
.
LIST_URI
))
def
test_get_list_empty
(
self
):
UserPreference
.
objects
.
all
()
.
delete
()
result
=
self
.
get_json
(
self
.
LIST_URI
)
self
.
assertEqual
(
result
[
"count"
],
0
)
self
.
assertIsNone
(
result
[
"next"
])
self
.
assertIsNone
(
result
[
"previous"
])
self
.
assertEqual
(
result
[
"results"
],
[])
def
test_get_list_nonempty
(
self
):
def
test_get_list_nonempty
(
self
):
result
=
self
.
get_json
(
self
.
LIST_URI
)
result
=
self
.
get_json
(
self
.
LIST_URI
)
self
.
assertEqual
(
result
[
"count"
],
3
)
self
.
assertEqual
(
result
[
"count"
],
3
)
...
@@ -357,3 +356,29 @@ class UserPreferenceViewSetTest(UserApiTestCase):
...
@@ -357,3 +356,29 @@ class UserPreferenceViewSetTest(UserApiTestCase):
"url"
:
uri
,
"url"
:
uri
,
}
}
)
)
class
TestLanguageSetting
(
TestCase
):
"""
Test setting languages
"""
def
test_set_preference_happy
(
self
):
user
=
UserFactory
.
create
()
self
.
client
.
login
(
username
=
user
.
username
,
password
=
'test'
)
lang
=
'en'
response
=
self
.
client
.
post
(
reverse
(
'user_api_set_language'
),
{
'language'
:
lang
})
self
.
assertEqual
(
response
.
status_code
,
200
)
user_pref
=
UserPreference
.
get_preference
(
user
,
LANGUAGE_KEY
)
self
.
assertEqual
(
user_pref
,
lang
)
def
test_set_preference_missing_lang
(
self
):
user
=
UserFactory
.
create
()
self
.
client
.
login
(
username
=
user
.
username
,
password
=
'test'
)
response
=
self
.
client
.
post
(
reverse
(
'user_api_set_language'
))
self
.
assertEqual
(
response
.
status_code
,
400
)
self
.
assertIsNone
(
UserPreference
.
get_preference
(
user
,
LANGUAGE_KEY
))
common/djangoapps/user_api/urls.py
View file @
be189e60
...
@@ -9,4 +9,5 @@ user_api_router.register(r'user_prefs', user_api_views.UserPreferenceViewSet)
...
@@ -9,4 +9,5 @@ user_api_router.register(r'user_prefs', user_api_views.UserPreferenceViewSet)
urlpatterns
=
patterns
(
urlpatterns
=
patterns
(
''
,
''
,
url
(
r'^v1/'
,
include
(
user_api_router
.
urls
)),
url
(
r'^v1/'
,
include
(
user_api_router
.
urls
)),
url
(
r'^setlang/'
,
'user_api.views.set_language'
,
name
=
'user_api_set_language'
)
)
)
common/djangoapps/user_api/views.py
View file @
be189e60
from
django.conf
import
settings
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
from
django.contrib.auth.decorators
import
login_required
from
django.http
import
HttpResponse
,
HttpResponseBadRequest
from
rest_framework
import
authentication
from
rest_framework
import
authentication
from
rest_framework
import
filters
from
rest_framework
import
filters
from
rest_framework
import
permissions
from
rest_framework
import
permissions
from
rest_framework
import
viewsets
from
rest_framework
import
viewsets
from
user_api.models
import
UserPreference
from
user_api.models
import
UserPreference
,
LANGUAGE_KEY
from
user_api.serializers
import
UserSerializer
,
UserPreferenceSerializer
from
user_api.serializers
import
UserSerializer
,
UserPreferenceSerializer
...
@@ -43,3 +45,18 @@ class UserPreferenceViewSet(viewsets.ReadOnlyModelViewSet):
...
@@ -43,3 +45,18 @@ class UserPreferenceViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class
=
UserPreferenceSerializer
serializer_class
=
UserPreferenceSerializer
paginate_by
=
10
paginate_by
=
10
paginate_by_param
=
"page_size"
paginate_by_param
=
"page_size"
@login_required
def
set_language
(
request
):
"""
This view is called when the user would like to set a language preference
"""
user
=
request
.
user
lang_pref
=
request
.
POST
.
get
(
'language'
,
None
)
if
lang_pref
:
UserPreference
.
set_preference
(
user
,
LANGUAGE_KEY
,
lang_pref
)
return
HttpResponse
(
'{"success": true}'
)
return
HttpResponseBadRequest
(
'no language provided'
)
lms/envs/common.py
View file @
be189e60
...
@@ -698,6 +698,10 @@ MIDDLEWARE_CLASSES = (
...
@@ -698,6 +698,10 @@ MIDDLEWARE_CLASSES = (
# Allows us to dark-launch particular languages
# Allows us to dark-launch particular languages
'dark_lang.middleware.DarkLangMiddleware'
,
'dark_lang.middleware.DarkLangMiddleware'
,
# Allows us to set user preferences
# should be after DarkLangMiddleware
'user_api.middleware.UserPreferenceMiddleware'
,
# Detects user-requested locale from 'accept-language' header in http request
# Detects user-requested locale from 'accept-language' header in http request
'django.middleware.locale.LocaleMiddleware'
,
'django.middleware.locale.LocaleMiddleware'
,
...
...
lms/templates/dashboard.html
View file @
be189e60
...
@@ -83,15 +83,17 @@
...
@@ -83,15 +83,17 @@
});
});
});
});
$
(
"#change_language_form"
).
submit
(
function
(
event
,
xhr
)
{
$
(
"#submit-lang"
).
click
(
function
(
event
,
xhr
)
{
$
.
post
(
'/i18n/setlang/'
,
event
.
preventDefault
();
{
"language"
:
language
,},
$
.
post
(
'/user_api/setlang/'
,
function
(
data
)
{
{
"language"
:
$
(
'#settings-language-value'
).
val
()})
if
(
data
.
success
){
.
done
(
location
.
reload
();
function
(
data
){
}
// submit form as normal
})
$
(
'.settings-language-form'
).
submit
();
});
}
);
});
$
(
"#change_email_form"
).
submit
(
function
(){
$
(
"#change_email_form"
).
submit
(
function
(){
var
new_email
=
$
(
'#new_email_field'
).
val
();
var
new_email
=
$
(
'#new_email_field'
).
val
();
...
...
lms/templates/dashboard/_dashboard_info_language.html
View file @
be189e60
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
%
>
<
%!
from
django
.
utils
.
translation
import
ugettext
as
_
%
>
<
%!
from
django
.
core
.
urlresolvers
import
reverse
%
>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
<
%
namespace
name=
'static'
file=
'../static_content.html'
/>
...
...
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