diff --git a/cms/djangoapps/contentstore/tests/test_libraries.py b/cms/djangoapps/contentstore/tests/test_libraries.py index 529396e087..0e45222f10 100644 --- a/cms/djangoapps/contentstore/tests/test_libraries.py +++ b/cms/djangoapps/contentstore/tests/test_libraries.py @@ -25,6 +25,7 @@ from openedx.core.djangoapps.content.course_structures.tests import SignalDiscon from xblock_django.user_service import DjangoXBlockUserService from xmodule.x_module import STUDIO_VIEW from student import auth +from student.tests.factories import UserFactory class LibraryTestCase(ModuleStoreTestCase): @@ -34,6 +35,7 @@ class LibraryTestCase(ModuleStoreTestCase): def setUp(self): super(LibraryTestCase, self).setUp() + self.user = UserFactory(password=self.user_password, is_staff=True) self.client = AjaxEnabledTestClient() self._login_as_staff_user(logout_first=False) @@ -477,7 +479,8 @@ class TestLibraryAccess(SignalDisconnectTestMixin, LibraryTestCase): def setUp(self): """ Create a library, staff user, and non-staff user """ super(TestLibraryAccess, self).setUp() - self.non_staff_user, self.non_staff_user_password = self.create_non_staff_user() + self.non_staff_user_password = 'foo' + self.non_staff_user = UserFactory(password=self.non_staff_user_password, is_staff=False) def _login_as_non_staff_user(self, logout_first=True): """ Login as a user that starts out with no roles/permissions granted. """ diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index 1cb8a6f6b8..490a7bdfe6 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -1217,6 +1217,7 @@ class TestEditSplitModule(ItemTest): """ def setUp(self): super(TestEditSplitModule, self).setUp() + self.user = UserFactory() self.course.user_partitions = [ UserPartition( 0, 'first_partition', 'First Partition', diff --git a/common/djangoapps/xblock_django/tests/test_user_service.py b/common/djangoapps/xblock_django/tests/test_user_service.py index 0b4e8c0c72..1783bd274f 100644 --- a/common/djangoapps/xblock_django/tests/test_user_service.py +++ b/common/djangoapps/xblock_django/tests/test_user_service.py @@ -8,10 +8,13 @@ from xblock_django.user_service import ( ATTR_KEY_USER_ID, ATTR_KEY_USERNAME, ATTR_KEY_USER_IS_STAFF, + ATTR_KEY_USER_PREFERENCES, + USER_PREFERENCES_WHITE_LIST, ) from student.models import anonymous_id_for_user from student.tests.factories import UserFactory, AnonymousUserFactory from opaque_keys.edx.keys import CourseKey +from openedx.core.djangoapps.user_api.preferences.api import set_user_preference class UserServiceTestCase(TestCase): @@ -22,6 +25,9 @@ class UserServiceTestCase(TestCase): super(UserServiceTestCase, self).setUp() self.user = UserFactory(username="tester", email="test@tester.com") self.user.profile.name = "Test Tester" + set_user_preference(self.user, 'pref-lang', 'en') + set_user_preference(self.user, 'time_zone', 'US/Pacific') + set_user_preference(self.user, 'not_white_listed', 'hidden_value') self.anon_user = AnonymousUserFactory() def assert_is_anon_xb_user(self, xb_user): @@ -42,6 +48,12 @@ class UserServiceTestCase(TestCase): self.assertEqual(xb_user.opt_attrs[ATTR_KEY_USERNAME], dj_user.username) self.assertEqual(xb_user.opt_attrs[ATTR_KEY_USER_ID], dj_user.id) self.assertFalse(xb_user.opt_attrs[ATTR_KEY_USER_IS_STAFF]) + self.assertTrue( + all( + pref in USER_PREFERENCES_WHITE_LIST + for pref in xb_user.opt_attrs[ATTR_KEY_USER_PREFERENCES] + ) + ) def test_convert_anon_user(self): """ diff --git a/common/djangoapps/xblock_django/user_service.py b/common/djangoapps/xblock_django/user_service.py index 3adb5cb65b..3816c29690 100644 --- a/common/djangoapps/xblock_django/user_service.py +++ b/common/djangoapps/xblock_django/user_service.py @@ -3,13 +3,16 @@ Support for converting a django user to an XBlock user """ from django.contrib.auth.models import User from opaque_keys.edx.keys import CourseKey -from xblock.reference.user_service import XBlockUser, UserService +from openedx.core.djangoapps.user_api.preferences.api import get_user_preferences from student.models import anonymous_id_for_user, get_user_by_username_or_email +from xblock.reference.user_service import XBlockUser, UserService ATTR_KEY_IS_AUTHENTICATED = 'edx-platform.is_authenticated' ATTR_KEY_USER_ID = 'edx-platform.user_id' ATTR_KEY_USERNAME = 'edx-platform.username' ATTR_KEY_USER_IS_STAFF = 'edx-platform.user_is_staff' +ATTR_KEY_USER_PREFERENCES = 'edx-platform.user_preferences' +USER_PREFERENCES_WHITE_LIST = ['pref-lang', 'time_zone'] class DjangoXBlockUserService(UserService): @@ -69,6 +72,12 @@ class DjangoXBlockUserService(UserService): xblock_user.opt_attrs[ATTR_KEY_USER_ID] = django_user.id xblock_user.opt_attrs[ATTR_KEY_USERNAME] = django_user.username xblock_user.opt_attrs[ATTR_KEY_USER_IS_STAFF] = django_user.user_is_staff + user_preferences = get_user_preferences(django_user) + xblock_user.opt_attrs[ATTR_KEY_USER_PREFERENCES] = { + pref: user_preferences.get(pref) + for pref in USER_PREFERENCES_WHITE_LIST + if pref in user_preferences + } else: xblock_user.opt_attrs[ATTR_KEY_IS_AUTHENTICATED] = False diff --git a/openedx/core/djangoapps/user_api/models.py b/openedx/core/djangoapps/user_api/models.py index 6d893ef6f3..78c65a7fa0 100644 --- a/openedx/core/djangoapps/user_api/models.py +++ b/openedx/core/djangoapps/user_api/models.py @@ -31,7 +31,7 @@ class UserPreference(models.Model): unique_together = ("user", "key") @classmethod - def get_value(cls, user, preference_key): + def get_value(cls, user, preference_key, default=None): """Gets the user preference value for a given key. Note: @@ -42,15 +42,16 @@ class UserPreference(models.Model): Arguments: user (User): The user whose preference should be set. preference_key (str): The key for the user preference. + default: The object to return if user does not have preference key set Returns: - The user preference value, or None if one is not set. + The user preference value, or default if one is not set. """ try: user_preference = cls.objects.get(user=user, key=preference_key) return user_preference.value except cls.DoesNotExist: - return None + return default @receiver(pre_save, sender=UserPreference) diff --git a/openedx/core/djangoapps/user_api/tests/test_models.py b/openedx/core/djangoapps/user_api/tests/test_models.py index d3977e1c1b..ba23299bf4 100644 --- a/openedx/core/djangoapps/user_api/tests/test_models.py +++ b/openedx/core/djangoapps/user_api/tests/test_models.py @@ -93,6 +93,10 @@ class UserPreferenceModelTest(ModuleStoreTestCase): pref = UserPreference.get_value(user, 'testkey_none') self.assertIsNone(pref) + # get default value for key that doesn't exist for user + pref = UserPreference.get_value(user, 'testkey_none', 'default_value') + self.assertEqual('default_value', pref) + class TestUserPreferenceEvents(UserSettingsEventTestMixin, TestCase): """ diff --git a/openedx/core/lib/time_zone_utils.py b/openedx/core/lib/time_zone_utils.py index 35f792e579..b9637b41f3 100644 --- a/openedx/core/lib/time_zone_utils.py +++ b/openedx/core/lib/time_zone_utils.py @@ -11,10 +11,8 @@ def get_user_time_zone(user): Returns pytz time zone object of the user's time zone if available or UTC time zone if unavailable """ #TODO: exception for unknown timezones? - time_zone = user.preferences.model.get_value(user, "time_zone") - if time_zone is not None: - return timezone(time_zone) - return utc + time_zone = user.preferences.model.get_value(user, "time_zone", 'utc') + return timezone(time_zone) def _format_time_zone_string(time_zone, date_time, format_string):