Merge pull request #1744 from edx/flowerhack/feature/verified-cert-events

Events for entering verified flow & buying
This commit is contained in:
Julia Hansbrough
2013-12-10 11:47:47 -08:00
9 changed files with 101 additions and 10 deletions

View File

@@ -37,6 +37,7 @@ class ChooseModeView(View):
enrollment_mode = CourseEnrollment.enrollment_mode_for_user(request.user, course_id)
upgrade = request.GET.get('upgrade', False)
request.session['attempting_upgrade'] = upgrade
# verified users do not need to register or upgrade
if enrollment_mode == 'verified':

View File

@@ -35,9 +35,7 @@ from track import contexts
from track.views import server_track
from eventtracking import tracker
unenroll_done = Signal(providing_args=["course_enrollment"])
log = logging.getLogger(__name__)
AUDIT_LOG = logging.getLogger("audit")

View File

@@ -95,4 +95,4 @@ Feature: LMS.Verified certificates
Then I see the course on my dashboard
And I see that I am on the verified track
And a "edx.course.enrollment.activated" server event is emitted
And a "edx.course.enrollment.upgrade.succeeded" server event is emitted

View File

@@ -557,6 +557,7 @@ class CertificateItem(OrderItem):
"""
super(CertificateItem, cls).add_to_order(order, course_id, cost, currency=currency)
course_enrollment = CourseEnrollment.get_or_create_enrollment(order.user, course_id)
# do some validation on the enrollment mode
@@ -570,7 +571,7 @@ class CertificateItem(OrderItem):
user=order.user,
course_id=course_id,
course_enrollment=course_enrollment,
mode=mode
mode=mode,
)
item.status = order.status
item.qty = 1
@@ -595,7 +596,6 @@ class CertificateItem(OrderItem):
log.exception(
"Could not submit verification attempt for enrollment {}".format(self.course_enrollment)
)
self.course_enrollment.change_mode(self.mode)
self.course_enrollment.activate()

View File

@@ -6,7 +6,7 @@ import StringIO
from textwrap import dedent
from boto.exception import BotoServerError # this is a super-class of SESError and catches connection errors
from mock import patch, MagicMock
from mock import patch, MagicMock, sentinel
from django.core import mail
from django.conf import settings
from django.db import DatabaseError
@@ -425,12 +425,21 @@ class CertificateItemTest(ModuleStoreTestCase):
min_price=self.cost)
course_mode.save()
patcher = patch('student.models.server_track')
self.mock_server_track = patcher.start()
self.addCleanup(patcher.stop)
crum_patcher = patch('student.models.crum.get_current_request')
self.mock_get_current_request = crum_patcher.start()
self.addCleanup(crum_patcher.stop)
self.mock_get_current_request.return_value = sentinel.request
def test_existing_enrollment(self):
CourseEnrollment.enroll(self.user, self.course_id)
cart = Order.get_cart_for_user(user=self.user)
CertificateItem.add_to_order(cart, self.course_id, self.cost, 'verified')
# verify that we are still enrolled
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course_id))
self.mock_server_track.reset_mock()
cart.purchase()
enrollment = CourseEnrollment.objects.get(user=self.user, course_id=self.course_id)
self.assertEquals(enrollment.mode, u'verified')

View File

@@ -20,7 +20,7 @@ from student.models import CourseEnrollment
from course_modes.models import CourseMode
from edxmako.shortcuts import render_to_response
from shoppingcart.processors import render_purchase_form_html
from mock import patch, Mock
from mock import patch, Mock, sentinel
def mock_render_purchase_form_html(*args, **kwargs):
@@ -39,6 +39,8 @@ postpay_mock = Mock()
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
class ShoppingCartViewsTests(ModuleStoreTestCase):
def setUp(self):
patcher = patch('student.models.server_track')
self.mock_server_track = patcher.start()
self.user = UserFactory.create()
self.user.set_password('password')
self.user.save()
@@ -53,6 +55,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
self.verified_course_id = 'org/test/Test_Course'
CourseFactory.create(org='org', number='test', run='course1', display_name='Test Course')
self.cart = Order.get_cart_for_user(self.user)
self.addCleanup(patcher.stop)
def login_user(self):
self.client.login(username=self.user.username, password="password")
@@ -83,6 +86,7 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
def test_add_course_to_cart_success(self):
self.login_user()
reverse('shoppingcart.views.add_course_to_cart', args=[self.course_id])
resp = self.client.post(reverse('shoppingcart.views.add_course_to_cart', args=[self.course_id]))
self.assertEqual(resp.status_code, 200)
self.assertTrue(PaidCourseRegistration.contained_in_order(self.cart, self.course_id))
@@ -202,6 +206,55 @@ class ShoppingCartViewsTests(ModuleStoreTestCase):
self.assertIn(cert_item, context['order_items'])
self.assertFalse(context['any_refunds'])
@patch('shoppingcart.views.render_to_response', render_mock)
def test_show_receipt_success_with_upgrade(self):
reg_item = PaidCourseRegistration.add_to_order(self.cart, self.course_id)
cert_item = CertificateItem.add_to_order(self.cart, self.verified_course_id, self.cost, 'honor')
self.cart.purchase(first='FirstNameTesting123', street1='StreetTesting123')
self.login_user()
# When we come from the upgrade flow, we'll have a session variable showing that
s = self.client.session
s['attempting_upgrade'] = True
s.save()
self.mock_server_track.reset_mock()
resp = self.client.get(reverse('shoppingcart.views.show_receipt', args=[self.cart.id]))
# Once they've upgraded, they're no longer *attempting* to upgrade
attempting_upgrade = self.client.session.get('attempting_upgrade', False)
self.assertFalse(attempting_upgrade)
self.assertEqual(resp.status_code, 200)
self.assertIn('FirstNameTesting123', resp.content)
self.assertIn('80.00', resp.content)
((template, context), _) = render_mock.call_args
# When we come from the upgrade flow, we get these context variables
self.assertEqual(template, 'shoppingcart/receipt.html')
self.assertEqual(context['order'], self.cart)
self.assertIn(reg_item, context['order_items'])
self.assertIn(cert_item, context['order_items'])
self.assertFalse(context['any_refunds'])
course_enrollment = CourseEnrollment.get_or_create_enrollment(self.user, self.course_id)
course_enrollment.emit_event('edx.course.enrollment.upgrade.succeeded')
self.mock_server_track.assert_any_call(
None,
'edx.course.enrollment.upgrade.succeeded',
{
'user_id': course_enrollment.user.id,
'course_id': course_enrollment.course_id,
'mode': course_enrollment.mode
}
)
@patch('shoppingcart.views.render_to_response', render_mock)
def test_show_receipt_success_refund(self):
reg_item = PaidCourseRegistration.add_to_order(self.cart, self.course_id)

View File

@@ -12,11 +12,14 @@ from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
from edxmako.shortcuts import render_to_response
from .models import Order, PaidCourseRegistration, OrderItem
from student.models import CourseEnrollment
from .processors import process_postpay_callback, render_purchase_form_html
from .exceptions import ItemAlreadyInCartException, AlreadyEnrolledInCourseException, CourseDoesNotExistException
log = logging.getLogger("shoppingcart")
EVENT_NAME_USER_UPGRADED = 'edx.course.enrollment.upgrade.succeeded'
@require_POST
def add_course_to_cart(request, course_id):
@@ -124,6 +127,13 @@ def show_receipt(request, ordernum):
receipt_template = order_items[0].single_item_receipt_template
context.update(order_items[0].single_item_receipt_context)
# Only orders where order_items.count() == 1 might be attempting to upgrade
attempting_upgrade = request.session.get('attempting_upgrade', False)
if attempting_upgrade:
course_enrollment = CourseEnrollment.get_or_create_enrollment(request.user, order_items[0].course_id)
course_enrollment.emit_event(EVENT_NAME_USER_UPGRADED)
request.session['attempting_upgrade'] = False
return render_to_response(receipt_template, context)

View File

@@ -2,6 +2,7 @@
<%!
from django.core.urlresolvers import reverse
import waffle
%>
<%inherit file="main.html" />
@@ -22,6 +23,21 @@
$(this).closest('.message.is-expandable').toggleClass('is-expanded');
}
$("#upgrade-to-verified").click(function(event) {
user = $(event.target).data("user");
course = $(event.target).data("course-id");
Logger.log('edx.course.enrollment.upgrade.clicked', [user, course], null);
% if waffle.flag_is_active(request, 'alternate_upsell_copy'):
analytics.track("Clicked on Alternate Upsell Copy", {
course: course
});
% else:
analytics.track("Clicked on Regular Upsell Copy", {
course: course
});
% endif
});
$(".email-settings").click(function(event) {
$("#email_settings_course_id").val( $(event.target).data("course-id") );
$("#email_settings_course_number").text( $(event.target).data("course-number") );

View File

@@ -61,13 +61,17 @@
<%include file='_dashboard_certificate_information.html' args='cert_status=cert_status,course=course, enrollment=enrollment'/>
% endif
%if course_mode_info['show_upsell']:
% if course_mode_info['show_upsell']:
<div class="message message-upsell has-actions is-expandable is-shown">
<div class="wrapper-tip">
<h4 class="message-title">
<i class="icon-caret-down ui-toggle-expansion"></i>
<span class="value">${_("Challenge Yourself!")}</span>
% if waffle.flag_is_active(request, 'alternate_upsell_copy'):
<span class="value">${_("Document your accomplishment!")}</span>
% else:
<span class="value">${_("Challenge Yourself!")}</span>
% endif
</h4>
<p class="message-copy">${_("Take this course as an ID-verified student.")}</p>
</div>
@@ -80,7 +84,7 @@
<a class="action action-upgrade" href="${reverse('course_modes_choose', kwargs={'course_id': course.id})}?upgrade=True">
<img class="deco-graphic" src="${static.url('images/vcert-ribbon-s.png')}" alt="ID Verified Ribbon/Badge">
<span class="wrapper-copy">
<span class="copy">${_("Upgrade to Verified Track")}</span>
<span class="copy" id="upgrade-to-verified" data-course-id="${course.id}" data-user="${user.username}">${_("Upgrade to Verified Track")}</span>
</span>
</a>
</li>