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:
Albert (AJ) St. Aubin
2018-05-18 12:58:12 -04:00
committed by GitHub
8 changed files with 111 additions and 127 deletions

View File

@@ -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):
"""

View File

@@ -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())

View File

@@ -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):

View File

@@ -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,

View File

@@ -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;

View File

@@ -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

View File

@@ -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>

View File

@@ -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>