Merge pull request #14444 from edx/aj/TNL-6381_upsell_msg
Aj/tnl 6381 upsell msg
This commit is contained in:
@@ -191,7 +191,6 @@ $btn-border-radius: $component-border-radius !default;
|
||||
$btn-large-padding-vertical: spacing-vertical(small);
|
||||
$btn-large-padding-horizontal: spacing-horizontal(mid-large);
|
||||
|
||||
|
||||
$btn-base-padding-vertical: spacing-vertical(x-small);
|
||||
$btn-base-padding-horizontal: spacing-horizontal(base);
|
||||
$btn-base-font-size: font-size(base);
|
||||
|
||||
@@ -45,6 +45,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
days_till_upgrade_deadline=4,
|
||||
enroll_user=True,
|
||||
enrollment_mode=CourseMode.VERIFIED,
|
||||
user_enrollment_mode=None,
|
||||
course_min_price=100,
|
||||
days_till_verification_deadline=14,
|
||||
verification_status=None,
|
||||
@@ -72,8 +73,11 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
)
|
||||
|
||||
if enroll_user:
|
||||
enrollment_mode = enrollment_mode or CourseMode.DEFAULT_MODE_SLUG
|
||||
CourseEnrollmentFactory.create(course_id=self.course.id, user=self.user, mode=enrollment_mode)
|
||||
if user_enrollment_mode:
|
||||
CourseEnrollmentFactory.create(course_id=self.course.id, user=self.user, mode=user_enrollment_mode)
|
||||
else:
|
||||
enrollment_mode = enrollment_mode or CourseMode.DEFAULT_MODE_SLUG
|
||||
CourseEnrollmentFactory.create(course_id=self.course.id, user=self.user, mode=enrollment_mode)
|
||||
|
||||
if days_till_verification_deadline is not None:
|
||||
VerificationDeadline.objects.create(
|
||||
@@ -274,18 +278,64 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
)
|
||||
self.assertEqual(block.title, 'Course End')
|
||||
|
||||
## Tests Verified Upgrade Deadline Date Block
|
||||
# Tests Verified Upgrade Deadline Date Block
|
||||
|
||||
def check_upgrade_banner(self, banner_expected=True, include_url_parameter=True):
|
||||
"""
|
||||
Helper method to check for the presence of the Upgrade Banner
|
||||
"""
|
||||
url = reverse('info', args=[self.course.id.to_deprecated_string()])
|
||||
if include_url_parameter:
|
||||
url += '?upgrade=true'
|
||||
resp = self.client.get(url)
|
||||
expected_banner_text = "Give yourself an additional incentive to complete"
|
||||
if banner_expected:
|
||||
self.assertIn(expected_banner_text, resp.content)
|
||||
else:
|
||||
self.assertNotIn(expected_banner_text, resp.content)
|
||||
|
||||
@freeze_time('2015-01-02')
|
||||
def test_verified_upgrade_deadline_date(self):
|
||||
self.setup_course_and_user(days_till_upgrade_deadline=1)
|
||||
self.setup_course_and_user(days_till_upgrade_deadline=1, user_enrollment_mode=CourseMode.AUDIT)
|
||||
self.client.login(username='mrrobot', password='test')
|
||||
block = VerifiedUpgradeDeadlineDate(self.course, self.user)
|
||||
self.assertEqual(block.date, datetime.now(utc) + timedelta(days=1))
|
||||
self.assertTrue(block.is_enabled)
|
||||
self.assertEqual(block.link, reverse('verify_student_upgrade_and_verify', args=(self.course.id,)))
|
||||
self.check_upgrade_banner()
|
||||
|
||||
def test_without_upgrade_deadline(self):
|
||||
self.setup_course_and_user(enrollment_mode=None)
|
||||
self.client.login(username='mrrobot', password='test')
|
||||
block = VerifiedUpgradeDeadlineDate(self.course, self.user)
|
||||
self.assertFalse(block.is_enabled)
|
||||
self.assertIsNone(block.date)
|
||||
self.check_upgrade_banner(banner_expected=False)
|
||||
|
||||
@freeze_time('2015-01-02')
|
||||
def test_verified_upgrade_banner_not_present_past_deadline(self):
|
||||
self.setup_course_and_user(days_till_upgrade_deadline=-1, user_enrollment_mode=CourseMode.AUDIT)
|
||||
self.client.login(username='mrrobot', password='test')
|
||||
block = VerifiedUpgradeDeadlineDate(self.course, self.user)
|
||||
self.assertFalse(block.is_enabled)
|
||||
self.check_upgrade_banner(banner_expected=False)
|
||||
|
||||
@freeze_time('2015-01-02')
|
||||
def test_verified_upgrade_banner_cookie(self):
|
||||
self.setup_course_and_user(days_till_upgrade_deadline=1, user_enrollment_mode=CourseMode.AUDIT)
|
||||
self.client.login(username='mrrobot', password='test')
|
||||
|
||||
# No URL parameter or cookie present, notification should not be shown.
|
||||
self.check_upgrade_banner(include_url_parameter=False, banner_expected=False)
|
||||
|
||||
# Now pass URL parameter-- notification should be shown.
|
||||
self.check_upgrade_banner(include_url_parameter=True)
|
||||
|
||||
# A cookie should be set in the previous call, so it is no longer necessary to pass
|
||||
# the URL parameter in order to see the notification.
|
||||
self.check_upgrade_banner(include_url_parameter=False)
|
||||
|
||||
# Unfortunately (according to django doc), it is not possible to test expiration of the cookie.
|
||||
|
||||
def test_ecommerce_checkout_redirect(self):
|
||||
"""Verify the block link redirects to ecommerce checkout if it's enabled."""
|
||||
|
||||
@@ -65,6 +65,7 @@ from courseware.courses import (
|
||||
sort_by_start_date,
|
||||
UserNotEnrolled
|
||||
)
|
||||
from courseware.date_summary import VerifiedUpgradeDeadlineDate
|
||||
from courseware.masquerade import setup_masquerade
|
||||
from courseware.model_data import FieldDataCache
|
||||
from courseware.models import StudentModule, BaseStudentModuleHistory
|
||||
@@ -343,6 +344,22 @@ def course_info(request, course_id):
|
||||
if settings.FEATURES.get('ENABLE_MKTG_SITE'):
|
||||
url_to_enroll = marketing_link('COURSES')
|
||||
|
||||
store_upgrade_cookie = False
|
||||
upgrade_cookie_name = 'show_upgrade_notification'
|
||||
upgrade_link = None
|
||||
if request.user.is_authenticated():
|
||||
show_upgrade_notification = False
|
||||
if request.GET.get('upgrade', 'false') == 'true':
|
||||
store_upgrade_cookie = True
|
||||
show_upgrade_notification = True
|
||||
elif upgrade_cookie_name in request.COOKIES and bool(request.COOKIES[upgrade_cookie_name]):
|
||||
show_upgrade_notification = True
|
||||
|
||||
if show_upgrade_notification:
|
||||
upgrade_data = VerifiedUpgradeDeadlineDate(course, user)
|
||||
if upgrade_data.is_enabled:
|
||||
upgrade_link = upgrade_data.link
|
||||
|
||||
context = {
|
||||
'request': request,
|
||||
'masquerade_user': user,
|
||||
@@ -354,6 +371,7 @@ def course_info(request, course_id):
|
||||
'studio_url': studio_url,
|
||||
'show_enroll_banner': show_enroll_banner,
|
||||
'url_to_enroll': url_to_enroll,
|
||||
'upgrade_link': upgrade_link
|
||||
}
|
||||
|
||||
# Get the URL of the user's last position in order to display the 'where you were last' message
|
||||
@@ -371,7 +389,17 @@ def course_info(request, course_id):
|
||||
if CourseEnrollment.is_enrolled(request.user, course.id):
|
||||
inject_coursetalk_keys_into_context(context, course_key)
|
||||
|
||||
return render_to_response('courseware/info.html', context)
|
||||
response = render_to_response('courseware/info.html', context)
|
||||
if store_upgrade_cookie:
|
||||
response.set_cookie(
|
||||
upgrade_cookie_name,
|
||||
True,
|
||||
max_age=10 * 24 * 60 * 60, # set for 10 days
|
||||
domain=settings.SESSION_COOKIE_DOMAIN,
|
||||
httponly=True # no use case for accessing from JavaScript
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def get_last_accessed_courseware(course, request, user):
|
||||
|
||||
BIN
lms/static/images/edx-verified-mini-cert.png
Normal file
BIN
lms/static/images/edx-verified-mini-cert.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.9 KiB |
@@ -9,7 +9,13 @@
|
||||
});
|
||||
});
|
||||
$('.date-summary-verified-upgrade-deadline .date-summary-link').on('click', function() {
|
||||
Logger.log('edx.course.home.upgrade_verified.clicked', {});
|
||||
Logger.log('edx.course.home.upgrade_verified.clicked', {location: 'sidebar'});
|
||||
});
|
||||
$('.upgrade-banner-button').on('click', function() {
|
||||
Logger.log('edx.course.home.upgrade_verified.clicked', {location: 'notification'});
|
||||
});
|
||||
$('.view-verified-info').on('click', function() {
|
||||
Logger.log('edx.course.home.learn_about_verified.clicked', {location: 'notification'});
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
<div class="upgrade-banner">
|
||||
<div class="notification-color-border"></div>
|
||||
<div class="notification-content">
|
||||
<div class="upgrade-icon">
|
||||
<img src="${STATIC_URL}images/edx-verified-mini-cert.png">
|
||||
</div>
|
||||
<div class="upgrade-msg">
|
||||
<h4 class="upgrade-msg">Give yourself an additional incentive to complete</h4>
|
||||
<p class="view-verified-info">Earn a verified certificate
|
||||
<a href="https://www.edx.org/verified-certificate" target="_blank">Learn More</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="upgrade-banner-button">
|
||||
<a href="/verify_student/upgrade/course-v1:Test+TestX+2015" class="btn-upgrade">Upgrade Now</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="date-summary-container">
|
||||
<div class="date-summary date-summary-verified-upgrade-deadline">
|
||||
<h3 class="heading">Verification Upgrade Deadline</h3>
|
||||
|
||||
@@ -17,9 +17,23 @@ define(['jquery', 'logger', 'js/courseware/course_home_events'], function($, Log
|
||||
});
|
||||
});
|
||||
|
||||
it('sends an event when "Upgrade to Verified" is clicked', function() {
|
||||
it('sends an event when "Upgrade to Verified" is clicked from the sidebar', function() {
|
||||
$('.date-summary-link').click();
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.course.home.upgrade_verified.clicked', {});
|
||||
expect(Logger.log).toHaveBeenCalledWith('edx.course.home.upgrade_verified.clicked', {location: 'sidebar'});
|
||||
});
|
||||
|
||||
it('sends an event when "Upgrade Now" is clicked from the upsell notification', function() {
|
||||
$('.upgrade-banner-button').click();
|
||||
expect(Logger.log).toHaveBeenCalledWith(
|
||||
'edx.course.home.upgrade_verified.clicked', {location: 'notification'}
|
||||
);
|
||||
});
|
||||
|
||||
it('sends an event when "Learn More" is clicked from the upsell notification', function() {
|
||||
$('.view-verified-info').click();
|
||||
expect(Logger.log).toHaveBeenCalledWith(
|
||||
'edx.course.home.learn_about_verified.clicked', {location: 'notification'}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
// Upgrade button
|
||||
$btn-upgrade-border-color: $uxpl-green-base !default;
|
||||
$btn-upgrade-background: $uxpl-green-base !default;
|
||||
$btn-upgrade-color: #fcfcfc !default;
|
||||
$btn-upgrade-focus-color: $btn-upgrade-color !default;
|
||||
$btn-upgrade-focus-border-color: rgb(0, 155, 0) !default;
|
||||
$btn-upgrade-focus-background: rgb(0, 155, 0) !default;
|
||||
$btn-upgrade-active-border-color: $uxpl-green-base !default;
|
||||
$btn-upgrade-active-background: $uxpl-green-base !default;
|
||||
|
||||
//// Notifications
|
||||
// Upgrade
|
||||
|
||||
$notification-highlight-border-color: $uxpl-green-base !default;
|
||||
$lms-border-color: $uxpl-gray-background !default;
|
||||
$notification-background: rgb(255, 255, 255) !default
|
||||
|
||||
.home {
|
||||
@include clearfix();
|
||||
max-width: 1140px;
|
||||
@@ -56,6 +73,110 @@ div.info-wrapper {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
div.upgrade-banner {
|
||||
// This banner uses the Pattern Library's defined variables
|
||||
@include border-left(0px);
|
||||
|
||||
border: 1px solid $lms-border-color;
|
||||
width: 100%;
|
||||
display: table;
|
||||
|
||||
.notification-color-border {
|
||||
width: 6px; //Value defined by UX team
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
display: table-cell;
|
||||
background: $notification-highlight-border-color;
|
||||
}
|
||||
|
||||
.notification-content {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
align-content: flex-start;
|
||||
flex-flow: row wrap;
|
||||
background: $notification-background;
|
||||
width: 100%;
|
||||
padding: $baseline/2 0;
|
||||
margin-bottom: 0;
|
||||
justify-content: space-between;
|
||||
|
||||
.upgrade-icon {
|
||||
margin: 0;
|
||||
padding: $baseline/2 $baseline;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
// flex: grow, shrink, base
|
||||
// The 7 was the value that allowed the icon image to grow to the UX
|
||||
// desired size.
|
||||
flex: 7 1 50px;
|
||||
// The following dimensions were added so that the
|
||||
// icon will adjust as the notification is adjusted
|
||||
// but will not be smaller or larger than UX requirements.
|
||||
min-height: 50px;
|
||||
min-width: 80px;
|
||||
max-height: 90px;
|
||||
max-width: 130px;
|
||||
|
||||
img {
|
||||
min-height: 50px;
|
||||
min-width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.upgrade-msg {
|
||||
flex: 5 1 60%; //This percentage was required to get the text
|
||||
// in the message to wrap when collapsed.
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
padding: $baseline/2 0;
|
||||
.msg-title {
|
||||
font-weight: font-weight(semi-bold);
|
||||
font-size: font-size(large);
|
||||
line-height: $base-line-height;
|
||||
}
|
||||
.view-verified-info {
|
||||
margin-top: $baseline/4;
|
||||
font-weight: font-weight(normal);
|
||||
font-size: font-size(base);
|
||||
}
|
||||
|
||||
a:link, a:hover, a:visited, a:active {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
|
||||
.upgrade-banner-button {
|
||||
@include margin(0, 0, 0, auto);
|
||||
padding: $baseline/2 $baseline;
|
||||
}
|
||||
|
||||
.btn-upgrade {
|
||||
@extend %btn-shims;
|
||||
|
||||
border-color: $btn-upgrade-border-color;
|
||||
background: $btn-upgrade-background;
|
||||
color: $btn-upgrade-color;
|
||||
// STATE: hover and focus
|
||||
&:hover,
|
||||
&.is-hovered,
|
||||
&:focus,
|
||||
&.is-focused {
|
||||
border-color: $btn-upgrade-focus-border-color;
|
||||
background-color: $btn-upgrade-focus-background;
|
||||
color: $btn-upgrade-focus-color;
|
||||
}
|
||||
|
||||
// STATE: is disabled
|
||||
&:disabled,
|
||||
&.is-disabled {
|
||||
border-color: $btn-disabled-border-color;
|
||||
background: $btn-brand-disabled-background;
|
||||
color: $btn-upgrade-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> p {
|
||||
margin-bottom: lh();
|
||||
}
|
||||
|
||||
@@ -81,6 +81,26 @@ from openedx.core.djangolib.markup import HTML, Text
|
||||
</div>
|
||||
% endif
|
||||
|
||||
% if upgrade_link:
|
||||
<div class="upgrade-banner">
|
||||
<div class="notification-color-border"></div>
|
||||
<div class="notification-content">
|
||||
<div class="upgrade-icon">
|
||||
<img src="${STATIC_URL}images/edx-verified-mini-cert.png">
|
||||
</div>
|
||||
<div class="upgrade-msg">
|
||||
<h4 class="msg-title">${_("Give yourself an additional incentive to complete")}</h4>
|
||||
<p class="view-verified-info">${_("Earn a verified certificate.")}
|
||||
<a href="https://www.edx.org/verified-certificate" target="_blank">${_("Learn More")}</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="upgrade-banner-button">
|
||||
<a href="${upgrade_link}" class="btn-upgrade">${_("Upgrade Now")}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<h4>${_("Course Updates and News")}</h4>
|
||||
${HTML(get_course_info_section(request, masquerade_user, course, 'updates'))}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user