diff --git a/lms/djangoapps/commerce/tests/test_views.py b/lms/djangoapps/commerce/tests/test_views.py
index 47fd4240d7..22637c8080 100644
--- a/lms/djangoapps/commerce/tests/test_views.py
+++ b/lms/djangoapps/commerce/tests/test_views.py
@@ -1,18 +1,6 @@
""" Tests for commerce views. """
-
-import json
-
-import ddt
-import mock
-from django.urls import reverse
-
-from course_modes.models import CourseMode
-from openedx.core.djangoapps.theming.tests.test_util import with_comprehensive_theme
-from student.models import CourseEnrollment
from student.tests.factories import UserFactory
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
-from xmodule.modulestore.tests.factories import CourseFactory
class UserMixin(object):
@@ -25,123 +13,3 @@ class UserMixin(object):
def _login(self):
""" Log into LMS. """
self.client.login(username=self.user.username, password='test')
-
-
-@ddt.ddt
-class ReceiptViewTests(UserMixin, ModuleStoreTestCase):
- """ Tests for the receipt view. """
-
- def setUp(self):
- """
- Add a user and a course
- """
- super(ReceiptViewTests, self).setUp()
- self.user = UserFactory()
- self.client.login(username=self.user.username, password='test')
- self.course = CourseFactory.create(
- org='edX',
- course='900',
- run='test_run'
- )
-
- def test_login_required(self):
- """ The view should redirect to the login page if the user is not logged in. """
- self.client.logout()
- response = self.client.post(reverse('commerce:checkout_receipt'))
- self.assertEqual(response.status_code, 302)
-
- def post_to_receipt_page(self, post_data):
- """ DRY helper """
- response = self.client.post(reverse('commerce:checkout_receipt'), params={'basket_id': 1}, data=post_data)
- self.assertEqual(response.status_code, 200)
- return response
-
- def test_user_verification_status_success(self):
- """
- Test user verification status. If the user enrollment for the course belongs to verified modes
- e.g. Verified, Professional then verification is required.
- """
- # Enroll as verified in the course with the current user.
- CourseEnrollment.enroll(self.user, self.course.id, mode=CourseMode.VERIFIED)
- response = self.client.get(
- reverse('commerce:user_verification_status'), data={'course_id': str(self.course.id)}
- )
- json_data = json.loads(response.content.decode('utf-8'))
- self.assertEqual(json_data['is_verification_required'], True)
-
- # Enroll as honor in the course with the current user.
- CourseEnrollment.enroll(self.user, self.course.id, mode=CourseMode.HONOR)
- response = self.client.get(
- reverse('commerce:user_verification_status'), data={'course_id': str(self.course.id)}
- )
- json_data = json.loads(response.content.decode('utf-8'))
- self.assertEqual(json_data['is_verification_required'], False)
-
- def test_user_verification_status_failure(self):
- """
- Test user verification status failure. View should required HttpResponseBadRequest 400 if course id is missing.
- """
- response = self.client.get(reverse('commerce:user_verification_status'))
- self.assertEqual(response.status_code, 400)
-
- @ddt.data('decision', 'reason_code', 'signed_field_names', None)
- def test_is_cybersource(self, post_key):
- """
- Ensure the view uses three specific POST keys to detect a request initiated by Cybersource.
- """
- self._login()
- post_data = {'decision': 'REJECT', 'reason_code': '200', 'signed_field_names': 'dummy'}
- if post_key is not None:
- # a key will be missing; we will not expect the receipt page to handle a cybersource decision
- del post_data[post_key]
- expected_pattern = r"
(\s+)Receipt"
- else:
- expected_pattern = r"(\s+)Payment Failed"
- response = self.post_to_receipt_page(post_data)
- self.assertRegex(response.content.decode('utf-8'), expected_pattern)
-
- @ddt.data('ACCEPT', 'REJECT', 'ERROR')
- def test_cybersource_decision(self, decision):
- """
- Ensure the view renders a page appropriately depending on the Cybersource decision.
- """
- self._login()
- post_data = {'decision': decision, 'reason_code': '200', 'signed_field_names': 'dummy'}
- expected_pattern = r"(\s+)Receipt" if decision == 'ACCEPT' else r"(\s+)Payment Failed"
- response = self.post_to_receipt_page(post_data)
- self.assertRegex(response.content.decode('utf-8'), expected_pattern)
-
- @ddt.data(True, False)
- @mock.patch('lms.djangoapps.commerce.views.is_user_payment_error')
- def test_cybersource_message(self, is_user_message_expected, mock_is_user_payment_error):
- """
- Ensure that the page displays the right message for the reason_code (it
- may be a user error message or a system error message).
- """
- mock_is_user_payment_error.return_value = is_user_message_expected
- self._login()
- response = self.post_to_receipt_page({'decision': 'REJECT', 'reason_code': '99', 'signed_field_names': 'dummy'})
- self.assertTrue(mock_is_user_payment_error.called)
- self.assertTrue(mock_is_user_payment_error.call_args[0][0], '99')
-
- user_message = "There was a problem with this transaction"
- system_message = "A system error occurred while processing your payment"
- self.assertRegex(
- response.content.decode('utf-8'),
- user_message if is_user_message_expected else system_message
- )
- self.assertNotRegex(
- response.content.decode('utf-8'),
- user_message if not is_user_message_expected else system_message
- )
-
- @with_comprehensive_theme("edx.org")
- def test_hide_nav_header(self):
- self._login()
- post_data = {'decision': 'ACCEPT', 'reason_code': '200', 'signed_field_names': 'dummy'}
- response = self.post_to_receipt_page(post_data)
-
- # Verify that the header navigation links are hidden for the edx.org version
- self.assertNotContains(response, "How it Works")
- self.assertNotContains(response, "Find courses")
- self.assertNotContains(response, "Schools & Partners")
diff --git a/lms/djangoapps/commerce/urls.py b/lms/djangoapps/commerce/urls.py
deleted file mode 100644
index b7b31fb6c8..0000000000
--- a/lms/djangoapps/commerce/urls.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-Defines the URL routes for this app.
-"""
-
-
-from django.conf.urls import url
-
-from . import views
-
-app_name = 'commerce'
-urlpatterns = [
- url(r'^checkout/cancel/$', views.checkout_cancel, name='checkout_cancel'),
- url(r'^checkout/error/$', views.checkout_error, name='checkout_error'),
- url(r'^checkout/receipt/$', views.checkout_receipt, name='checkout_receipt'),
- url(r'^checkout/verification_status/$', views.user_verification_status, name='user_verification_status'),
-]
diff --git a/lms/djangoapps/commerce/views.py b/lms/djangoapps/commerce/views.py
deleted file mode 100644
index 1a10ceae6e..0000000000
--- a/lms/djangoapps/commerce/views.py
+++ /dev/null
@@ -1,126 +0,0 @@
-""" Commerce views. """
-
-
-import logging
-
-from django.conf import settings
-from django.contrib.auth.decorators import login_required
-from django.core.cache import cache
-from django.http import HttpResponseBadRequest
-from django.utils.translation import ugettext as _
-from django.views.decorators.csrf import csrf_exempt
-from django.views.decorators.http import require_http_methods
-from opaque_keys.edx.locator import CourseLocator
-
-from course_modes.models import CourseMode
-from edxmako.shortcuts import render_to_response
-from lms.djangoapps.verify_student.services import IDVerificationService
-from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
-from openedx.core.djangoapps.theming.helpers import is_request_in_themed_site
-from openedx.core.djangolib.markup import HTML
-from shoppingcart.processors.CyberSource2 import is_user_payment_error
-from student.models import CourseEnrollment
-from util.json_request import JsonResponse
-
-from .models import CommerceConfiguration
-
-log = logging.getLogger(__name__)
-
-
-@csrf_exempt
-def checkout_cancel(_request):
- """ Checkout/payment cancellation view. """
- context = {
- 'payment_support_email': configuration_helpers.get_value(
- 'payment_support_email', settings.PAYMENT_SUPPORT_EMAIL,
- )
- }
- return render_to_response("commerce/checkout_cancel.html", context)
-
-
-@csrf_exempt
-def checkout_error(_request):
- """ Checkout/payment error view. """
- context = {
- 'payment_support_email': configuration_helpers.get_value(
- 'payment_support_email', settings.PAYMENT_SUPPORT_EMAIL,
- )
- }
- return render_to_response("commerce/checkout_error.html", context)
-
-
-@csrf_exempt
-@login_required
-def checkout_receipt(request):
- """ Receipt view. """
-
- page_title = _('Receipt')
- is_payment_complete = True
- payment_support_email = configuration_helpers.get_value('payment_support_email', settings.PAYMENT_SUPPORT_EMAIL)
- payment_support_link = HTML(u'{email} ').format(email=payment_support_email)
-
- is_cybersource = all(k in request.POST for k in ('signed_field_names', 'decision', 'reason_code'))
- if is_cybersource and request.POST['decision'] != 'ACCEPT':
- # Cybersource may redirect users to this view if it couldn't recover
- # from an error while capturing payment info.
- is_payment_complete = False
- page_title = _('Payment Failed')
- reason_code = request.POST['reason_code']
- # if the problem was with the info submitted by the user, we present more detailed messages.
- if is_user_payment_error(reason_code):
- error_summary = _("There was a problem with this transaction. You have not been charged.")
- error_text = _(
- "Make sure your information is correct, or try again with a different card or another form of payment."
- )
- else:
- error_summary = _("A system error occurred while processing your payment. You have not been charged.")
- error_text = _("Please wait a few minutes and then try again.")
- for_help_text = _(u"For help, contact {payment_support_link}.").format(payment_support_link=payment_support_link)
- else:
- # if anything goes wrong rendering the receipt, it indicates a problem fetching order data.
- error_summary = _("An error occurred while creating your receipt.")
- error_text = None # nothing particularly helpful to say if this happens.
- for_help_text = _(
- u"If your course does not appear on your dashboard, contact {payment_support_link}."
- ).format(payment_support_link=payment_support_link)
-
- commerce_configuration = CommerceConfiguration.current()
- # user order cache should be cleared when a new order is placed
- # so user can see new order in their order history.
- if is_payment_complete and commerce_configuration.enabled and commerce_configuration.is_cache_enabled:
- cache_key = commerce_configuration.CACHE_KEY + '.' + str(request.user.id)
- cache.delete(cache_key)
-
- context = {
- 'page_title': page_title,
- 'is_payment_complete': is_payment_complete,
- 'platform_name': configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME),
- 'verified': IDVerificationService.user_has_valid_or_pending(request.user),
- 'error_summary': error_summary,
- 'error_text': error_text,
- 'for_help_text': for_help_text,
- 'payment_support_email': payment_support_email,
- 'username': request.user.username,
- 'nav_hidden': True,
- 'is_request_in_themed_site': is_request_in_themed_site()
- }
- return render_to_response('commerce/checkout_receipt.html', context)
-
-
-@require_http_methods(["GET"])
-@login_required
-def user_verification_status(request):
- """
- Check for user verification status.
- :return 'True' if the user enrollment for the course belongs to verified modes e.g. Verified, Professional.
- """
- course_id = request.GET.get('course_id', None)
-
- if course_id is None:
- return HttpResponseBadRequest()
-
- course_key = CourseLocator.from_string(course_id)
- enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(request.user, course_key)
- is_verification_required = enrollment_mode in CourseMode.VERIFIED_MODES
-
- return JsonResponse({'is_verification_required': is_verification_required})
diff --git a/lms/static/js/commerce/views/receipt_view.js b/lms/static/js/commerce/views/receipt_view.js
deleted file mode 100644
index 9e377d7e40..0000000000
--- a/lms/static/js/commerce/views/receipt_view.js
+++ /dev/null
@@ -1,382 +0,0 @@
-/**
- * View for the receipt page.
- */
-
-/* globals _, Backbone */
-var edx = edx || {};
-
-(function($, _, Backbone) {
- 'use strict';
-
- edx.commerce = edx.commerce || {};
-
- edx.commerce.ReceiptView = Backbone.View.extend({
- useEcommerceApi: true,
- ecommerceBasketId: null,
- ecommerceOrderNumber: null,
-
- initialize: function() {
- this.ecommerceBasketId = $.url('?basket_id');
- this.ecommerceOrderNumber = $.url('?orderNum');
- this.useEcommerceApi = this.ecommerceBasketId || this.ecommerceOrderNumber;
- _.bindAll(this, 'renderReceipt', 'renderError', 'getProviderData', 'renderProvider', 'getCourseData');
-
- this.render();
- },
-
- /**
- * @param product
- * @returns {bool} True if product requires user to be verified by Software Secure.
- */
- requiresVerification: function(product) {
- function getAttribute(attribute, defaultValue) {
- var attr = _.findWhere(product.attribute_values, {name: attribute});
- if (!attr) {
- return defaultValue;
- }
- return attr.value;
- }
-
- return getAttribute('id_verification_required', true);
- },
-
- renderReceipt: function(data) {
- var templateHtml = $('#receipt-tpl').html(),
- self = this,
- context = {
- platformName: this.$el.data('platform-name'),
- verified: this.$el.data('verified').toLowerCase() === 'true',
- is_request_in_themed_site: this.$el.data('is-request-in-themed-site').toLowerCase() === 'true'
- },
- providerId,
- courseRequiresVerification;
-
- // True if any of the courses bought requires verification
- courseRequiresVerification = _.any(data.lines, function(line) {
- return this.requiresVerification(line.product);
- }, this);
-
- // Add the receipt info to the template context
- this.courseKey = this.getOrderCourseKey(data);
- this.username = this.$el.data('username');
- $.ajax({
- type: 'GET',
- url: '/commerce/checkout/verification_status/',
- data: {course_id: this.courseKey}
- }).success(function(response) {
- _.extend(context, {
- receipt: self.receiptContext(data),
- courseKey: self.courseKey,
- is_verification_required: response.is_verification_required && courseRequiresVerification
- });
-
- self.$el.html(_.template(templateHtml)(context));
-
- self.trackLinks();
-
- self.trackPurchase(data);
-
- self.renderCourseNamePlaceholder(self.courseKey);
-
- self.renderUserFullNamePlaceholder(self.username);
-
- providerId = self.getCreditProviderId(data);
- if (providerId) {
- self.getProviderData(providerId).then(self.renderProvider, self.renderError);
- }
- }).error(function() {
- self.renderError();
- });
- },
- renderCourseNamePlaceholder: function(courseId) {
- // Display the course Id or name (if available) in the placeholder
- var $courseNamePlaceholder = $('.course_name_placeholder');
- $courseNamePlaceholder.text(courseId);
-
- this.getCourseData(courseId).then(function(responseData) {
- $courseNamePlaceholder.text(responseData.name);
- });
- },
- renderUserFullNamePlaceholder: function(username) {
- var userModel = Backbone.Model.extend({
- urlRoot: '/api/user/v1/accounts/',
- url: function() {
- return this.urlRoot + this.id;
- }
- });
- this.user = new userModel({id: username});
- this.user.fetch({success: function(userData) {
- $('.full_name_placeholder').text(userData.get('name'));
- }});
- },
- renderProvider: function(context) {
- var templateHtml = $('#provider-tpl').html(),
- providerDiv = this.$el.find('#receipt-provider');
- context.course_key = this.courseKey;
- context.username = this.username;
- context.platformName = this.$el.data('platform-name');
- providerDiv.html(_.template(templateHtml)(context)).removeClass('hidden');
- },
-
- renderError: function() {
- // Display an error
- $('#error-container').removeClass('hidden');
- },
-
- trackPurchase: function(order) {
- window.analytics.track('Completed Purchase', {
- orderId: order.number,
- total: order.total_excl_tax,
- currency: order.currency
- });
- },
-
- render: function() {
- var self = this,
- orderId = this.ecommerceOrderNumber || this.ecommerceBasketId || $.url('?payment-order-num');
-
- if (orderId && this.$el.data('is-payment-complete') === 'True') {
- // Get the order details
- self.$el.removeClass('hidden');
- self.getReceiptData(orderId).then(self.renderReceipt, self.renderError);
- } else {
- self.renderError();
- }
- },
-
- trackLinks: function() {
- var $verifyNowButton = $('#verify_now_button'),
- $verifyLaterButton = $('#verify_later_button');
-
- // Track a virtual pageview, for easy funnel reconstruction.
- window.analytics.page('payment', 'receipt');
-
- // Track the user's decision to verify immediately
- window.analytics.trackLink($verifyNowButton, 'edx.bi.user.verification.immediate', {
- category: 'verification'
- });
-
- // Track the user's decision to defer their verification
- window.analytics.trackLink($verifyLaterButton, 'edx.bi.user.verification.deferred', {
- category: 'verification'
- });
- },
-
- /**
- * Retrieve receipt data from Oscar (via LMS).
- * @param {string} orderId Identifier of the order that was purchased.
- * @return {object} JQuery Promise.
- */
- getReceiptData: function(orderId) {
- var urlFormat = '/shoppingcart/receipt/{orderId}/';
-
- if (this.ecommerceOrderNumber) {
- urlFormat = '/api/commerce/v1/orders/{orderId}/';
- } else if (this.ecommerceBasketId) {
- urlFormat = '/api/commerce/v0/baskets/{orderId}/order/';
- }
-
- return $.ajax({
- url: edx.StringUtils.interpolate(urlFormat, {orderId: orderId}),
- type: 'GET',
- dataType: 'json'
- }).retry({times: 5, timeout: 2000, statusCodes: [404]});
- },
- /**
- * Retrieve credit provider data from LMS.
- * @param {string} providerId The providerId of the credit provider.
- * @return {object} JQuery Promise.
- */
- getProviderData: function(providerId) {
- var providerUrl = '/api/credit/v1/providers/{providerId}/';
-
- return $.ajax({
- url: edx.StringUtils.interpolate(providerUrl, {providerId: providerId}),
- type: 'GET',
- dataType: 'json',
- contentType: 'application/json',
- headers: {
- 'X-CSRFToken': $.cookie('csrftoken')
- }
- }).retry({times: 5, timeout: 2000, statusCodes: [404]});
- },
- /**
- * Retrieve course data from LMS.
- * @param {string} courseId The courseId of the course.
- * @return {object} JQuery Promise.
- */
- getCourseData: function(courseId) {
- var courseDetailUrl = '/api/courses/v1/courses/{courseId}/';
- return $.ajax({
- url: edx.StringUtils.interpolate(courseDetailUrl, {courseId: courseId}),
- type: 'GET',
- dataType: 'json'
- });
- },
-
- /**
- * Construct the template context from data received
- * from the E-Commerce API.
- *
- * @param {object} order Receipt data received from the server
- * @return {object} Receipt template context.
- */
- receiptContext: function(order) {
- var self = this,
- receiptContext;
-
- if (this.useEcommerceApi) {
- receiptContext = {
- orderNum: order.number,
- currency: order.currency,
- purchasedDatetime: order.date_placed,
- totalCost: self.formatMoney(order.total_excl_tax),
- isRefunded: false,
- items: [],
- billedTo: null
- };
-
- if (order.billing_address) {
- receiptContext.billedTo = {
- firstName: order.billing_address.first_name,
- lastName: order.billing_address.last_name,
- city: order.billing_address.city,
- state: order.billing_address.state,
- postalCode: order.billing_address.postcode,
- country: order.billing_address.country
- };
- }
-
- receiptContext.items = _.map(
- order.lines,
- function(line) {
- return {
- lineDescription: line.description,
- cost: self.formatMoney(line.line_price_excl_tax)
- };
- }
- );
- } else {
- receiptContext = {
- orderNum: order.orderNum,
- currency: order.currency,
- purchasedDatetime: order.purchase_datetime,
- totalCost: self.formatMoney(order.total_cost),
- isRefunded: order.status === 'refunded',
- billedTo: {
- firstName: order.billed_to.first_name,
- lastName: order.billed_to.last_name,
- city: order.billed_to.city,
- state: order.billed_to.state,
- postalCode: order.billed_to.postal_code,
- country: order.billed_to.country
- },
- items: []
- };
-
- receiptContext.items = _.map(
- order.items,
- function(item) {
- return {
- lineDescription: item.line_desc,
- cost: self.formatMoney(item.line_cost)
- };
- }
- );
- }
-
- return receiptContext;
- },
-
- getOrderCourseKey: function(order) {
- var length, items;
- if (this.useEcommerceApi) {
- length = order.lines.length;
- for (var i = 0; i < length; i++) {
- var line = order.lines[i],
- attributeValues = _.find(line.product.attribute_values, function(attribute) {
- // If the attribute has a 'code' property, compare its value, otherwise compare 'name'
- var value_to_match = 'course_key';
- if (attribute.code) {
- return attribute.code === value_to_match;
- } else {
- return attribute.name === value_to_match;
- }
- });
-
- // This method assumes that all items in the order are related to a single course.
- if (attributeValues != undefined) {
- return attributeValues.value;
- }
- }
- } else {
- items = _.filter(order.items, function(item) {
- return item.course_key;
- });
-
- if (items.length > 0) {
- return items[0].course_key;
- }
- }
-
- return null;
- },
-
- formatMoney: function(moneyStr) {
- return Number(moneyStr).toFixed(2);
- },
-
- /**
- * Check whether the payment is for the credit course or not.
- *
- * @param {object} order Receipt data received from the server
- * @return {string} String of the provider_id or null.
- */
- getCreditProviderId: function(order) {
- var attributeValues,
- line = order.lines[0];
- if (this.useEcommerceApi) {
- attributeValues = _.find(line.product.attribute_values, function(attribute) {
- return attribute.name === 'credit_provider';
- });
-
- // This method assumes that all items in the order are related to a single course.
- if (attributeValues != undefined) {
- return attributeValues.value;
- }
- }
-
- return null;
- }
- });
-
- new edx.commerce.ReceiptView({
- el: $('#receipt-container')
- });
-}(jQuery, _, Backbone));
-
-function completeOrder(event) {
- 'use strict';
- var courseKey = $(event).data('course-key'),
- username = $(event).data('username'),
- providerId = $(event).data('provider'),
- $errorContainer = $('#error-container');
-
- try {
- event.preventDefault();
- } catch (err) {
- // Ignore the error as not all event inputs have the preventDefault method.
- }
-
- analytics.track(
- 'edx.bi.credit.clicked_complete_credit',
- {
- category: 'credit',
- label: courseKey
- }
- );
-
- edx.commerce.credit.createCreditRequest(providerId, courseKey, username).fail(function() {
- $errorContainer.removeClass('hidden');
- });
-}
diff --git a/lms/static/js/fixtures/commerce/checkout_receipt.html b/lms/static/js/fixtures/commerce/checkout_receipt.html
deleted file mode 100644
index 9c0809a701..0000000000
--- a/lms/static/js/fixtures/commerce/checkout_receipt.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
Loading Order Data...
- Please wait while we retrieve your order details.
-
-
-
-
diff --git a/lms/static/js/spec/commerce/receipt_view_spec.js b/lms/static/js/spec/commerce/receipt_view_spec.js
deleted file mode 100644
index ea00ed44fd..0000000000
--- a/lms/static/js/spec/commerce/receipt_view_spec.js
+++ /dev/null
@@ -1,338 +0,0 @@
-define([
- 'jquery',
- 'jquery.ajax-retry',
- 'js/commerce/views/receipt_view',
- 'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers'
-],
- function($, AjaxRetry, ReceiptView, AjaxHelpers) {
- 'use strict';
- describe('edx.commerce.ReceiptView', function() {
- var data, courseResponseData, providerResponseData, mockRequests, mockRender, createReceiptView,
- createProduct, createLine, createOrderResponse, doCheckVerification, doCheckVerificationNagRendered,
- userResponseData;
-
- createReceiptView = function() {
- return new ReceiptView({el: $('#receipt-container')});
- };
-
- mockRequests = function(requests, method, apiUrl, responseData) {
- AjaxHelpers.expectRequest(requests, method, apiUrl);
- AjaxHelpers.respondWithJson(requests, responseData);
- };
-
- mockRender = function(useEcommerceOrderNumber, isVerified, requestInThemedSite) {
- var requests, view, orderUrlFormat,
- actualRequestInThemedSite = requestInThemedSite;
- if (typeof actualRequestInThemedSite === 'undefined') {
- actualRequestInThemedSite = 'False';
- }
- requests = AjaxHelpers.requests(this);
- $('#receipt-container').data({
- verified: isVerified,
- 'is-request-in-themed-site': actualRequestInThemedSite
- });
- view = createReceiptView();
- view.useEcommerceApi = true;
- if (useEcommerceOrderNumber) {
- view.ecommerceOrderNumber = 'EDX-123456';
- orderUrlFormat = '/api/commerce/v1/orders/EDX-123456/';
- } else {
- view.ecommerceBasketId = 'EDX-123456';
- orderUrlFormat = '/api/commerce/v0/baskets/EDX-123456/order/';
- }
- view.render();
- mockRequests(requests, 'GET', orderUrlFormat, data);
-
- mockRequests(
- requests, 'GET', '/commerce/checkout/verification_status/?course_id=' +
- encodeURIComponent('course-v1:edx+dummy+2015_T3'), {is_verification_required: true}
- );
-
- mockRequests(
- requests, 'GET', '/api/courses/v1/courses/course-v1:edx+dummy+2015_T3/', courseResponseData
- );
-
- mockRequests(
- requests, 'GET', '/api/user/v1/accounts/user-1', userResponseData
- );
-
- mockRequests(requests, 'GET', '/api/credit/v1/providers/edx/', providerResponseData);
- return view;
- };
-
- createProduct = function(attributes) {
- var actualAttributes = attributes;
- if (typeof actualAttributes === 'undefined') {
- actualAttributes = [
- {
- name: 'certificate_type',
- value: 'verified'
- },
- {
- name: 'course_key',
- code: 'course_key',
- value: 'course-v1:edx+dummy+2015_T3'
- },
- {
- name: 'credit_provider',
- value: 'edx'
- }
- ];
- }
-
- return {
- attribute_values: actualAttributes,
- stockrecords: [
- {
- price_currency: 'USD',
- product: 123,
- partner_sku: '1234ABC',
- partner: 1,
- price_excl_tax: '10.00',
- id: 123
- }
- ],
- product_class: 'Seat',
- title: 'Dummy title',
- url: 'https://ecom.edx.org/api/v2/products/123/',
- price: '10.00',
- expires: null,
- is_available_to_buy: true,
- id: 123,
- structure: 'child'
- };
- };
-
- createLine = function(product) {
- var actualProduct = product;
- if (typeof actualProduct === 'undefined') {
- actualProduct = createProduct();
- }
- return {
- status: 'Open',
- unit_price_excl_tax: '10.00',
- product: actualProduct,
- line_price_excl_tax: '10.00',
- description: 'dummy description',
- title: 'dummy title',
- quantity: 1
- };
- };
-
- createOrderResponse = function(lines) {
- var actualLines = lines;
- if (typeof actualLines === 'undefined') {
- actualLines = [createLine()];
- }
- return {
- status: 'Open',
- billed_to: {
- city: 'dummy city',
- first_name: 'john',
- last_name: 'doe',
- country: 'AL',
- line2: 'line2',
- line1: 'line1',
- state: '',
- postcode: '12345'
- },
- lines: actualLines,
- number: 'EDX-123456',
- date_placed: '2016-01-01T01:01:01Z',
- currency: 'USD',
- total_excl_tax: '10.00'
- };
- };
-
- doCheckVerification = function(attributes, expected) {
- var view = createReceiptView(),
- product = createProduct(attributes);
- expect(view.requiresVerification(product)).toBe(expected);
- };
-
- doCheckVerificationNagRendered = function(attributes, userVerified, expected, requestInThemedSite) {
- var view;
- data = createOrderResponse([createLine(createProduct(attributes))]);
- view = mockRender(true, userVerified, requestInThemedSite);
- if (expected) {
- expect(view.$('.nav-wizard.is-ready').text()).toContain('Want to confirm your identity later');
- } else {
- expect(view.$('.nav-wizard.is-ready').text()).toContain('Go to Dashboard');
- }
- };
-
- beforeEach(function() {
- var receiptFixture, providerFixture;
- // Stub analytics tracking
- window.analytics = jasmine.createSpyObj('analytics', ['page', 'track', 'trackLink']);
-
- loadFixtures('js/fixtures/commerce/checkout_receipt.html');
-
- receiptFixture = readFixtures('templates/commerce/receipt.underscore');
- providerFixture = readFixtures('templates/commerce/provider.underscore');
- appendSetFixtures(
- '' +
- ''
- );
-
- data = createOrderResponse();
-
- providerResponseData = {
- id: 'edx',
- display_name: 'edX',
- url: 'http://www.edx.org',
- status_url: 'http://www.edx.org/status',
- description: 'Nothing',
- enable_integration: false,
- fulfillment_instructions: '',
- thumbnail_url: 'http://edx.org/thumbnail.png'
- };
-
- courseResponseData = {
- id: 'course-v1:edx+dummy+2015_T3',
- name: 'receipt test',
- category: 'course',
- org: 'edx',
- run: '2015_T2',
- course: 'CS420',
- uri: 'http://test.com/api/courses/v1/courses/course-v1:edx+dummy+2015_T3/',
- image_url: '/test.jpg',
- start: '2030-01-01T00:00:00Z',
- end: null
- };
- userResponseData = {
- username: 'user-1',
- name: 'full name'
- };
- });
-
- it('sends analytic event when verified receipt is rendered', function() {
- mockRender(true, 'True');
- expect(window.analytics.track).toHaveBeenCalledWith(
- 'Completed Purchase',
- {
- orderId: 'EDX-123456',
- total: '10.00',
- currency: 'USD'
- }
- );
- });
-
- it('sends analytic event when non verified receipt is rendered', function() {
- mockRender(true, 'False');
- expect(window.analytics.track).toHaveBeenCalledWith(
- 'Completed Purchase',
- {
- orderId: 'EDX-123456',
- total: '10.00',
- currency: 'USD'
- }
- );
- });
-
- it('renders a receipt correctly with Ecommerce Order Number', function() {
- var view;
-
- view = mockRender(true, 'True');
- expect(view.$('.course_name_placeholder').text()).toContain('receipt test');
- });
-
- it('renders a receipt correctly with Ecommerce Basket Id', function() {
- var view;
-
- view = mockRender(false, 'True');
- expect(view.$('.course_name_placeholder').text()).toContain('receipt test');
- });
-
- it('requiresVerification returns true if product requires verification', function() {
- var expected = true,
- attributes = [
- {name: 'certificate_type', value: 'professional'},
- {name: 'course_key', value: 'course-v1:OC+OC+2'},
- {name: 'id_verification_required', value: true}
- ];
- doCheckVerification(attributes, expected, 'False');
- });
-
- it('requiresVerification returns true if product requires verification, different order', function() {
- var expected = true,
- attributes = [
- {name: 'certificate_type', value: 'professional'},
- {name: 'id_verification_required', value: true},
- {name: 'course_key', value: 'course-v1:OC+OC+2'}
- ];
- doCheckVerification(attributes, expected, 'False');
- });
-
- it('requiresVerification defaults to true', function() {
- var expected = true,
- attributes = [
- {name: 'certificate_type', value: 'professional'},
- {name: 'course_key', value: 'course-v1:OC+OC+2'}
- ];
- doCheckVerification(attributes, expected, 'False');
- });
-
- it('requiresVerification returns false for courses not requiring verification', function() {
- var expected = false,
- attributes = [
- {name: 'certificate_type', value: 'professional'},
- {name: 'id_verification_required', value: false},
- {name: 'course_key', value: 'course-v1:OC+OC+2'}
- ];
- doCheckVerification(attributes, expected, 'False');
- });
-
- it('receipt view verification nag for not verified users in a verified course', function() {
- var attributes = [
- {name: 'certificate_type', value: 'professional'},
- {name: 'id_verification_required', value: true},
- {name: 'course_key', value: 'course-v1:edx+dummy+2015_T3'},
- {name: 'credit_provider', value: 'edx'}
- ];
- doCheckVerificationNagRendered(attributes, 'False', true, 'False');
- });
-
- it("receipt view doesn't show verification nag for a verified user in a verified course", function() {
- var attributes = [
- {name: 'certificate_type', value: 'professional'},
- {name: 'id_verification_required', value: true},
- {name: 'course_key', value: 'course-v1:edx+dummy+2015_T3'},
- {name: 'credit_provider', value: 'edx'}
- ];
- doCheckVerificationNagRendered(attributes, 'True', false, 'False');
- });
-
- it("receipt view doesn't show verification for a unverified user in a not verified course", function() {
- var attributes = [
- {name: 'certificate_type', value: 'professional'},
- {name: 'id_verification_required', value: false},
- {name: 'course_key', value: 'course-v1:edx+dummy+2015_T3'},
- {name: 'credit_provider', value: 'edx'}
- ];
- doCheckVerificationNagRendered(attributes, 'False', false, 'False');
- });
-
- it("receipt view doesn't show verification nag for a verified user in a not verified course", function() {
- var attributes = [
- {name: 'certificate_type', value: 'professional'},
- {name: 'id_verification_required', value: false},
- {name: 'course_key', value: 'course-v1:edx+dummy+2015_T3'},
- {name: 'credit_provider', value: 'edx'}
- ];
- doCheckVerificationNagRendered(attributes, 'True', false, 'False');
- });
-
- it("receipt view doesn't show verification nag for a not verified user in a verified" +
- ' course on themed site', function() {
- var attributes = [
- {name: 'certificate_type', value: 'professional'},
- {name: 'id_verification_required', value: true},
- {name: 'course_key', value: 'course-v1:edx+dummy+2015_T3'},
- {name: 'credit_provider', value: 'edx'}
- ];
- doCheckVerificationNagRendered(attributes, 'False', false, 'True');
- });
- });
- }
-);
diff --git a/lms/static/lms/js/spec/main.js b/lms/static/lms/js/spec/main.js
index 8de036f33a..7c0cdb2c12 100644
--- a/lms/static/lms/js/spec/main.js
+++ b/lms/static/lms/js/spec/main.js
@@ -79,7 +79,6 @@
// Manually specify LMS files that are not converted to RequireJS
'history': 'js/vendor/history',
- 'js/commerce/views/receipt_view': 'js/commerce/views/receipt_view',
'js/staff_debug_actions': 'js/staff_debug_actions',
'js/vendor/jquery.qubit': 'js/vendor/jquery.qubit',
'js/utils/navigation': 'js/utils/navigation',
@@ -347,10 +346,6 @@
exports: 'js/ccx/schedule',
deps: ['jquery', 'underscore', 'backbone', 'gettext', 'moment']
},
- 'js/commerce/views/receipt_view': {
- exports: 'edx.commerce.ReceiptView',
- deps: ['jquery', 'jquery.url', 'backbone', 'underscore', 'string_utils']
- },
// Backbone classes loaded explicitly until they are converted to use RequireJS
'js/instructor_dashboard/ecommerce': {
@@ -714,7 +709,6 @@
'js/learner_dashboard/spec/unenroll_view_spec.js',
'js/spec/api_admin/catalog_preview_spec.js',
'js/spec/ccx/schedule_spec.js',
- 'js/spec/commerce/receipt_view_spec.js',
'js/spec/components/card/card_spec.js',
'js/spec/components/header/header_spec.js',
'js/spec/course_sharing/course_sharing_events_spec.js',
diff --git a/lms/templates/commerce/checkout_cancel.html b/lms/templates/commerce/checkout_cancel.html
deleted file mode 100644
index 08566ddb3c..0000000000
--- a/lms/templates/commerce/checkout_cancel.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<%page expression_filter="h"/>
-<%! from django.utils.translation import ugettext as _
-from openedx.core.djangolib.markup import HTML, Text
-%>
-
-<%inherit file="../main.html" />
-
-<%block name="pagetitle">${_("Checkout Cancelled")}%block>
-
-
-
- ${_("Checkout Cancelled")}
- ${ Text(_(u"Your transaction has been cancelled. If you feel an error has occurred, contact {email}.")).format(
- email=HTML("{email} ").format(email=payment_support_email)) }
-
diff --git a/lms/templates/commerce/checkout_error.html b/lms/templates/commerce/checkout_error.html
deleted file mode 100644
index ecc8dc596a..0000000000
--- a/lms/templates/commerce/checkout_error.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<%page expression_filter="h"/>
-<%! from django.utils.translation import ugettext as _
-from openedx.core.djangolib.markup import HTML, Text
-%>
-
-<%inherit file="../main.html" />
-
-<%block name="pagetitle">${_("Checkout Error")}%block>
-
-
-
- ${_("Checkout Error")}
- ${ Text(_(u"An error has occurred with your payment. {b_start}You have not been charged.{b_end} Please try to submit your payment again. If this problem persists, contact {email}.")).format(
- b_start=HTML(''),
- b_end=HTML(' '),
- email=HTML("{email} ").format(email=payment_support_email)) }
-
diff --git a/lms/templates/commerce/checkout_receipt.html b/lms/templates/commerce/checkout_receipt.html
deleted file mode 100644
index 2b89d30100..0000000000
--- a/lms/templates/commerce/checkout_receipt.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<%page expression_filter="h"/>
-<%!
-from django.utils.translation import ugettext as _
-%>
-<%namespace name='static' file='../static_content.html'/>
-
-<%inherit file="../main.html" />
-<%block name="bodyclass">register verification-process step-requirements%block>
-
-<%block name="pagetitle">${page_title}%block>
-
-<%block name="header_extras">
-
-
-
-%block>
-<%block name="js_extra">
-
-
-
-
-%block>
-
-<%block name="content">
-
-
-
-
-
-
- ${error_summary}
- ${error_summary}
-
- %if error_text:
-
- %endif
-
-
-
-
-
-
-
-
-
-
${_("Loading Order Data...")}
- ${ _("Please wait while we retrieve your order details.") }
-
-
-
-%block>
diff --git a/lms/templates/commerce/provider.underscore b/lms/templates/commerce/provider.underscore
deleted file mode 100644
index d86955eb39..0000000000
--- a/lms/templates/commerce/provider.underscore
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
- <%- edx.StringUtils.interpolate(
- gettext("You still need to visit the {display_name} website to complete the credit process."),
- { display_name: display_name })
- %>
-
-
- <%- edx.StringUtils.interpolate(
- gettext("To finalize course credit, {display_name} requires {platform_name} learners to submit a credit request."),
- { display_name: display_name, platform_name: platformName })
- %>
-
-
- <%- fulfillment_instructions %>
-
-
-
-
diff --git a/lms/templates/commerce/receipt.underscore b/lms/templates/commerce/receipt.underscore
deleted file mode 100644
index 9a434efe60..0000000000
--- a/lms/templates/commerce/receipt.underscore
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
- <%= edx.HtmlUtils.interpolateHtml(
- gettext( "Thank you {full_name}! We have received your payment for {course_name}."),
- {
- course_name: edx.HtmlUtils.HTML(" "),
- full_name: edx.HtmlUtils.HTML(" ")
- })
- %>
-
-
- <% if ( receipt ) { %>
-
-
-
-
<%- gettext( "Please print this page for your records; it serves as your receipt. You will also receive an email with the same information." ) %>
-
-
-
-
-
-
- <%- gettext( "Order No." ) %>
- <%- gettext( "Description" ) %>
- <%- gettext( "Date" ) %>
- <%- gettext( "Amount" ) %>
-
-
-
-
- <% for ( var i = 0; i < receipt.items.length; i++ ) { %>
- <% if ( receipt.isRefunded ) { %>
- <%- receipt.orderNum %>
- <%- receipt.items[i].lineDescription %>
- <%- receipt.purchasedDatetime %>
- <%- receipt.items[i].cost %> (<%- receipt.currency.toUpperCase() %>)
- <% } else { %>
-
- <%- receipt.orderNum %>
- <%- receipt.items[i].lineDescription %>
- <%- receipt.purchasedDatetime %>
- <%- receipt.items[i].cost %> (<%- receipt.currency.toUpperCase() %>)
-
- <% } %>
- <% } %>
-
-
-
-
- <%- gettext( "Total" ) %>
-
-
- <%- receipt.totalCost %>
- (<%- receipt.currency.toUpperCase() %>)
-
-
-
-
-
- <% if ( receipt.isRefunded ) { %>
-
-
<%- gettext( "Please Note" ) %>:
-
-
<%- gettext( "Crossed out items have been refunded." ) %>
-
-
- <% } %>
-
-
- <% if ( receipt.billedTo ) { %>
-
-
<%- gettext( "Billed to" ) %>:
- <%- receipt.billedTo.firstName %>
- <%- receipt.billedTo.lastName %>
- (<%- receipt.billedTo.city %> ,
- <%- receipt.billedTo.state %>
- <%- receipt.billedTo.postalCode %>
- <%- receipt.billedTo.country.toUpperCase() %> )
-
-
- <% } %>
-
-
-
-
-
- <% } else { %>
- <%- gettext( "No receipt available" ) %>
- <% } %>
-
-
- <% if ( !is_verification_required || verified || is_request_in_themed_site) { %>
- <%- gettext( "Go to Dashboard" ) %>
- <% } else { %>
- ">
- <%- gettext( "Want to confirm your identity later?" ) %>
-
-
-
- <%- gettext( "Verify Now" ) %>
-
- <% } %>
-
-
-
diff --git a/lms/urls.py b/lms/urls.py
index 11eb68908f..b4c018227d 100644
--- a/lms/urls.py
+++ b/lms/urls.py
@@ -817,7 +817,6 @@ if configuration_helpers.get_value('ENABLE_BULK_ENROLLMENT_VIEW', settings.FEATU
# Shopping cart
urlpatterns += [
url(r'^shoppingcart/', include('shoppingcart.urls')),
- url(r'^commerce/', include(('lms.djangoapps.commerce.urls', 'lms.djangoapps.commerce'), namespace='commerce')),
]
# Course goals