From ebc9c75e3652aed11c5e6b5dbafbf7dd775069a4 Mon Sep 17 00:00:00 2001 From: Clinton Blackburn Date: Tue, 3 Mar 2015 15:50:47 -0500 Subject: [PATCH 1/4] Explicitly naming task This should prevent errors due to relative imports. See http://docs.celeryproject.org/en/latest/userguide/tasks.html#automatic-naming-and-relative-imports for additional information. --- openedx/core/djangoapps/content/course_structures/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/content/course_structures/models.py b/openedx/core/djangoapps/content/course_structures/models.py index 7819aec3fc..ebbd320c4f 100644 --- a/openedx/core/djangoapps/content/course_structures/models.py +++ b/openedx/core/djangoapps/content/course_structures/models.py @@ -63,7 +63,7 @@ def listen_for_course_publish(sender, course_key, **kwargs): update_course_structure.delay(unicode(course_key), countdown=0) -@task() +@task(name=u'openedx.core.djangoapps.content.course_structures.models.update_course_structure') def update_course_structure(course_key): """ Regenerates and updates the course structure (in the database) for the specified course. From 84d91a7901d75f9197969436aac3d2ad3cb7fc42 Mon Sep 17 00:00:00 2001 From: cahrens Date: Tue, 3 Mar 2015 16:16:20 -0500 Subject: [PATCH 2/4] Correctly point to MAX_LENGTH instead of MIN_LENGTH. Bug introduced in recent commit. --- openedx/core/djangoapps/user_api/api/profile.py | 5 +++++ openedx/core/djangoapps/user_api/tests/test_views.py | 5 ++--- openedx/core/djangoapps/user_api/views.py | 4 +--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/openedx/core/djangoapps/user_api/api/profile.py b/openedx/core/djangoapps/user_api/api/profile.py index 28de57068c..371e4a4186 100644 --- a/openedx/core/djangoapps/user_api/api/profile.py +++ b/openedx/core/djangoapps/user_api/api/profile.py @@ -14,6 +14,7 @@ from pytz import UTC import analytics from eventtracking import tracker +from ..accounts import NAME_MIN_LENGTH from ..accounts.views import AccountView from ..models import User, UserPreference, UserOrgTag from ..helpers import intercept_errors @@ -36,6 +37,10 @@ class ProfileInternalError(Exception): pass +FULL_NAME_MAX_LENGTH = 255 +FULL_NAME_MIN_LENGTH = NAME_MIN_LENGTH + + @intercept_errors(ProfileInternalError, ignore_errors=[ProfileRequestError]) def preference_info(username): """Retrieve information about a user's preferences. diff --git a/openedx/core/djangoapps/user_api/tests/test_views.py b/openedx/core/djangoapps/user_api/tests/test_views.py index c9c841527e..3d11542e38 100644 --- a/openedx/core/djangoapps/user_api/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/tests/test_views.py @@ -28,7 +28,6 @@ from ..api import account as account_api, profile as profile_api from ..models import UserOrgTag from ..tests.factories import UserPreferenceFactory from ..tests.test_constants import SORTED_COUNTRIES -from openedx.core.djangoapps.user_api.accounts import NAME_MIN_LENGTH TEST_API_KEY = "test_api_key" @@ -842,7 +841,7 @@ class RegistrationViewTest(ApiTestCase): u"label": u"Full name", u"instructions": u"The name that will appear on your certificates", u"restrictions": { - "max_length": NAME_MIN_LENGTH, + "max_length": profile_api.FULL_NAME_MAX_LENGTH, }, } ) @@ -922,7 +921,7 @@ class RegistrationViewTest(ApiTestCase): u"label": u"Full name", u"instructions": u"The name that will appear on your certificates", u"restrictions": { - "max_length": NAME_MIN_LENGTH + "max_length": profile_api.FULL_NAME_MAX_LENGTH, } } ) diff --git a/openedx/core/djangoapps/user_api/views.py b/openedx/core/djangoapps/user_api/views.py index 0a93898c5a..929c7133d1 100644 --- a/openedx/core/djangoapps/user_api/views.py +++ b/openedx/core/djangoapps/user_api/views.py @@ -33,8 +33,6 @@ from .helpers import FormDescription, shim_student_view, require_post_params from .models import UserPreference, UserProfile from .serializers import UserSerializer, UserPreferenceSerializer -from openedx.core.djangoapps.user_api.accounts import NAME_MIN_LENGTH - class LoginSessionView(APIView): """HTTP end-points for logging in users. """ @@ -352,7 +350,7 @@ class RegistrationView(APIView): label=name_label, instructions=name_instructions, restrictions={ - "max_length": NAME_MIN_LENGTH, + "max_length": profile_api.FULL_NAME_MAX_LENGTH, }, required=required ) From 167bd05ac823a3f495bebc282ac67e055a6304c6 Mon Sep 17 00:00:00 2001 From: cahrens Date: Tue, 3 Mar 2015 17:16:47 -0500 Subject: [PATCH 3/4] Add bok choy coverage for correctly displayed name and email address. --- common/test/acceptance/pages/lms/dashboard.py | 15 +++++++++++++++ common/test/acceptance/tests/lms/test_lms.py | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/common/test/acceptance/pages/lms/dashboard.py b/common/test/acceptance/pages/lms/dashboard.py index 4404a8f7ad..9aaeee09e8 100644 --- a/common/test/acceptance/pages/lms/dashboard.py +++ b/common/test/acceptance/pages/lms/dashboard.py @@ -51,6 +51,21 @@ class DashboardPage(PageObject): return self.q(css='section.info > hgroup > h3 > a').map(_get_course_name).results + @property + def full_name(self): + """Return the displayed value for the user's full name""" + return self.q(css='li.info--username .data').text[0] + + @property + def email(self): + """Return the displayed value for the user's email address""" + return self.q(css='li.info--email .data').text[0] + + @property + def username(self): + """Return the displayed value for the user's username""" + return self.q(css='h1.user-name').text[0] + def get_enrollment_mode(self, course_name): """Get the enrollment mode for a given course on the dashboard. diff --git a/common/test/acceptance/tests/lms/test_lms.py b/common/test/acceptance/tests/lms/test_lms.py index 567efc79ed..9d1a33ac33 100644 --- a/common/test/acceptance/tests/lms/test_lms.py +++ b/common/test/acceptance/tests/lms/test_lms.py @@ -170,6 +170,10 @@ class RegisterFromCombinedPageTest(UniqueCourseTest): course_names = self.dashboard_page.wait_for_page().available_courses self.assertIn(self.course_info["display_name"], course_names) + self.assertEqual("Test User", self.dashboard_page.full_name) + self.assertEqual(email, self.dashboard_page.email) + self.assertEqual(username, self.dashboard_page.username) + def test_register_failure(self): # Navigate to the registration page self.register_page.visit() From 6f118a3d8fdf645329984063cf2a1cabc334493e Mon Sep 17 00:00:00 2001 From: Andy Armstrong Date: Tue, 3 Mar 2015 15:58:21 -0500 Subject: [PATCH 4/4] Default profile visibility to off for now --- lms/envs/common.py | 2 +- .../user_api/profiles/tests/test_views.py | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lms/envs/common.py b/lms/envs/common.py index 5b40e63693..c933ef9e44 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -2056,7 +2056,7 @@ SEARCH_RESULT_PROCESSOR = "lms.lib.courseware_search.lms_result_processor.LmsSea PROFILE_CONFIGURATION = { # Default visibility level for accounts without a specified value # The value is one of: 'all_users', 'private' - "default_visibility": 'all_users', + "default_visibility": "private", # The list of all fields that can be shown on a learner's profile "all_fields": [ diff --git a/openedx/core/djangoapps/user_api/profiles/tests/test_views.py b/openedx/core/djangoapps/user_api/profiles/tests/test_views.py index 8341988d74..28e4377861 100644 --- a/openedx/core/djangoapps/user_api/profiles/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/profiles/tests/test_views.py @@ -7,6 +7,7 @@ import unittest from django.conf import settings from django.core.urlresolvers import reverse +from mock import patch from openedx.core.djangoapps.user_api.accounts.tests.test_views import UserAPITestCase from openedx.core.djangoapps.user_api.models import UserPreference @@ -59,6 +60,10 @@ class TestProfileAPI(UserAPITestCase): ("staff_client", "staff_user"), ) @ddt.unpack + # Note: using getattr so that the patching works even if there is no configuration. + # This is needed when testing CMS as the patching is still executed even though the + # suite is skipped. + @patch.dict(getattr(settings, "PROFILE_CONFIGURATION", {}), {"default_visibility": "all_users"}) def test_get_default_profile(self, api_client, username): """ Test that any logged in user can get the main test user's public profile information. @@ -68,6 +73,26 @@ class TestProfileAPI(UserAPITestCase): response = self.send_get(client) self._verify_full_profile_response(response) + @ddt.data( + ("client", "user"), + ("different_client", "different_user"), + ("staff_client", "staff_user"), + ) + @ddt.unpack + # Note: using getattr so that the patching works even if there is no configuration. + # This is needed when testing CMS as the patching is still executed even though the + # suite is skipped. + @patch.dict(getattr(settings, "PROFILE_CONFIGURATION", {}), {"default_visibility": "private"}) + def test_get_default_private_profile(self, api_client, username): + """ + Test that any logged in user gets only the public fields for a profile + if the default visibility is 'private'. + """ + client = self.login_client(api_client, username) + self.create_mock_profile(self.user) + response = self.send_get(client) + self._verify_private_profile_response(response) + @ddt.data( ("client", "user"), ("different_client", "different_user"),