Commit fe3472cb by Will Daly

Merge pull request #5013 from edx/will/ecom-113

ECOM-113: Already verified page sometimes displays the incorrect price
parents 17395248 83bfb178
import ddt
import unittest
import decimal
import ddt
from django.conf import settings
from django.test.utils import override_settings
from django.core.urlresolvers import reverse
......@@ -162,7 +163,7 @@ class CourseModeViewTest(ModuleStoreTestCase):
POST_PARAMS_FOR_COURSE_MODE = {
'audit': {'audit_mode': True},
'honor': {'honor-code': True},
'verified': {'certificate_mode': True}
'verified': {'certificate_mode': True, 'contribution': '1.23'}
}
# TODO (ECOM-16): Remove the auto-register flag once the AB-test completes
......@@ -203,3 +204,20 @@ class CourseModeViewTest(ModuleStoreTestCase):
self.fail("Must provide a valid redirect URL name")
self.assertRedirects(resp, redirect_url)
def test_remember_donation_for_course(self):
# Create the course modes
for mode in ('audit', 'honor', 'verified'):
CourseModeFactory(mode_slug=mode, course_id=self.course.id)
# Choose the mode (POST request)
choose_track_url = reverse('course_modes_choose', args=[unicode(self.course.id)])
self.client.post(choose_track_url, self.POST_PARAMS_FOR_COURSE_MODE['verified'])
# Expect that the contribution amount is stored in the user's session
self.assertIn('donation_for_course', self.client.session)
self.assertIn(unicode(self.course.id), self.client.session['donation_for_course'])
actual_amount = self.client.session['donation_for_course'][unicode(self.course.id)]
expected_amount = decimal.Decimal(self.POST_PARAMS_FOR_COURSE_MODE['verified']['contribution'])
self.assertEqual(actual_amount, expected_amount)
......@@ -16,7 +16,6 @@ from edxmako.shortcuts import render_to_response
from course_modes.models import CourseMode
from courseware.access import has_access
from student.models import CourseEnrollment
from verify_student.models import SoftwareSecurePhotoVerification
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xmodule.modulestore.django import modulestore
......@@ -92,7 +91,7 @@ class ChooseModeView(View):
)
donation_for_course = request.session.get("donation_for_course", {})
chosen_price = donation_for_course.get(course_key, None)
chosen_price = donation_for_course.get(unicode(course_key), None)
course = modulestore().get_course(course_key)
context = {
......@@ -164,7 +163,7 @@ class ChooseModeView(View):
return self.get(request, course_id, error=error_msg)
donation_for_course = request.session.get("donation_for_course", {})
donation_for_course[course_key] = amount_value
donation_for_course[unicode(course_key)] = amount_value
request.session["donation_for_course"] = donation_for_course
return redirect(
......
......@@ -13,6 +13,7 @@ verify_student/start?course_id=MITx/6.002x/2013_Spring # create
import json
import mock
import urllib
import decimal
from mock import patch, Mock
import pytz
from datetime import timedelta, datetime
......@@ -98,6 +99,21 @@ class TestVerifyView(ModuleStoreTestCase):
response = self.client.get(url, {'upgrade': "True"})
self.assertIn("You are upgrading your registration for", response.content)
def test_show_selected_contribution_amount(self):
# Set the donation amount in the client's session
session = self.client.session
session['donation_for_course'] = {
unicode(self.course_key): decimal.Decimal('1.23')
}
session.save()
# Retrieve the page
url = reverse('verify_student_verify', kwargs={"course_id": unicode(self.course_key)})
response = self.client.get(url)
# Expect that the user's contribution amount is shown on the page
self.assertContains(response, '1.23')
@override_settings(MODULESTORE=MODULESTORE_CONFIG)
class TestVerifiedView(ModuleStoreTestCase):
......@@ -126,6 +142,25 @@ class TestVerifiedView(ModuleStoreTestCase):
# Location should contains dashboard.
self.assertIn('dashboard', response._headers.get('location')[1])
def test_show_selected_contribution_amount(self):
# Configure the course to have a verified mode
for mode in ('audit', 'honor', 'verified'):
CourseModeFactory(mode_slug=mode, course_id=self.course.id)
# Set the donation amount in the client's session
session = self.client.session
session['donation_for_course'] = {
unicode(self.course_id): decimal.Decimal('1.23')
}
session.save()
# Retrieve the page
url = reverse('verify_student_verified', kwargs={"course_id": unicode(self.course_id)})
response = self.client.get(url)
# Expect that the user's contribution amount is shown on the page
self.assertContains(response, '1.23')
@override_settings(MODULESTORE=MODULESTORE_CONFIG)
class TestReverifyView(ModuleStoreTestCase):
......@@ -548,6 +583,26 @@ class TestCreateOrder(ModuleStoreTestCase):
data = json.loads(response.content)
self.assertEqual(data['override_custom_receipt_page'], "http://testserver/shoppingcart/postpay_callback/")
def test_create_order_set_donation_amount(self):
# Verify the student so we don't need to submit photos
self._verify_student()
# Create an order
url = reverse('verify_student_create_order')
params = {
'course_id': unicode(self.course.id),
'contribution': '1.23'
}
self.client.post(url, params)
# Verify that the client's session contains the new donation amount
self.assertIn('donation_for_course', self.client.session)
self.assertIn(unicode(self.course.id), self.client.session['donation_for_course'])
actual_amount = self.client.session['donation_for_course'][unicode(self.course.id)]
expected_amount = decimal.Decimal('1.23')
self.assertEqual(actual_amount, expected_amount)
def _verify_student(self):
""" Simulate that the student's identity has already been verified. """
attempt = SoftwareSecurePhotoVerification.objects.create(user=self.user)
......
......@@ -82,7 +82,7 @@ class VerifyView(View):
if not current_mode:
return redirect(reverse('dashboard'))
if course_id.to_deprecated_string() in request.session.get("donation_for_course", {}):
chosen_price = request.session["donation_for_course"][course_id.to_deprecated_string()]
chosen_price = request.session["donation_for_course"][unicode(course_id)]
else:
chosen_price = current_mode.min_price
......@@ -145,7 +145,7 @@ class VerifiedView(View):
if not current_mode:
return redirect(reverse('dashboard'))
if course_id.to_deprecated_string() in request.session.get("donation_for_course", {}):
chosen_price = request.session["donation_for_course"][course_id.to_deprecated_string()]
chosen_price = request.session["donation_for_course"][unicode(course_id)]
else:
chosen_price = current_mode.min_price
......@@ -189,15 +189,15 @@ def create_order(request):
course_id = request.POST['course_id']
course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
donation_for_course = request.session.get('donation_for_course', {})
current_donation = donation_for_course.get(course_id, decimal.Decimal(0))
contribution = request.POST.get("contribution", donation_for_course.get(course_id, 0))
current_donation = donation_for_course.get(unicode(course_id), decimal.Decimal(0))
contribution = request.POST.get("contribution", donation_for_course.get(unicode(course_id), 0))
try:
amount = decimal.Decimal(contribution).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_DOWN)
except decimal.InvalidOperation:
return HttpResponseBadRequest(_("Selected price is not valid number."))
if amount != current_donation:
donation_for_course[course_id] = amount
donation_for_course[unicode(course_id)] = amount
request.session['donation_for_course'] = donation_for_course
# prefer professional mode over verified_mode
......
......@@ -84,8 +84,15 @@ PIPELINE_SASS_ARGUMENTS = '--debug-info --require {proj_dir}/static/sass/bourbon
FEATURES['AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING'] = True
FEATURES['ENABLE_PAYMENT_FAKE'] = True
for processor in CC_PROCESSOR.values():
processor['PURCHASE_ENDPOINT'] = '/shoppingcart/payment_fake/'
CC_PROCESSOR_NAME = 'CyberSource2'
CC_PROCESSOR = {
'CyberSource2': {
"PURCHASE_ENDPOINT": '/shoppingcart/payment_fake/',
"SECRET_KEY": 'abcd123',
"ACCESS_KEY": 'abcd123',
"PROFILE_ID": 'edx',
}
}
#####################################################################
# See if the developer has any local overrides.
......
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