This functionality is activated by adding a SKU to a non-honor course mode. When the feature is activated, verified orders will be created by the E-Commerce Service instead of LMS. After payment, the E-Commerce Service will also create the enrollment.
89 lines
3.5 KiB
Python
89 lines
3.5 KiB
Python
""" Tests the E-Commerce API module. """
|
|
|
|
import json
|
|
|
|
from ddt import ddt, data
|
|
from django.core.urlresolvers import reverse
|
|
from django.test.testcases import TestCase
|
|
from django.test.utils import override_settings
|
|
import httpretty
|
|
from requests import Timeout
|
|
|
|
from commerce.api import EcommerceAPI
|
|
from commerce.constants import OrderStatus
|
|
from commerce.exceptions import InvalidResponseError, TimeoutError, InvalidConfigurationError
|
|
from commerce.tests import EcommerceApiTestMixin
|
|
from student.tests.factories import UserFactory
|
|
|
|
|
|
@ddt
|
|
@override_settings(ECOMMERCE_API_URL=EcommerceApiTestMixin.ECOMMERCE_API_URL,
|
|
ECOMMERCE_API_SIGNING_KEY=EcommerceApiTestMixin.ECOMMERCE_API_SIGNING_KEY)
|
|
class EcommerceAPITests(EcommerceApiTestMixin, TestCase):
|
|
""" Tests for the E-Commerce API client. """
|
|
|
|
SKU = '1234'
|
|
|
|
def setUp(self):
|
|
super(EcommerceAPITests, self).setUp()
|
|
self.url = reverse('commerce:orders')
|
|
self.user = UserFactory()
|
|
self.api = EcommerceAPI()
|
|
|
|
def test_constructor_url_strip(self):
|
|
""" Verifies that the URL is stored with trailing slashes removed. """
|
|
url = 'http://example.com'
|
|
api = EcommerceAPI(url, 'edx')
|
|
self.assertEqual(api.url, url)
|
|
|
|
api = EcommerceAPI(url + '/', 'edx')
|
|
self.assertEqual(api.url, url)
|
|
|
|
@override_settings(ECOMMERCE_API_URL=None, ECOMMERCE_API_SIGNING_KEY=None)
|
|
def test_no_settings(self):
|
|
"""
|
|
If the settings ECOMMERCE_API_URL and ECOMMERCE_API_SIGNING_KEY are invalid, the constructor should
|
|
raise a ValueError.
|
|
"""
|
|
self.assertRaises(InvalidConfigurationError, EcommerceAPI)
|
|
|
|
@httpretty.activate
|
|
def test_create_order(self):
|
|
""" Verify the method makes a call to the E-Commerce API with the correct headers and data. """
|
|
self._mock_ecommerce_api()
|
|
number, status, body = self.api.create_order(self.user, self.SKU)
|
|
|
|
# Validate the request sent to the E-Commerce API endpoint.
|
|
request = httpretty.last_request()
|
|
self.assertValidOrderRequest(request, self.user, self.ECOMMERCE_API_SIGNING_KEY, self.SKU)
|
|
|
|
# Validate the data returned by the method
|
|
self.assertEqual(number, self.ORDER_NUMBER)
|
|
self.assertEqual(status, OrderStatus.COMPLETE)
|
|
self.assertEqual(body, self.ECOMMERCE_API_SUCCESSFUL_BODY)
|
|
|
|
@httpretty.activate
|
|
@data(400, 401, 405, 406, 429, 500, 503)
|
|
def test_create_order_with_invalid_http_status(self, status):
|
|
""" If the E-Commerce API returns a non-200 status, the method should raise an InvalidResponseError. """
|
|
self._mock_ecommerce_api(status=status, body=json.dumps({'user_message': 'FAIL!'}))
|
|
self.assertRaises(InvalidResponseError, self.api.create_order, self.user, self.SKU)
|
|
|
|
@httpretty.activate
|
|
def test_create_order_with_invalid_json(self):
|
|
""" If the E-Commerce API returns un-parseable data, the method should raise an InvalidResponseError. """
|
|
self._mock_ecommerce_api(body='TOTALLY NOT JSON!')
|
|
self.assertRaises(InvalidResponseError, self.api.create_order, self.user, self.SKU)
|
|
|
|
@httpretty.activate
|
|
def test_create_order_with_timeout(self):
|
|
""" If the call to the E-Commerce API times out, the method should raise a TimeoutError. """
|
|
|
|
def request_callback(_request, _uri, _headers):
|
|
""" Simulates API timeout """
|
|
raise Timeout
|
|
|
|
self._mock_ecommerce_api(body=request_callback)
|
|
|
|
self.assertRaises(TimeoutError, self.api.create_order, self.user, self.SKU)
|