Merge pull request #7327 from edx/andya/preferences-api

Implement full preferences API
This commit is contained in:
Andy Armstrong
2015-03-17 00:57:01 -04:00
55 changed files with 2476 additions and 1173 deletions

View File

@@ -6,7 +6,7 @@ consist primarily of authentication, request validation, and serialization.
from ipware.ip import get_ip
from django.utils.decorators import method_decorator
from opaque_keys import InvalidKeyError
from openedx.core.djangoapps.user_api import api as user_api
from openedx.core.djangoapps.user_api.preferences.api import update_email_opt_in
from openedx.core.lib.api.permissions import ApiKeyHeaderPermission, ApiKeyHeaderPermissionIsAuthenticated
from rest_framework import status
from rest_framework.response import Response
@@ -349,7 +349,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
email_opt_in = request.DATA.get('email_opt_in', None)
if email_opt_in is not None:
org = course_id.org
user_api.profile.update_email_opt_in(request.user, org, email_opt_in)
update_email_opt_in(request.user, org, email_opt_in)
return Response(response)
except CourseModeNotFoundError as error:
return Response(

View File

@@ -2,7 +2,7 @@
Middleware for Language Preferences
"""
from openedx.core.djangoapps.user_api.models import UserPreference
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
from lang_pref import LANGUAGE_KEY
@@ -20,6 +20,6 @@ class LanguagePreferenceMiddleware(object):
no language set on the session (i.e. from dark language overrides), use the user's preference.
"""
if request.user.is_authenticated() and 'django_language' not in request.session:
user_pref = UserPreference.get_preference(request.user, LANGUAGE_KEY)
user_pref = get_user_preference(request.user, LANGUAGE_KEY)
if user_pref:
request.session['django_language'] = user_pref

View File

@@ -3,7 +3,7 @@ from django.test.client import RequestFactory
from django.contrib.sessions.middleware import SessionMiddleware
from lang_pref.middleware import LanguagePreferenceMiddleware
from openedx.core.djangoapps.user_api.models import UserPreference
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
from lang_pref import LANGUAGE_KEY
from student.tests.factories import UserFactory
@@ -28,7 +28,7 @@ class TestUserPreferenceMiddleware(TestCase):
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')
set_user_preference(self.user, LANGUAGE_KEY, 'eo')
self.middleware.process_request(self.request)
self.assertEquals(self.request.session['django_language'], 'eo')
@@ -36,7 +36,7 @@ class TestUserPreferenceMiddleware(TestCase):
# 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')
set_user_preference(self.user, LANGUAGE_KEY, 'eo')
self.middleware.process_request(self.request)
self.assertEquals(self.request.session['django_language'], 'en')

View File

@@ -4,7 +4,7 @@ Tests for the language setting view
from django.core.urlresolvers import reverse
from django.test import TestCase
from student.tests.factories import UserFactory
from openedx.core.djangoapps.user_api.models import UserPreference
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
from lang_pref import LANGUAGE_KEY
@@ -20,7 +20,7 @@ class TestLanguageSetting(TestCase):
response = self.client.post(reverse('lang_pref_set_language'), {'language': lang})
self.assertEquals(response.status_code, 200)
user_pref = UserPreference.get_preference(user, LANGUAGE_KEY)
user_pref = get_user_preference(user, LANGUAGE_KEY)
self.assertEqual(user_pref, lang)
def test_set_preference_missing_lang(self):
@@ -31,4 +31,4 @@ class TestLanguageSetting(TestCase):
self.assertEquals(response.status_code, 400)
self.assertIsNone(UserPreference.get_preference(user, LANGUAGE_KEY))
self.assertIsNone(get_user_preference(user, LANGUAGE_KEY))

View File

@@ -4,7 +4,7 @@ Views for accessing language preferences
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseBadRequest
from openedx.core.djangoapps.user_api.models import UserPreference
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
from lang_pref import LANGUAGE_KEY
@@ -13,11 +13,10 @@ 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)
set_user_preference(request.user, LANGUAGE_KEY, lang_pref)
return HttpResponse('{"success": true}')
return HttpResponseBadRequest('no language provided')

View File

@@ -40,7 +40,7 @@ class UserProfileFactory(DjangoModelFactory):
level_of_education = None
gender = u'm'
mailing_address = None
goals = u'World domination'
goals = u'Learn a lot'
class CourseModeFactory(DjangoModelFactory):

View File

@@ -1,4 +1,4 @@
"Tests for account creation"
"""Tests for account creation"""
import json
import ddt
@@ -14,7 +14,7 @@ from django.test.utils import override_settings
import mock
from openedx.core.djangoapps.user_api.models import UserPreference
from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
from lang_pref import LANGUAGE_KEY
from notification_prefs import NOTIFICATION_PREF_KEY
@@ -42,7 +42,7 @@ TEST_CS_URL = 'https://comments.service.test:123/'
}
)
class TestCreateAccount(TestCase):
"Tests for account creation"
"""Tests for account creation"""
def setUp(self):
self.username = "test_user"
@@ -63,14 +63,14 @@ class TestCreateAccount(TestCase):
response = self.client.post(self.url, self.params)
self.assertEqual(response.status_code, 200)
user = User.objects.get(username=self.username)
self.assertEqual(UserPreference.get_preference(user, LANGUAGE_KEY), lang)
self.assertEqual(get_user_preference(user, LANGUAGE_KEY), lang)
@ddt.data("en", "eo")
def test_header_lang_pref_saved(self, lang):
response = self.client.post(self.url, self.params, HTTP_ACCEPT_LANGUAGE=lang)
user = User.objects.get(username=self.username)
self.assertEqual(response.status_code, 200)
self.assertEqual(UserPreference.get_preference(user, LANGUAGE_KEY), lang)
self.assertEqual(get_user_preference(user, LANGUAGE_KEY), lang)
def create_account_and_fetch_profile(self):
"""
@@ -225,7 +225,7 @@ class TestCreateAccount(TestCase):
response = self.client.post(self.url, self.params)
self.assertEqual(response.status_code, 200)
user = User.objects.get(username=self.username)
preference = UserPreference.get_preference(user, NOTIFICATION_PREF_KEY)
preference = get_user_preference(user, NOTIFICATION_PREF_KEY)
if digest_enabled:
self.assertIsNotNone(preference)
else:

View File

@@ -103,7 +103,7 @@ class EnrollmentTest(UrlResetMixin, ModuleStoreTestCase):
self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course.id))
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_EMAIL_OPT_IN': True})
@patch('openedx.core.djangoapps.user_api.api.profile.update_email_opt_in')
@patch('openedx.core.djangoapps.user_api.preferences.api.update_email_opt_in')
@ddt.data(
([], 'true'),
([], 'false'),

View File

@@ -85,7 +85,6 @@ from external_auth.login_and_register import (
from bulk_email.models import Optout, CourseAuthorization
import shoppingcart
from lang_pref import LANGUAGE_KEY
from notification_prefs.views import enable_notifications
import track.views
@@ -118,6 +117,12 @@ from embargo import api as embargo_api
import analytics
from eventtracking import tracker
# Note that this lives in LMS, so this dependency should be refactored.
from notification_prefs.views import enable_notifications
# Note that this lives in openedx, so this dependency should be refactored.
from openedx.core.djangoapps.user_api.preferences import api as preferences_api
log = logging.getLogger("edx.student")
AUDIT_LOG = logging.getLogger("audit")
@@ -632,20 +637,17 @@ def dashboard(request):
# Re-alphabetize language options
language_options.sort()
# TODO: remove circular dependency on openedx from common
from openedx.core.djangoapps.user_api.models import UserPreference
# try to get the prefered language for the user
cur_pref_lang_code = UserPreference.get_preference(request.user, LANGUAGE_KEY)
# try to get the preferred language for the user
preferred_language_code = preferences_api.get_user_preference(request.user, LANGUAGE_KEY)
# try and get the current language of the user
cur_lang_code = get_language()
if cur_pref_lang_code and cur_pref_lang_code in settings.LANGUAGE_DICT:
current_language_code = get_language()
if preferred_language_code and preferred_language_code in settings.LANGUAGE_DICT:
# if the user has a preference, get the name from the code
current_language = settings.LANGUAGE_DICT[cur_pref_lang_code]
elif cur_lang_code in settings.LANGUAGE_DICT:
current_language = settings.LANGUAGE_DICT[preferred_language_code]
elif current_language_code in settings.LANGUAGE_DICT:
# if the user's browser is showing a particular language,
# use that as the current language
current_language = settings.LANGUAGE_DICT[cur_lang_code]
current_language = settings.LANGUAGE_DICT[current_language_code]
else:
# otherwise, use the default language
current_language = settings.LANGUAGE_DICT[settings.LANGUAGE_CODE]
@@ -680,7 +682,7 @@ def dashboard(request):
'billing_email': settings.PAYMENT_SUPPORT_EMAIL,
'language_options': language_options,
'current_language': current_language,
'current_language_code': cur_lang_code,
'current_language_code': current_language_code,
'user': user,
'duplicate_provider': None,
'logout_url': reverse(logout_user),
@@ -800,13 +802,10 @@ def try_change_enrollment(request):
def _update_email_opt_in(request, org):
"""Helper function used to hit the profile API if email opt-in is enabled."""
# TODO: remove circular dependency on openedx from common
from openedx.core.djangoapps.user_api.api import profile as profile_api
email_opt_in = request.POST.get('email_opt_in')
if email_opt_in is not None:
email_opt_in_boolean = email_opt_in == 'true'
profile_api.update_email_opt_in(request.user, org, email_opt_in_boolean)
preferences_api.update_email_opt_in(request.user, org, email_opt_in_boolean)
@require_POST
@@ -1391,10 +1390,7 @@ def _do_create_account(form):
log.exception("UserProfile creation failed for user {id}.".format(id=user.id))
raise
# TODO: remove circular dependency on openedx from common
from openedx.core.djangoapps.user_api.models import UserPreference
UserPreference.set_preference(user, LANGUAGE_KEY, get_language())
preferences_api.set_user_preference(user, LANGUAGE_KEY, get_language())
return (user, profile, registration)

View File

@@ -89,6 +89,9 @@ from logging import getLogger
from . import provider
# Note that this lives in openedx, so this dependency should be refactored.
from openedx.core.djangoapps.user_api.preferences.api import update_email_opt_in
# These are the query string params you can pass
# to the URL that starts the authentication process.
@@ -669,10 +672,8 @@ def change_enrollment(strategy, user=None, is_dashboard=False, *args, **kwargs):
# If the email opt in parameter is found, set the preference.
email_opt_in = strategy.session_get(AUTH_EMAIL_OPT_IN_KEY)
if email_opt_in:
# TODO: remove circular dependency on openedx from common
from openedx.core.djangoapps.user_api.api import profile
opt_in = email_opt_in.lower() == 'true'
profile.update_email_opt_in(user, course_id.org, opt_in)
update_email_opt_in(user, course_id.org, opt_in)
# Check whether we're blocked from enrolling by a
# country access rule.