Merge pull request #6647 from edx/renzo/split-payment-verification-acceptance-tests
Bok Choy tests for the split payment and verification flow
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import unittest
|
||||
import decimal
|
||||
import ddt
|
||||
from mock import patch
|
||||
from django.conf import settings
|
||||
from django.test.utils import override_settings
|
||||
from django.core.urlresolvers import reverse
|
||||
@@ -9,10 +10,12 @@ from xmodule.modulestore.tests.django_utils import (
|
||||
ModuleStoreTestCase, mixed_store_config
|
||||
)
|
||||
|
||||
from util.testing import UrlResetMixin
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from course_modes.tests.factories import CourseModeFactory
|
||||
from student.tests.factories import CourseEnrollmentFactory, UserFactory
|
||||
from student.models import CourseEnrollment
|
||||
from course_modes.models import CourseMode, Mode
|
||||
|
||||
|
||||
# Since we don't need any XML course fixtures, use a modulestore configuration
|
||||
@@ -23,10 +26,10 @@ MODULESTORE_CONFIG = mixed_store_config(settings.COMMON_TEST_DATA_ROOT, {}, incl
|
||||
@ddt.ddt
|
||||
@override_settings(MODULESTORE=MODULESTORE_CONFIG)
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
class CourseModeViewTest(ModuleStoreTestCase):
|
||||
|
||||
class CourseModeViewTest(UrlResetMixin, ModuleStoreTestCase):
|
||||
@patch.dict(settings.FEATURES, {'MODE_CREATION_FOR_TESTING': True})
|
||||
def setUp(self):
|
||||
super(CourseModeViewTest, self).setUp()
|
||||
super(CourseModeViewTest, self).setUp('course_modes.urls')
|
||||
self.course = CourseFactory.create()
|
||||
self.user = UserFactory.create(username="Bob", email="bob@example.com", password="edx")
|
||||
self.client.login(username=self.user.username, password="edx")
|
||||
@@ -235,3 +238,65 @@ class CourseModeViewTest(ModuleStoreTestCase):
|
||||
response = self.client.post(choose_track_url, self.POST_PARAMS_FOR_COURSE_MODE['unsupported'])
|
||||
|
||||
self.assertEqual(400, response.status_code)
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_default_mode_creation(self):
|
||||
# Hit the mode creation endpoint with no querystring params, to create an honor mode
|
||||
url = reverse('create_mode', args=[unicode(self.course.id)])
|
||||
response = self.client.get(url)
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
expected_mode = [Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None)]
|
||||
course_mode = CourseMode.modes_for_course(self.course.id)
|
||||
|
||||
self.assertEquals(course_mode, expected_mode)
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
@ddt.data(
|
||||
(u'verified', u'Verified Certificate', 10, '10,20,30', 'usd'),
|
||||
(u'professional', u'Professional Education', 100, '100,200', 'usd'),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_verified_mode_creation(self, mode_slug, mode_display_name, min_price, suggested_prices, currency):
|
||||
parameters = {}
|
||||
parameters['mode_slug'] = mode_slug
|
||||
parameters['mode_display_name'] = mode_display_name
|
||||
parameters['min_price'] = min_price
|
||||
parameters['suggested_prices'] = suggested_prices
|
||||
parameters['currency'] = currency
|
||||
|
||||
url = reverse('create_mode', args=[unicode(self.course.id)])
|
||||
response = self.client.get(url, parameters)
|
||||
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
expected_mode = [Mode(mode_slug, mode_display_name, min_price, suggested_prices, currency, None, None)]
|
||||
course_mode = CourseMode.modes_for_course(self.course.id)
|
||||
|
||||
self.assertEquals(course_mode, expected_mode)
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_multiple_mode_creation(self):
|
||||
# Create an honor mode
|
||||
base_url = reverse('create_mode', args=[unicode(self.course.id)])
|
||||
self.client.get(base_url)
|
||||
|
||||
# Excluding the currency parameter implicitly tests the mode creation endpoint's ability to
|
||||
# use default values when parameters are partially missing.
|
||||
parameters = {}
|
||||
parameters['mode_slug'] = u'verified'
|
||||
parameters['mode_display_name'] = u'Verified Certificate'
|
||||
parameters['min_price'] = 10
|
||||
parameters['suggested_prices'] = '10,20'
|
||||
|
||||
# Create a verified mode
|
||||
url = reverse('create_mode', args=[unicode(self.course.id)])
|
||||
response = self.client.get(url, parameters)
|
||||
|
||||
honor_mode = Mode(u'honor', u'Honor Code Certificate', 0, '', 'usd', None, None)
|
||||
verified_mode = Mode(u'verified', u'Verified Certificate', 10, '10,20', 'usd', None, None)
|
||||
expected_modes = [honor_mode, verified_mode]
|
||||
course_modes = CourseMode.modes_for_course(self.course.id)
|
||||
|
||||
self.assertEquals(course_modes, expected_modes)
|
||||
|
||||
@@ -8,5 +8,11 @@ from course_modes import views
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
# pylint seems to dislike as_view() calls because it's a `classonlymethod` instead of `classmethod`, so we disable the warning
|
||||
url(r'^choose/{}/$'.format(settings.COURSE_ID_PATTERN), views.ChooseModeView.as_view(), name="course_modes_choose"), # pylint: disable=no-value-for-parameter
|
||||
url(r'^choose/{}/$'.format(settings.COURSE_ID_PATTERN), views.ChooseModeView.as_view(), name='course_modes_choose'), # pylint: disable=no-value-for-parameter
|
||||
)
|
||||
|
||||
# Enable verified mode creation
|
||||
if settings.FEATURES.get('MODE_CREATION_FOR_TESTING'):
|
||||
urlpatterns += (
|
||||
url(r'^create_mode/{}/$'.format(settings.COURSE_ID_PATTERN), 'course_modes.views.create_mode', name='create_mode'),
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ Views for the course_mode module
|
||||
import decimal
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponseBadRequest
|
||||
from django.http import HttpResponse, HttpResponseBadRequest
|
||||
from django.shortcuts import redirect
|
||||
from django.views.generic.base import View
|
||||
from django.utils.translation import ugettext as _
|
||||
@@ -226,3 +226,48 @@ class ChooseModeView(View):
|
||||
return 'honor'
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def create_mode(request, course_id):
|
||||
"""Add a mode to the course corresponding to the given course ID.
|
||||
|
||||
Only available when settings.FEATURES['MODE_CREATION_FOR_TESTING'] is True.
|
||||
|
||||
Attempts to use the following querystring parameters from the request:
|
||||
`mode_slug` (str): The mode to add, either 'honor', 'verified', or 'professional'
|
||||
`mode_display_name` (str): Describes the new course mode
|
||||
`min_price` (int): The minimum price a user must pay to enroll in the new course mode
|
||||
`suggested_prices` (str): Comma-separated prices to suggest to the user.
|
||||
`currency` (str): The currency in which to list prices.
|
||||
|
||||
By default, this endpoint will create an 'honor' mode for the given course with display name
|
||||
'Honor Code', a minimum price of 0, no suggested prices, and using USD as the currency.
|
||||
|
||||
Args:
|
||||
request (`Request`): The Django Request object.
|
||||
course_id (unicode): The slash-separated course key.
|
||||
|
||||
Returns:
|
||||
Response
|
||||
"""
|
||||
PARAMETERS = {
|
||||
'mode_slug': u'honor',
|
||||
'mode_display_name': u'Honor Code Certificate',
|
||||
'min_price': 0,
|
||||
'suggested_prices': u'',
|
||||
'currency': u'usd',
|
||||
}
|
||||
|
||||
# Try pulling querystring parameters out of the request
|
||||
for parameter, default in PARAMETERS.iteritems():
|
||||
PARAMETERS[parameter] = request.GET.get(parameter, default)
|
||||
|
||||
# Attempt to create the new mode for the given course
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
CourseMode.objects.get_or_create(course_id=course_key, **PARAMETERS)
|
||||
|
||||
# Return a success message and a 200 response
|
||||
return HttpResponse("Mode '{mode_slug}' created for course with ID '{course_id}'.".format(
|
||||
mode_slug=PARAMETERS['mode_slug'],
|
||||
course_id=course_id
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user