diff --git a/common/djangoapps/student/tests/test_activate_account.py b/common/djangoapps/student/tests/test_activate_account.py index 30cd2e1a7a..e32f6c78b4 100644 --- a/common/djangoapps/student/tests/test_activate_account.py +++ b/common/djangoapps/student/tests/test_activate_account.py @@ -112,7 +112,6 @@ class TestActivateAccount(TestCase): def test_activation_without_keys(self, mock_segment_identify): self.assert_no_tracking(mock_segment_identify) - @override_settings(FEATURES=dict(settings.FEATURES, DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR=True)) def test_account_activation_message(self): """ Verify that account correct activation message is displayed. @@ -122,59 +121,29 @@ class TestActivateAccount(TestCase): """ # Log in with test user. self.login() - expected_message = render_to_string( - 'registration/account_activation_sidebar_notice.html', - { - 'email': self.user.email, - 'platform_name': self.platform_name, - 'activation_email_support_link': self.activation_email_support_link - } + expected_message = ( + u"Check your {email_start}{email}{email_end} inbox for an account activation link from " + u"{platform_name}. If you need help, contact {link_start}{platform_name} Support{link_end}." + ).format( + platform_name=self.platform_name, + email_start="", + email_end="", + email=self.user.email, + link_start="".format( + activation_email_support_link=self.activation_email_support_link, + ), + link_end="", ) response = self.client.get(reverse('dashboard')) - self.assertContains(response, expected_message, html=True) + self.assertContains(response, expected_message) # Now make sure account activation message goes away when user activated the account self.user.is_active = True self.user.save() self.login() - expected_message = render_to_string( - 'registration/account_activation_sidebar_notice.html', - { - 'email': self.user.email, - 'platform_name': self.platform_name, - 'activation_email_support_link': self.activation_email_support_link - } - ) response = self.client.get(reverse('dashboard')) - self.assertNotContains(response, expected_message, html=True) - - @override_settings(FEATURES=dict(settings.FEATURES, DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR=False)) - def test_account_activation_message_disabled(self): - """ - Verify that old account activation message is displayed when - DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR is disabled. - """ - # Log in with test user. - self.login() - expected_message = render_to_string( - 'registration/activate_account_notice.html', - {'email': self.user.email} - ) - - response = self.client.get(reverse('dashboard')) - self.assertContains(response, expected_message, html=True) - - # Now make sure account activation message goes away when user activated the account - self.user.is_active = True - self.user.save() - self.login() - expected_message = render_to_string( - 'registration/activate_account_notice.html', - {'email': self.user.email} - ) - response = self.client.get(reverse('dashboard')) - self.assertNotContains(response, expected_message, html=True) + self.assertNotContains(response, expected_message) def test_account_activation_notification_on_logistration(self): """ diff --git a/common/djangoapps/student/tests/test_views.py b/common/djangoapps/student/tests/test_views.py index e3f85cb4e7..6a47a230d9 100644 --- a/common/djangoapps/student/tests/test_views.py +++ b/common/djangoapps/student/tests/test_views.py @@ -27,6 +27,7 @@ from milestones.tests.utils import MilestonesTestCaseMixin from openedx.core.djangoapps.catalog.tests.factories import ProgramFactory from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory +from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration_context from pyquery import PyQuery as pq from student.cookies import get_user_info_cookie_data from student.helpers import DISABLE_UNENROLL_CERT_STATES @@ -264,6 +265,11 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin, 'DASHBOARD_TWITTER': True, }, } + MOCK_SETTINGS_HIDE_COURSES = { + 'FEATURES': { + 'HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED': True, + } + } def setUp(self): """ @@ -619,6 +625,40 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin, response = self.client.get(self.path) self.assertEqual(pq(response.content)(self.EMAIL_SETTINGS_ELEMENT_ID).length, 0) + @patch.multiple('django.conf.settings', **MOCK_SETTINGS_HIDE_COURSES) + def test_hide_dashboard_courses_until_activated(self): + """ + Verify that when the HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED feature is enabled, + inactive users don't see the Courses list, but active users still do. + """ + # Ensure active users see the course list + self.assertTrue(self.user.is_active) + response = self.client.get(reverse('dashboard')) + self.assertIn('You are not enrolled in any courses yet.', response.content) + + # Ensure inactive users don't see the course list + self.user.is_active = False + self.user.save() + response = self.client.get(reverse('dashboard')) + self.assertNotIn('You are not enrolled in any courses yet.', response.content) + + def test_show_empty_dashboard_message(self): + """ + Verify that when the EMPTY_DASHBOARD_MESSAGE feature is set, + its text is displayed in an empty courses list. + """ + empty_dashboard_message = "Check out our lovely free courses!" + response = self.client.get(reverse('dashboard')) + self.assertIn('You are not enrolled in any courses yet.', response.content) + self.assertNotIn(empty_dashboard_message, response.content) + + with with_site_configuration_context(configuration={ + "EMPTY_DASHBOARD_MESSAGE": empty_dashboard_message, + }): + response = self.client.get(reverse('dashboard')) + self.assertIn('You are not enrolled in any courses yet.', response.content) + self.assertIn(empty_dashboard_message, response.content) + @staticmethod def _remove_whitespace_from_html_string(html): return ''.join(html.split()) diff --git a/common/djangoapps/student/views/dashboard.py b/common/djangoapps/student/views/dashboard.py index 78e2b4bd2c..cc7d42ef0b 100644 --- a/common/djangoapps/student/views/dashboard.py +++ b/common/djangoapps/student/views/dashboard.py @@ -40,6 +40,7 @@ from openedx.core.djangoapps.programs.utils import ProgramDataExtender, ProgramP from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.djangoapps.util.maintenance_banner import add_maintenance_banner from openedx.core.djangoapps.waffle_utils import WaffleFlag, WaffleFlagNamespace +from openedx.core.djangolib.markup import HTML, Text from openedx.features.enterprise_support.api import get_dashboard_consent_notification from shoppingcart.api import order_history from shoppingcart.models import CourseRegistrationCode, DonationConfiguration @@ -562,6 +563,13 @@ def student_dashboard(request): activation_email_support_link = configuration_helpers.get_value( 'ACTIVATION_EMAIL_SUPPORT_LINK', settings.ACTIVATION_EMAIL_SUPPORT_LINK ) or settings.SUPPORT_SITE_LINK + hide_dashboard_courses_until_activated = configuration_helpers.get_value( + 'HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED', + settings.FEATURES.get('HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED', False) + ) + empty_dashboard_message = configuration_helpers.get_value( + 'EMPTY_DASHBOARD_MESSAGE', None + ) # Get the org whitelist or the org blacklist for the current site site_org_whitelist, site_org_blacklist = get_org_black_and_whitelist_for_site() @@ -602,28 +610,21 @@ def student_dashboard(request): ) course_optouts = Optout.objects.filter(user=user).values_list('course_id', flat=True) - sidebar_account_activation_message = '' - banner_account_activation_message = '' - display_account_activation_message_on_sidebar = configuration_helpers.get_value( - 'DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR', - settings.FEATURES.get('DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR', False) - ) - - # Display activation message in sidebar if DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR - # flag is active. Otherwise display existing message at the top. - if display_account_activation_message_on_sidebar and not user.is_active: - sidebar_account_activation_message = render_to_string( - 'registration/account_activation_sidebar_notice.html', - { - 'email': user.email, - 'platform_name': platform_name, - 'activation_email_support_link': activation_email_support_link - } - ) - elif not user.is_active: - banner_account_activation_message = render_to_string( - 'registration/activate_account_notice.html', - {'email': user.email} + # Display activation message + activate_account_message = '' + if not user.is_active: + activate_account_message = Text(_( + "Check your {email_start}{email}{email_end} inbox for an account activation link from {platform_name}. " + "If you need help, contact {link_start}{platform_name} Support{link_end}." + )).format( + platform_name=platform_name, + email_start=HTML(""), + email_end=HTML(""), + email=user.email, + link_start=HTML("").format( + activation_email_support_link=activation_email_support_link, + ), + link_end=HTML(""), ) enterprise_message = get_dashboard_consent_notification(request, user, course_enrollments) @@ -789,13 +790,12 @@ def student_dashboard(request): 'enrollment_message': enrollment_message, 'redirect_message': redirect_message, 'account_activation_messages': account_activation_messages, + 'activate_account_message': activate_account_message, 'course_enrollments': course_enrollments, 'course_entitlements': course_entitlements, 'course_entitlement_available_sessions': course_entitlement_available_sessions, 'unfulfilled_entitlement_pseudo_sessions': unfulfilled_entitlement_pseudo_sessions, 'course_optouts': course_optouts, - 'banner_account_activation_message': banner_account_activation_message, - 'sidebar_account_activation_message': sidebar_account_activation_message, 'staff_access': staff_access, 'errored_courses': errored_courses, 'show_courseware_links_for': show_courseware_links_for, @@ -825,6 +825,9 @@ def student_dashboard(request): 'disable_courseware_js': True, 'display_course_modes_on_dashboard': enable_verified_certificates and display_course_modes_on_dashboard, 'display_sidebar_on_dashboard': display_sidebar_on_dashboard, + 'display_sidebar_account_activation_message': not(user.is_active or hide_dashboard_courses_until_activated), + 'display_dashboard_courses': (user.is_active or not hide_dashboard_courses_until_activated), + 'empty_dashboard_message': empty_dashboard_message, } if ecommerce_service.is_enabled(request.user): diff --git a/lms/envs/common.py b/lms/envs/common.py index 2725704ecc..7dd42d762c 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -133,6 +133,9 @@ FEATURES = { # Can be turned off if course lists need to be hidden. Effects views and templates. 'COURSES_ARE_BROWSABLE': True, + # Set to hide the courses list on the Learner Dashboard if they are not enrolled in any courses yet. + 'HIDE_DASHBOARD_COURSES_UNTIL_ACTIVATED': False, + # Enables ability to restrict enrollment in specific courses by the user account login method 'RESTRICT_ENROLL_BY_REG_METHOD': False, @@ -375,9 +378,6 @@ FEATURES = { # See LEARNER-493 'ENABLE_ONE_CLICK_PROGRAM_PURCHASE': False, - # Whether to display account activation notification on dashboard. - 'DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR': False, - # Allow users to change their email address. 'ALLOW_EMAIL_ADDRESS_CHANGE': True, diff --git a/lms/static/sass/multicourse/_dashboard.scss b/lms/static/sass/multicourse/_dashboard.scss index 63b7562195..9c17dab753 100644 --- a/lms/static/sass/multicourse/_dashboard.scss +++ b/lms/static/sass/multicourse/_dashboard.scss @@ -1098,7 +1098,7 @@ .empty-dashboard-message { border: 3px solid $gray-l4; background: $gray-l6; - padding: ($baseline*2) 0; + padding: ($baseline*2) ($baseline/10); text-align: center; p { @@ -1109,7 +1109,13 @@ text-shadow: 0 1px rgba(255,255,255, 0.6); } - a { + p.custom-message { + @include font-size(14); + + text-shadow: none; + } + + a.btn { background-color: theme-color('primary'); border: 1px solid theme-color('primary'); box-shadow: 0 1px 8px 0 $shadow-l1; diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html index 3be671e7ec..5369c2e9f2 100644 --- a/lms/templates/dashboard.html +++ b/lms/templates/dashboard.html @@ -122,10 +122,11 @@ from student.models import CourseEnrollment
-
+ % if display_dashboard_courses: <%include file="learner_dashboard/_dashboard_navigation_courses.html"/> + % endif % if len(course_entitlements + course_enrollments) > 0:
    @@ -195,14 +196,20 @@ from student.models import CourseEnrollment
% else:
-

${_("You are not enrolled in any courses yet.")}

- - % if settings.FEATURES.get('COURSES_ARE_BROWSABLE'): - - ${_("Explore courses")} - - - %endif + % if display_dashboard_courses: +

${_("You are not enrolled in any courses yet.")}

+ % if empty_dashboard_message: +

${empty_dashboard_message | n, decode.utf8}

+ %endif + % if settings.FEATURES.get('COURSES_ARE_BROWSABLE'): + + ${_("Explore courses")} + + %endif + % else: +

${_("Activate your account!")}

+

${ activate_account_message | n, decode.utf8 }

+ % endif
% endif @@ -225,9 +232,9 @@ from student.models import CourseEnrollment
- %if sidebar_account_activation_message: + %if display_sidebar_account_activation_message: %endif diff --git a/lms/templates/registration/account_activation_sidebar_notice.html b/lms/templates/registration/account_activation_sidebar_notice.html index 5fc1a8ca75..be474707d2 100644 --- a/lms/templates/registration/account_activation_sidebar_notice.html +++ b/lms/templates/registration/account_activation_sidebar_notice.html @@ -15,20 +15,7 @@ from openedx.core.djangolib.markup import HTML, Text Notice ${_("Activate your account!")} -

${Text(_( - "Check your {email_start}{email}{email_end} inbox for an account activation link from {platform_name}. " - "If you need help, contact {link_start}{platform_name} Support{link_end}." - )).format( - platform_name=platform_name, - email_start=HTML(""), - email_end=HTML(""), - email=email, - link_start=HTML("").format( - activation_email_support_link=activation_email_support_link, - ), - link_end=HTML(""), - )} -

+

${ activate_account_message | n, decode.utf8 }

## TODO: Add resend activation email functionality. ## TODO: Implementation of this is part of ENT-353. ## diff --git a/lms/templates/registration/activate_account_notice.html b/lms/templates/registration/activate_account_notice.html deleted file mode 100644 index 80b809943e..0000000000 --- a/lms/templates/registration/activate_account_notice.html +++ /dev/null @@ -1,28 +0,0 @@ -<%page expression_filter="h"/> -<%! -from django.utils.translation import ugettext as _ -from openedx.core.djangolib.markup import HTML, Text -%> -
-
-
-

${_("You're almost there!")}

-
-

${Text(_( - "There's just one more step: Before you " - "enroll in a course, you need to activate " - "your account. We've sent an email message to " - "{email_start}{email}{email_end} with " - "instructions for activating your account. If " - "you don't receive this message, check your " - "spam folder." - )).format( - email_start=HTML(""), - email_end=HTML(""), - email=email, - )} -

-
-
-
-
\ No newline at end of file