Commit b4b931d9 by Vedran Karacic Committed by Vedran Karačić

Revert "Change enrollment code redemption to the receipt page."

This reverts commit 42527ff3.
parent 42527ff3
import datetime
import urllib
import ddt
import httpretty
import mock
import pytz
from django.conf import settings
from django.core.urlresolvers import reverse
......@@ -22,9 +20,6 @@ from ecommerce.coupons.views import voucher_is_valid
from ecommerce.courses.tests.factories import CourseFactory
from ecommerce.extensions.api import exceptions
from ecommerce.extensions.catalogue.tests.mixins import CourseCatalogTestMixin
from ecommerce.extensions.checkout.mixins import EdxOrderPlacementMixin
from ecommerce.extensions.checkout.utils import get_receipt_page_url
from ecommerce.extensions.fulfillment.status import ORDER
from ecommerce.extensions.test.factories import prepare_voucher
from ecommerce.extensions.voucher.utils import get_voucher_and_products_from_code
from ecommerce.tests.mixins import ApiMockMixin, LmsApiMockMixin
......@@ -36,7 +31,6 @@ Benefit = get_model('offer', 'Benefit')
Catalog = get_model('catalogue', 'Catalog')
Course = get_model('courses', 'Course')
Product = get_model('catalogue', 'Product')
Order = get_model('order', 'Order')
OrderLineVouchers = get_model('voucher', 'OrderLineVouchers')
StockRecord = get_model('partner', 'StockRecord')
Voucher = get_model('voucher', 'Voucher')
......@@ -268,7 +262,6 @@ class CouponOfferViewTests(ApiMockMixin, CouponMixin, CourseCatalogTestMixin, Lm
self.assertEqual(response.status_code, 200)
@ddt.ddt
class CouponRedeemViewTests(CouponMixin, CourseCatalogTestMixin, LmsApiMockMixin, TestCase):
redeem_url = reverse('coupons:redeem')
......@@ -286,6 +279,7 @@ class CouponRedeemViewTests(CouponMixin, CourseCatalogTestMixin, LmsApiMockMixin
self.stock_record = StockRecord.objects.get(product=self.seat)
self.catalog = Catalog.objects.create(partner=self.partner)
self.catalog.stock_records.add(StockRecord.objects.get(product=self.seat))
self.student_dashboard_url = get_lms_url(self.site.siteconfiguration.student_dashboard_url)
def redeem_url_with_params(self, code=COUPON_CODE):
""" Constructs the coupon redemption URL with the proper string query parameters. """
......@@ -303,23 +297,12 @@ class CouponRedeemViewTests(CouponMixin, CourseCatalogTestMixin, LmsApiMockMixin
self.assertEqual(Voucher.objects.filter(code=coupon_code).count(), 1)
return coupon_code
def assert_redemption_page_redirects(self, expected_url, target=200, code=COUPON_CODE, query_string=''):
def assert_redemption_page_redirects(self, expected_url, target=200, code=COUPON_CODE):
""" Verify redirect from redeem page to expected page. """
self.request.user = self.user
self.mock_enrollment_api(self.request, self.user, self.course.id, is_active=False, mode=self.course_mode)
response = self.client.get(self.redeem_url_with_params(code=code))
if query_string:
order = Order.objects.latest()
expected_url = '{url}?{query_string}={order_num}'.format(
url=expected_url,
query_string=query_string,
order_num=order.number
)
self.assertRedirects(
response, expected_url, status_code=302, target_status_code=target, fetch_redirect_response=False
)
self.assertRedirects(response, expected_url, status_code=302, target_status_code=target)
def test_login_required(self):
""" Users are required to login before accessing the view. """
......@@ -375,75 +358,29 @@ class CouponRedeemViewTests(CouponMixin, CourseCatalogTestMixin, LmsApiMockMixin
self.assert_redemption_page_redirects(expected_url)
@httpretty.activate
@ddt.data(
(True, 'order_number'),
(False, 'orderNum')
)
@ddt.unpack
def test_basket_redirect_enrollment_code(self, ecomm_receipt, query_string):
""" Verify the view redirects to a receipt page when an enrollment code is provided. """
self.toggle_ecommerce_receipt_page(ecomm_receipt)
def test_basket_redirect_enrollment_code(self):
""" Verify the view redirects to LMS when an enrollment code is provided. """
code = self.create_and_test_coupon_and_return_code(benefit_value=100, code='')
receipt_page_url = get_receipt_page_url(self.site.siteconfiguration)
enrollment_api_url = '{root}{enrollment}'.format(
root=self.site.siteconfiguration.enrollment_api_url,
enrollment='enrollment'
)
httpretty.register_uri(httpretty.POST, enrollment_api_url, status=status.HTTP_200_OK)
httpretty.register_uri(httpretty.GET, receipt_page_url, status=status.HTTP_301_MOVED_PERMANENTLY)
httpretty.register_uri(httpretty.GET, self.student_dashboard_url, status=status.HTTP_301_MOVED_PERMANENTLY)
self.mock_account_api(self.request, self.user.username, data={'is_active': True})
self.assert_redemption_page_redirects(
receipt_page_url,
target=status.HTTP_301_MOVED_PERMANENTLY,
code=code,
query_string=query_string
)
@httpretty.activate
@mock.patch.object(EdxOrderPlacementMixin, 'place_free_order')
def test_basket_redirect_enrollment_code_error(self, place_free_order):
""" Verify the view redirects to checkout error page when an order is not completed. """
code = self.create_and_test_coupon_and_return_code(benefit_value=100, code='')
self.mock_account_api(self.request, self.user.username, data={'is_active': True})
open_order = OrderFactory(status=ORDER.OPEN)
place_free_order.return_value = open_order
self.assert_redemption_page_redirects(
self.get_full_url(reverse('checkout:error')),
self.student_dashboard_url,
target=status.HTTP_301_MOVED_PERMANENTLY,
code=code
)
@httpretty.activate
@ddt.data(
(True, 'order_number'),
(False, 'orderNum')
)
@ddt.unpack
def test_multiple_vouchers(self, ecomm_receipt, query_string):
def test_multiple_vouchers(self):
""" Verify a redirect to LMS happens when a basket with already existing vouchers is used. """
self.toggle_ecommerce_receipt_page(ecomm_receipt)
receipt_page_url = get_receipt_page_url(self.site.siteconfiguration)
code = self.create_and_test_coupon_and_return_code(benefit_value=100, code='')
basket = Basket.get_basket(self.user, self.site)
basket.vouchers.add(Voucher.objects.get(code=code))
enrollment_api_url = '{root}{enrollment}'.format(
root=self.site.siteconfiguration.enrollment_api_url,
enrollment='enrollment'
)
httpretty.register_uri(httpretty.POST, enrollment_api_url, status=status.HTTP_200_OK)
self.mock_account_api(self.request, self.user.username, data={'is_active': True})
httpretty.register_uri(httpretty.GET, receipt_page_url, status=status.HTTP_301_MOVED_PERMANENTLY)
httpretty.register_uri(httpretty.GET, self.student_dashboard_url, status=status.HTTP_301_MOVED_PERMANENTLY)
self.assert_redemption_page_redirects(
receipt_page_url,
self.student_dashboard_url,
target=status.HTTP_301_MOVED_PERMANENTLY,
code=code,
query_string=query_string
code=code
)
@httpretty.activate
......
......@@ -2,7 +2,6 @@ from __future__ import unicode_literals
import csv
import logging
import time
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
......@@ -22,8 +21,6 @@ from ecommerce.coupons.decorators import login_required_for_credit
from ecommerce.extensions.api import exceptions
from ecommerce.extensions.basket.utils import prepare_basket
from ecommerce.extensions.checkout.mixins import EdxOrderPlacementMixin
from ecommerce.extensions.checkout.utils import get_receipt_page_url
from ecommerce.extensions.fulfillment.status import ORDER
from ecommerce.extensions.voucher.utils import get_voucher_and_products_from_code
Applicator = get_class('offer.utils', 'Applicator')
......@@ -164,22 +161,11 @@ class CouponRedeemView(EdxOrderPlacementMixin, View):
basket = prepare_basket(request, product, voucher)
if basket.total_excl_tax == 0:
order = self.place_free_order(basket)
# Waiting for the order to finish its async fulfillment.
# Every 2 seconds the order status is checked. If after three checks
# it's not complete or the status is an error, user is redirected
# to the checkout error page.
for __ in range(3): # pragma: no cover
order.refresh_from_db()
if order.status == ORDER.COMPLETE:
return HttpResponseRedirect(get_receipt_page_url(self.request.site.siteconfiguration, order.number))
elif order.status == ORDER.FULFILLMENT_ERROR:
return HttpResponseRedirect(reverse('checkout:error'))
time.sleep(2) # pragma: no cover
return HttpResponseRedirect(reverse('checkout:error'))
return HttpResponseRedirect(reverse('basket:summary'))
self.place_free_order(basket)
else:
return HttpResponseRedirect(reverse('basket:summary'))
return HttpResponseRedirect(request.site.siteconfiguration.student_dashboard_url)
class EnrollmentCodeCsvView(View):
......
......@@ -74,8 +74,8 @@ class OrderListViewTests(AccessTokenMixin, ThrottlingMixin, TestCase):
content = json.loads(response.content)
self.assertEqual(content['count'], 2)
self.assertEqual(content['results'][0]['number'], unicode(order.number))
self.assertEqual(content['results'][1]['number'], unicode(order_2.number))
self.assertEqual(content['results'][0]['number'], unicode(order_2.number))
self.assertEqual(content['results'][1]['number'], unicode(order.number))
def test_with_other_users_orders(self):
""" The view should only return orders for the authenticated users. """
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('order', '0011_auto_20161025_1446'),
]
operations = [
migrations.AlterModelOptions(
name='historicalorder',
options={'ordering': ('-history_date', '-history_id'), 'get_latest_by': 'history_date', 'verbose_name': 'historical order'},
),
migrations.AlterModelOptions(
name='order',
options={'get_latest_by': 'date_placed'},
),
]
......@@ -21,9 +21,6 @@ class Order(AbstractOrder):
return any(line.product.get_product_class().name == 'Coupon' for line in
self.basket.all_lines())
class Meta(object):
get_latest_by = 'date_placed'
class PaymentEvent(AbstractPaymentEvent):
processor_name = models.CharField(_("Payment Processor"), max_length=32, blank=True, null=True)
......
......@@ -150,19 +150,6 @@ define([
expect(view.collection.previousPage).toHaveBeenCalled();
});
it('should disable the enrollment button', function() {
var ev = $.Event('click');
$('body').append('<a class="btn-success redeem-enrollment"></a>');
view.disableReedemEnrollmentBtn(ev);
expect(ev.isDefaultPrevented()).toBeFalsy();
expect($('.redeem-enrollment').attr('disabled')).toEqual('disabled');
expect($('.redeem-enrollment').hasClass('btn-default')).toBeTruthy();
expect($('.redeem-enrollment').hasClass('btn-success')).toBeFalsy();
view.disableReedemEnrollmentBtn(ev);
expect(ev.isDefaultPrevented()).toBeTruthy();
});
it('should create list item', function() {
var value = view.createListItem(1, false),
string = '<li class="page-item">' +
......
......@@ -24,8 +24,7 @@ define([
events: {
'click .prev': 'previous',
'click .next': 'next',
'click .page-number': 'goToPage',
'click .redeem-enrollment': 'disableReedemEnrollmentBtn'
'click .page-number': 'goToPage'
},
initialize: function (options) {
......@@ -33,18 +32,6 @@ define([
this.code = options.code;
},
disableReedemEnrollmentBtn: function(event) {
var btn = $('.redeem-enrollment');
if (btn.attr('disabled')) {
event.preventDefault();
} else {
btn.text('Enrolling...')
.attr('disabled', true)
.removeClass('btn-success')
.addClass('btn-default');
}
},
changePage: function() {
this.$el.html(
this.template({
......
......@@ -29,6 +29,7 @@
// views
// --------------------
@import 'views/basket';
@import 'views/cancel_error';
@import 'views/credit';
@import 'views/course_admin';
@import 'views/coupon_admin';
......
.receipt-cancel-error {
font-family: $font-family-sans-serif;
h1 {
font-weight: 600;
margin-bottom: 30px;
text-align: center;
}
.nav-link {
border-bottom: none;
text-decoration: none !important;
&:active, &:hover, &:focus {
border-bottom: 1px dotted #0079bc;
}
}
p {
font-size: large;
}
}
\ No newline at end of file
......@@ -310,8 +310,4 @@
color: #6B6969;
}
.btn-default[disabled]:hover,
.btn-default[disabled]:focus {
color: #333;
}
}
......@@ -70,7 +70,8 @@
<% } else { %>
<% if (isEnrollmentCode) { %>
<a href="/coupons/redeem/?code=<%= code %>&sku=<%= course.attributes.stockrecords.partner_sku %>"
class="btn btn-success redeem-enrollment"><%- gettext('Enroll Now') %></a>
id="RedeemEnrollment"
class="btn btn-success"><%- gettext('Enroll Now') %></a>
<% } else { %>
<a href="/coupons/redeem/?code=<%= code %>&sku=<%= course.attributes.stockrecords.partner_sku %>"
id="PurchaseCertificate"
......
......@@ -4,27 +4,23 @@
{% block title %}
{% trans "Checkout Error" %}
{% endblock %}
{% endblock title %}
{% block navbar %}
{% include 'edx/partials/_student_navbar.html' %}
{% endblock %}
{% endblock navbar %}
{% block content %}
<div id="error-message">
<div class="container">
<div class="depth depth-2 message-error-content">
<h1>{% trans "Checkout Error" %}</h1>
<h3>{{ error }}</h3>
<p>{% blocktrans %} An error has occurred with your payment. <b>You have not been charged.</b>
{% endblocktrans %}</p>
<p>{% with "<a class='nav-link' href='mailto:"|add:payment_support_email|add:"'>"|safe as start_link %}
{% blocktrans with end_link="</a>"|safe %}
Please try to submit your payment again. If this problem persists, contact {{ start_link }}
{{ payment_support_email }}{{ end_link }}.
{% endblocktrans %}
{% endwith %}</p>
</div>
</div>
<div class="container content-wrapper receipt-cancel-error">
<h1>{% trans "Checkout Error" %}</h1>
<p>{% blocktrans %} An error has occurred with your payment. <b>You have not been charged.</b>
{% endblocktrans %}</p>
<p>{% with "<a class='nav-link' href='mailto:"|add:payment_support_email|add:"'>"|safe as start_link %}
{% blocktrans with end_link="</a>"|safe %}
Please try to submit your payment again. If this problem persists, contact {{ start_link }}
{{ payment_support_email }}{{ end_link }}.
{% endblocktrans %}
{% endwith %}</p>
</div>
{% endblock %}
{% endblock content %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment