diff --git a/common/djangoapps/student/tests/test_activate_account.py b/common/djangoapps/student/tests/test_activate_account.py index 56f9b052b5..8d4bcffa15 100644 --- a/common/djangoapps/student/tests/test_activate_account.py +++ b/common/djangoapps/student/tests/test_activate_account.py @@ -3,10 +3,12 @@ from mock import patch import unittest from django.conf import settings -from django.contrib.auth.models import User from django.test import TestCase, override_settings +from django.core.urlresolvers import reverse +from edxmako.shortcuts import render_to_string from student.models import Registration +from student.tests.factories import UserFactory @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @@ -17,13 +19,38 @@ class TestActivateAccount(TestCase): super(TestActivateAccount, self).setUp() self.username = "jack" self.email = "jack@fake.edx.org" - self.user = User.objects.create(username=self.username, email=self.email, is_active=False) + self.password = "test-password" + self.user = UserFactory.create( + username=self.username, email=self.email, password=self.password, is_active=False, + ) # Set Up Registration self.registration = Registration() self.registration.register(self.user) self.registration.save() + def login(self): + """ + Login with test user. + + Since, only active users can login, so we must activate the user before login. + This method does the following tasks in order, + 1. Stores user's active/in-active status in a variable. + 2. Makes sure user account is active. + 3. Authenticated user with the client. + 4. Reverts user's original active/in-active status. + """ + is_active = self.user.is_active + + # Make sure user is active before login + self.user.is_active = True + self.user.save() + self.client.login(username=self.username, password=self.password) + + # Revert user activation status + self.user.is_active = is_active + self.user.save() + def assert_no_tracking(self, mock_segment_identify): """ Assert that activate sets the flag but does not call segment. """ # Ensure that the user starts inactive @@ -76,3 +103,59 @@ class TestActivateAccount(TestCase): @patch('student.models.analytics.identify') 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. + + If logged in user has not activated his/her account, make sure that an + account activation message is displayed on dashboard sidebar. + """ + # Log in with test user. + self.login() + expected_message = render_to_string( + 'registration/account_activation_sidebar_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/account_activation_sidebar_notice.html', + {'email': self.user.email} + ) + 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) diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 2cdf3ffe09..381c51a9a3 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -685,9 +685,22 @@ def dashboard(request): course_optouts = Optout.objects.filter(user=user).values_list('course_id', flat=True) - message = "" - if not user.is_active: - message = render_to_string( + 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} + ) + elif not user.is_active: + banner_account_activation_message = render_to_string( 'registration/activate_account_notice.html', {'email': user.email, 'platform_name': platform_name} ) @@ -819,7 +832,8 @@ def dashboard(request): 'redirect_message': redirect_message, 'course_enrollments': course_enrollments, 'course_optouts': course_optouts, - 'message': message, + '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, diff --git a/lms/envs/common.py b/lms/envs/common.py index a8b6d94d50..fbba924d80 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -377,6 +377,9 @@ FEATURES = { # Enable one click program purchase # See LEARNER-493 'ENABLE_ONE_CLICK_PROGRAM_PURCHASE': False, + + # Whether to display account activation notification on dashboard. + 'DISPLAY_ACCOUNT_ACTIVATION_MESSAGE_ON_SIDEBAR': False, } # Ignore static asset files on import which match this pattern diff --git a/lms/static/sass/multicourse/_dashboard.scss b/lms/static/sass/multicourse/_dashboard.scss index 5718bc4d72..1fae8f0982 100644 --- a/lms/static/sass/multicourse/_dashboard.scss +++ b/lms/static/sass/multicourse/_dashboard.scss @@ -1227,6 +1227,35 @@ border-bottom-color: $m-gray-l4; } } + + // Warning for status verification + &.warning { + border-top: 3px solid #ffc01f !important; + + .status-title { + font-weight: 400 !important; + + .fa { + color: #ffc01f; + } + } + + .btn { + font-size: 16px; + line-height: 25.16px; + padding: 10px 10px; + border: 1px solid #0079bc; + color: #0079bc; + text-decoration: none; + display: block; + } + .btn:hover { + cursor: pointer; + color: #fff; + background-color: #0079bc; + } + + } } // status - verification diff --git a/lms/templates/dashboard.html b/lms/templates/dashboard.html index faf9ed0fae..0e57bc3973 100644 --- a/lms/templates/dashboard.html +++ b/lms/templates/dashboard.html @@ -62,9 +62,10 @@ from openedx.core.djangolib.markup import HTML, Text
- %if message: + + %if banner_account_activation_message:
- ${message | n, decode.utf8} + ${banner_account_activation_message | n, decode.utf8}
%endif @@ -137,6 +138,12 @@ from openedx.core.djangolib.markup import HTML, Text % endif
+ %if sidebar_account_activation_message: + + %endif + % if settings.FEATURES.get('ENABLE_DASHBOARD_SEARCH'):