Merge pull request #18230 from open-craft/jill/empty-dashboard-message-rebase
Learner Dashboard improvements to assist with the Account Activation process (rebased)
This commit is contained in:
@@ -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="<strong>",
|
||||
email_end="</strong>",
|
||||
email=self.user.email,
|
||||
link_start="<a target='_blank' href='{activation_email_support_link}'>".format(
|
||||
activation_email_support_link=self.activation_email_support_link,
|
||||
),
|
||||
link_end="</a>",
|
||||
)
|
||||
|
||||
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):
|
||||
"""
|
||||
|
||||
@@ -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 <i>free</i> 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())
|
||||
|
||||
@@ -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("<strong>"),
|
||||
email_end=HTML("</strong>"),
|
||||
email=user.email,
|
||||
link_start=HTML("<a target='_blank' href='{activation_email_support_link}'>").format(
|
||||
activation_email_support_link=activation_email_support_link,
|
||||
),
|
||||
link_end=HTML("</a>"),
|
||||
)
|
||||
|
||||
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):
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -122,10 +122,11 @@ from student.models import CourseEnrollment
|
||||
|
||||
<main id="main" aria-label="Content" tabindex="-1">
|
||||
<div class="dashboard" id="dashboard-main">
|
||||
|
||||
<div class="main-container">
|
||||
<div class="my-courses" id="my-courses">
|
||||
% if display_dashboard_courses:
|
||||
<%include file="learner_dashboard/_dashboard_navigation_courses.html"/>
|
||||
% endif
|
||||
|
||||
% if len(course_entitlements + course_enrollments) > 0:
|
||||
<ul class="listing-courses">
|
||||
@@ -195,14 +196,20 @@ from student.models import CourseEnrollment
|
||||
</ul>
|
||||
% else:
|
||||
<div class="empty-dashboard-message">
|
||||
<p>${_("You are not enrolled in any courses yet.")}</p>
|
||||
|
||||
% if settings.FEATURES.get('COURSES_ARE_BROWSABLE'):
|
||||
<a class="btn btn-primary" href="${marketing_link('COURSES')}">
|
||||
${_("Explore courses")}
|
||||
</a>
|
||||
|
||||
%endif
|
||||
% if display_dashboard_courses:
|
||||
<p>${_("You are not enrolled in any courses yet.")}</p>
|
||||
% if empty_dashboard_message:
|
||||
<p class="custom-message">${empty_dashboard_message | n, decode.utf8}</p>
|
||||
%endif
|
||||
% if settings.FEATURES.get('COURSES_ARE_BROWSABLE'):
|
||||
<a class="btn btn-primary" href="${marketing_link('COURSES')}">
|
||||
${_("Explore courses")}
|
||||
</a>
|
||||
%endif
|
||||
% else:
|
||||
<p>${_("Activate your account!")}</p>
|
||||
<p class="custom-message">${ activate_account_message | n, decode.utf8 }</p>
|
||||
% endif
|
||||
</div>
|
||||
% endif
|
||||
|
||||
@@ -225,9 +232,9 @@ from student.models import CourseEnrollment
|
||||
</div>
|
||||
</div>
|
||||
<div class="side-container">
|
||||
%if sidebar_account_activation_message:
|
||||
%if display_sidebar_account_activation_message:
|
||||
<div class="sidebar-notification">
|
||||
${sidebar_account_activation_message | n, decode.utf8}
|
||||
<%include file="${static.get_template_path('registration/account_activation_sidebar_notice.html')}" />
|
||||
</div>
|
||||
%endif
|
||||
|
||||
|
||||
@@ -15,20 +15,7 @@ from openedx.core.djangolib.markup import HTML, Text
|
||||
<span class="sr">Notice</span>
|
||||
${_("Activate your account!")}
|
||||
</span>
|
||||
<p class="status-note">${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("<strong>"),
|
||||
email_end=HTML("</strong>"),
|
||||
email=email,
|
||||
link_start=HTML("<a target='_blank' href='{activation_email_support_link}'>").format(
|
||||
activation_email_support_link=activation_email_support_link,
|
||||
),
|
||||
link_end=HTML("</a>"),
|
||||
)}
|
||||
</p>
|
||||
<p class="status-note">${ activate_account_message | n, decode.utf8 }</p>
|
||||
## TODO: Add resend activation email functionality.
|
||||
## TODO: Implementation of this is part of ENT-353.
|
||||
## <button class="btn btn-neutral"><i class="fa fa-envelope-o"></i> Resend Activation Email </button>
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
%>
|
||||
<div class="wrapper-msg urgency-high">
|
||||
<div class="msg">
|
||||
<div class="msg-content">
|
||||
<h2 class="title">${_("You're almost there!")}</h2>
|
||||
<div class="copy">
|
||||
<p class='activation-message'>${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("<strong>"),
|
||||
email_end=HTML("</strong>"),
|
||||
email=email,
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user