Commit a37a50cf by David Baumgold

Merge branch 'release'

parents f85d2451 0eed96c2
...@@ -51,6 +51,21 @@ class DashboardPage(PageObject): ...@@ -51,6 +51,21 @@ class DashboardPage(PageObject):
return self.q(css='section.info > hgroup > h3 > a').map(_get_course_name).results 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): def get_enrollment_mode(self, course_name):
"""Get the enrollment mode for a given course on the dashboard. """Get the enrollment mode for a given course on the dashboard.
......
...@@ -170,6 +170,10 @@ class RegisterFromCombinedPageTest(UniqueCourseTest): ...@@ -170,6 +170,10 @@ class RegisterFromCombinedPageTest(UniqueCourseTest):
course_names = self.dashboard_page.wait_for_page().available_courses course_names = self.dashboard_page.wait_for_page().available_courses
self.assertIn(self.course_info["display_name"], course_names) 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): def test_register_failure(self):
# Navigate to the registration page # Navigate to the registration page
self.register_page.visit() self.register_page.visit()
......
...@@ -2051,7 +2051,7 @@ SEARCH_RESULT_PROCESSOR = "lms.lib.courseware_search.lms_result_processor.LmsSea ...@@ -2051,7 +2051,7 @@ SEARCH_RESULT_PROCESSOR = "lms.lib.courseware_search.lms_result_processor.LmsSea
PROFILE_CONFIGURATION = { PROFILE_CONFIGURATION = {
# Default visibility level for accounts without a specified value # Default visibility level for accounts without a specified value
# The value is one of: 'all_users', 'private' # 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 # The list of all fields that can be shown on a learner's profile
"all_fields": [ "all_fields": [
......
...@@ -63,7 +63,7 @@ def listen_for_course_publish(sender, course_key, **kwargs): ...@@ -63,7 +63,7 @@ def listen_for_course_publish(sender, course_key, **kwargs):
update_course_structure.delay(unicode(course_key), countdown=0) 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): def update_course_structure(course_key):
""" """
Regenerates and updates the course structure (in the database) for the specified course. Regenerates and updates the course structure (in the database) for the specified course.
......
...@@ -14,6 +14,7 @@ from pytz import UTC ...@@ -14,6 +14,7 @@ from pytz import UTC
import analytics import analytics
from eventtracking import tracker from eventtracking import tracker
from ..accounts import NAME_MIN_LENGTH
from ..accounts.views import AccountView from ..accounts.views import AccountView
from ..models import User, UserPreference, UserOrgTag from ..models import User, UserPreference, UserOrgTag
from ..helpers import intercept_errors from ..helpers import intercept_errors
...@@ -36,6 +37,10 @@ class ProfileInternalError(Exception): ...@@ -36,6 +37,10 @@ class ProfileInternalError(Exception):
pass pass
FULL_NAME_MAX_LENGTH = 255
FULL_NAME_MIN_LENGTH = NAME_MIN_LENGTH
@intercept_errors(ProfileInternalError, ignore_errors=[ProfileRequestError]) @intercept_errors(ProfileInternalError, ignore_errors=[ProfileRequestError])
def preference_info(username): def preference_info(username):
"""Retrieve information about a user's preferences. """Retrieve information about a user's preferences.
......
...@@ -7,6 +7,7 @@ import unittest ...@@ -7,6 +7,7 @@ import unittest
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse 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.accounts.tests.test_views import UserAPITestCase
from openedx.core.djangoapps.user_api.models import UserPreference from openedx.core.djangoapps.user_api.models import UserPreference
...@@ -59,6 +60,10 @@ class TestProfileAPI(UserAPITestCase): ...@@ -59,6 +60,10 @@ class TestProfileAPI(UserAPITestCase):
("staff_client", "staff_user"), ("staff_client", "staff_user"),
) )
@ddt.unpack @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): 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. Test that any logged in user can get the main test user's public profile information.
...@@ -74,6 +79,26 @@ class TestProfileAPI(UserAPITestCase): ...@@ -74,6 +79,26 @@ class TestProfileAPI(UserAPITestCase):
("staff_client", "staff_user"), ("staff_client", "staff_user"),
) )
@ddt.unpack @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"),
("staff_client", "staff_user"),
)
@ddt.unpack
def test_get_private_profile(self, api_client, requesting_username): def test_get_private_profile(self, api_client, requesting_username):
""" """
Test that private profile information is only available to the test user themselves. Test that private profile information is only available to the test user themselves.
......
...@@ -28,7 +28,6 @@ from ..api import account as account_api, profile as profile_api ...@@ -28,7 +28,6 @@ from ..api import account as account_api, profile as profile_api
from ..models import UserOrgTag from ..models import UserOrgTag
from ..tests.factories import UserPreferenceFactory from ..tests.factories import UserPreferenceFactory
from ..tests.test_constants import SORTED_COUNTRIES from ..tests.test_constants import SORTED_COUNTRIES
from openedx.core.djangoapps.user_api.accounts import NAME_MIN_LENGTH
TEST_API_KEY = "test_api_key" TEST_API_KEY = "test_api_key"
...@@ -842,7 +841,7 @@ class RegistrationViewTest(ApiTestCase): ...@@ -842,7 +841,7 @@ class RegistrationViewTest(ApiTestCase):
u"label": u"Full name", u"label": u"Full name",
u"instructions": u"The name that will appear on your certificates", u"instructions": u"The name that will appear on your certificates",
u"restrictions": { u"restrictions": {
"max_length": NAME_MIN_LENGTH, "max_length": profile_api.FULL_NAME_MAX_LENGTH,
}, },
} }
) )
...@@ -922,7 +921,7 @@ class RegistrationViewTest(ApiTestCase): ...@@ -922,7 +921,7 @@ class RegistrationViewTest(ApiTestCase):
u"label": u"Full name", u"label": u"Full name",
u"instructions": u"The name that will appear on your certificates", u"instructions": u"The name that will appear on your certificates",
u"restrictions": { u"restrictions": {
"max_length": NAME_MIN_LENGTH "max_length": profile_api.FULL_NAME_MAX_LENGTH,
} }
} }
) )
......
...@@ -33,8 +33,6 @@ from .helpers import FormDescription, shim_student_view, require_post_params ...@@ -33,8 +33,6 @@ from .helpers import FormDescription, shim_student_view, require_post_params
from .models import UserPreference, UserProfile from .models import UserPreference, UserProfile
from .serializers import UserSerializer, UserPreferenceSerializer from .serializers import UserSerializer, UserPreferenceSerializer
from openedx.core.djangoapps.user_api.accounts import NAME_MIN_LENGTH
class LoginSessionView(APIView): class LoginSessionView(APIView):
"""HTTP end-points for logging in users. """ """HTTP end-points for logging in users. """
...@@ -352,7 +350,7 @@ class RegistrationView(APIView): ...@@ -352,7 +350,7 @@ class RegistrationView(APIView):
label=name_label, label=name_label,
instructions=name_instructions, instructions=name_instructions,
restrictions={ restrictions={
"max_length": NAME_MIN_LENGTH, "max_length": profile_api.FULL_NAME_MAX_LENGTH,
}, },
required=required required=required
) )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment