diff --git a/lms/djangoapps/commerce/signals.py b/lms/djangoapps/commerce/signals.py index a6b53adb28..2a7351ce18 100644 --- a/lms/djangoapps/commerce/signals.py +++ b/lms/djangoapps/commerce/signals.py @@ -1,7 +1,7 @@ """ Signal handling functions for use with external commerce service. """ -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals import logging @@ -11,6 +11,7 @@ from django.dispatch import receiver from openedx.core.djangoapps.commerce.utils import is_commerce_service_configured from student.signals import REFUND_ORDER + from .utils import refund_seat log = logging.getLogger(__name__) diff --git a/lms/djangoapps/commerce/views.py b/lms/djangoapps/commerce/views.py index c4be88201c..82e1bab9f8 100644 --- a/lms/djangoapps/commerce/views.py +++ b/lms/djangoapps/commerce/views.py @@ -1,4 +1,6 @@ """ Commerce views. """ +from __future__ import absolute_import + import logging from django.conf import settings diff --git a/lms/djangoapps/verify_student/tests/fake_software_secure.py b/lms/djangoapps/verify_student/tests/fake_software_secure.py index f587f0bb38..fff0bff092 100644 --- a/lms/djangoapps/verify_student/tests/fake_software_secure.py +++ b/lms/djangoapps/verify_student/tests/fake_software_secure.py @@ -2,6 +2,8 @@ Fake Software Secure page for use in acceptance tests. """ +from __future__ import absolute_import + from django.conf import settings from django.contrib.auth.decorators import login_required from django.urls import reverse diff --git a/lms/djangoapps/verify_student/tests/test_integration.py b/lms/djangoapps/verify_student/tests/test_integration.py index 6d06518734..f0ad8dafb8 100644 --- a/lms/djangoapps/verify_student/tests/test_integration.py +++ b/lms/djangoapps/verify_student/tests/test_integration.py @@ -2,6 +2,9 @@ Integration tests of the payment flow, including course mode selection. """ +from __future__ import absolute_import + +import six from django.urls import reverse from course_modes.tests.factories import CourseModeFactory @@ -36,12 +39,12 @@ class TestProfEdVerification(ModuleStoreTestCase): self.urls = { 'course_modes_choose': reverse( 'course_modes_choose', - args=[unicode(self.course_key)] + args=[six.text_type(self.course_key)] ), 'verify_student_start_flow': reverse( 'verify_student_start_flow', - args=[unicode(self.course_key)] + args=[six.text_type(self.course_key)] ) + purchase_workflow, } diff --git a/lms/djangoapps/verify_student/tests/test_ssencrypt.py b/lms/djangoapps/verify_student/tests/test_ssencrypt.py index 1aae43d822..6e39b08c12 100644 --- a/lms/djangoapps/verify_student/tests/test_ssencrypt.py +++ b/lms/djangoapps/verify_student/tests/test_ssencrypt.py @@ -2,6 +2,8 @@ Tests of the encryption and decryption utilities in the ssencrypt module. """ +from __future__ import absolute_import + import base64 from lms.djangoapps.verify_student.ssencrypt import ( diff --git a/lms/djangoapps/verify_student/tests/test_utils.py b/lms/djangoapps/verify_student/tests/test_utils.py index 6f17c1bf36..1622c45046 100644 --- a/lms/djangoapps/verify_student/tests/test_utils.py +++ b/lms/djangoapps/verify_student/tests/test_utils.py @@ -3,16 +3,19 @@ Tests for verify_student utility functions. """ +from __future__ import absolute_import + +import unittest from datetime import timedelta import ddt -import unittest -from mock import patch -from pytest import mark from django.conf import settings from django.utils import timezone -from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, SSOVerification, ManualVerification -from lms.djangoapps.verify_student.utils import verification_for_datetime, most_recent_verification +from mock import patch +from pytest import mark + +from lms.djangoapps.verify_student.models import ManualVerification, SoftwareSecurePhotoVerification, SSOVerification +from lms.djangoapps.verify_student.utils import most_recent_verification, verification_for_datetime from student.tests.factories import UserFactory FAKE_SETTINGS = { diff --git a/lms/djangoapps/verify_student/tests/test_views.py b/lms/djangoapps/verify_student/tests/test_views.py index 8e3717f7ca..2f2bb4c1f9 100644 --- a/lms/djangoapps/verify_student/tests/test_views.py +++ b/lms/djangoapps/verify_student/tests/test_views.py @@ -3,8 +3,9 @@ Tests of verify_student views. """ +from __future__ import absolute_import + import json -import urllib from datetime import timedelta from uuid import uuid4 @@ -14,18 +15,23 @@ import httpretty import mock import moto import requests +import six +import six.moves.urllib.error # pylint: disable=import-error +import six.moves.urllib.parse # pylint: disable=import-error +import six.moves.urllib.request # pylint: disable=import-error from bs4 import BeautifulSoup from django.conf import settings from django.core import mail -from django.urls import reverse from django.test import TestCase from django.test.client import Client, RequestFactory from django.test.utils import override_settings +from django.urls import reverse from django.utils.timezone import now from django.utils.translation import ugettext as _ from mock import Mock, patch from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.locator import CourseLocator +from six.moves import zip from waffle.testutils import override_switch from common.test.utils import XssTestMixin @@ -35,11 +41,7 @@ from lms.djangoapps.commerce.models import CommerceConfiguration from lms.djangoapps.commerce.tests import TEST_API_URL, TEST_PAYMENT_DATA, TEST_PUBLIC_URL_ROOT from lms.djangoapps.commerce.utils import EcommerceService from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, VerificationDeadline -from lms.djangoapps.verify_student.views import ( - PayAndVerifyView, - checkout_with_ecommerce_service, - render_to_response -) +from lms.djangoapps.verify_student.views import PayAndVerifyView, checkout_with_ecommerce_service, render_to_response from openedx.core.djangoapps.embargo.test_utils import restrict_course from openedx.core.djangoapps.theming.tests.test_util import with_comprehensive_theme from openedx.core.djangoapps.user_api.accounts.api import get_account_settings @@ -67,7 +69,7 @@ class StartView(TestCase): attempting a Photo Verification. """ def start_url(self, course_id=""): - return "/verify_student/{0}".format(urllib.quote(course_id)) + return "/verify_student/{0}".format(six.moves.urllib.parse.quote(course_id)) def test_start_new_verification(self): """ @@ -506,12 +508,12 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): response = self._get_page('verify_student_payment_confirmation', course.id) courseware_url = ( - reverse("course_root", kwargs={'course_id': unicode(course.id)}) + reverse("course_root", kwargs={'course_id': six.text_type(course.id)}) if show_courseware_url else "" ) self._assert_course_details( response, - unicode(course.id), + six.text_type(course.id), course.display_name, courseware_url ) @@ -642,7 +644,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): course = self._create_course("verified") response = self._get_page(url_name, course.id, expected_status_code=302) - original_url = reverse(url_name, kwargs={'course_id': unicode(course.id)}) + original_url = reverse(url_name, kwargs={'course_id': six.text_type(course.id)}) login_url = u"{login_url}?next={original_url}".format( login_url=reverse('signin_user'), original_url=original_url @@ -742,7 +744,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): # Expect that the expiration date is set response = self._get_page(payment_flow, course.id) data = self._get_page_data(response) - self.assertEqual(data['verification_deadline'], unicode(deadline)) + self.assertEqual(data['verification_deadline'], six.text_type(deadline)) def test_course_mode_expired(self): deadline = now() + timedelta(days=-360) @@ -810,7 +812,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): # Check that the verification deadline (rather than the upgrade deadline) is displayed if verification_deadline is not None: - self.assertEqual(data["verification_deadline"], unicode(verification_deadline)) + self.assertEqual(data["verification_deadline"], six.text_type(verification_deadline)) else: self.assertEqual(data["verification_deadline"], "") @@ -941,13 +943,13 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): """Set the contribution amount pre-filled in a session var. """ session = self.client.session session["donation_for_course"] = { - unicode(course_id): amount + six.text_type(course_id): amount } session.save() def _get_page(self, url_name, course_key, expected_status_code=200, skip_first_step=False): """Retrieve one of the verification pages. """ - url = reverse(url_name, kwargs={"course_id": unicode(course_key)}) + url = reverse(url_name, kwargs={"course_id": six.text_type(course_key)}) if skip_first_step: url += "?skip-first-step=1" @@ -978,7 +980,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): def _assert_requirements_displayed(self, response, requirements): """Check that requirements are displayed on the page. """ response_dict = self._get_page_data(response) - for req, displayed in response_dict['requirements'].iteritems(): + for req, displayed in six.iteritems(response_dict['requirements']): if req in requirements: self.assertTrue(displayed, msg=u"Expected '{req}' requirement to be displayed".format(req=req)) else: @@ -1039,17 +1041,17 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase, XssTestMixin): def _assert_redirects_to_start_flow(self, response, course_id): """Check that the page redirects to the start of the payment/verification flow. """ - url = reverse('verify_student_start_flow', kwargs={'course_id': unicode(course_id)}) + url = reverse('verify_student_start_flow', kwargs={'course_id': six.text_type(course_id)}) self.assertRedirects(response, url) def _assert_redirects_to_verify_start(self, response, course_id, status_code=302): """Check that the page redirects to the "verify later" part of the flow. """ - url = reverse('verify_student_verify_now', kwargs={'course_id': unicode(course_id)}) + url = reverse('verify_student_verify_now', kwargs={'course_id': six.text_type(course_id)}) self.assertRedirects(response, url, status_code) def _assert_redirects_to_upgrade(self, response, course_id): """Check that the page redirects to the "upgrade" part of the flow. """ - url = reverse('verify_student_upgrade_and_verify', kwargs={'course_id': unicode(course_id)}) + url = reverse('verify_student_upgrade_and_verify', kwargs={'course_id': six.text_type(course_id)}) self.assertRedirects(response, url) @ddt.data("verify_student_start_flow", "verify_student_begin_flow") @@ -1158,7 +1160,7 @@ class CheckoutTestMixin(object): def test_create_order(self, patched_create_order): # Create an order params = { - 'course_id': unicode(self.course.id), + 'course_id': six.text_type(self.course.id), 'contribution': 100, } self._assert_checked_out(params, patched_create_order, self.course.id, 'verified') @@ -1168,7 +1170,7 @@ class CheckoutTestMixin(object): course = CourseFactory.create() CourseModeFactory.create(mode_slug="professional", course_id=course.id, min_price=10, sku=self.make_sku()) # Create an order for a prof ed course - params = {'course_id': unicode(course.id)} + params = {'course_id': six.text_type(course.id)} self._assert_checked_out(params, patched_create_order, course.id, 'professional') def test_create_order_no_id_professional(self, patched_create_order): @@ -1176,7 +1178,7 @@ class CheckoutTestMixin(object): course = CourseFactory.create() CourseModeFactory.create(mode_slug="no-id-professional", course_id=course.id, min_price=10, sku=self.make_sku()) # Create an order for a prof ed course - params = {'course_id': unicode(course.id)} + params = {'course_id': six.text_type(course.id)} self._assert_checked_out(params, patched_create_order, course.id, 'no-id-professional') def test_create_order_for_multiple_paid_modes(self, patched_create_order): @@ -1185,14 +1187,14 @@ class CheckoutTestMixin(object): CourseModeFactory.create(mode_slug="no-id-professional", course_id=course.id, min_price=10, sku=self.make_sku()) CourseModeFactory.create(mode_slug="professional", course_id=course.id, min_price=10, sku=self.make_sku()) # Create an order for a prof ed course - params = {'course_id': unicode(course.id)} + params = {'course_id': six.text_type(course.id)} # TODO jsa - is this the intended behavior? self._assert_checked_out(params, patched_create_order, course.id, 'no-id-professional') def test_create_order_bad_donation_amount(self, patched_create_order): # Create an order params = { - 'course_id': unicode(self.course.id), + 'course_id': six.text_type(self.course.id), 'contribution': '99.9' } self._assert_checked_out(params, patched_create_order, None, None, expected_status_code=400) @@ -1200,7 +1202,7 @@ class CheckoutTestMixin(object): def test_create_order_good_donation_amount(self, patched_create_order): # Create an order params = { - 'course_id': unicode(self.course.id), + 'course_id': six.text_type(self.course.id), 'contribution': '100.0' } self._assert_checked_out(params, patched_create_order, self.course.id, 'verified') @@ -1213,7 +1215,7 @@ class CheckoutTestMixin(object): expected_payment_data['payment_form_data'].update({'foo': 'bar'}) patched_create_order.return_value = expected_payment_data # there is no 'processor' parameter in the post payload, so the response should only contain payment form data. - params = {'course_id': unicode(self.course.id), 'contribution': 100} + params = {'course_id': six.text_type(self.course.id), 'contribution': 100} response = self.client.post(reverse('verify_student_create_order'), params) self.assertEqual(response.status_code, 200) self.assertTrue(patched_create_order.called) @@ -1237,7 +1239,9 @@ class TestCreateOrderShoppingCart(CheckoutTestMixin, ModuleStoreTestCase): def _get_checkout_args(self, patched_create_order): """ Assuming patched_create_order was called, return a mapping containing the call arguments.""" - return dict(zip(('request', 'user', 'course_key', 'course_mode', 'amount'), patched_create_order.call_args[0])) + return dict( + list(zip(('request', 'user', 'course_key', 'course_mode', 'amount'), patched_create_order.call_args[0])) + ) @override_settings(ECOMMERCE_API_URL=TEST_API_URL) @@ -1255,7 +1259,7 @@ class TestCreateOrderEcommerceService(CheckoutTestMixin, ModuleStoreTestCase): def _get_checkout_args(self, patched_create_order): """ Assuming patched_create_order was called, return a mapping containing the call arguments.""" - return dict(zip(('user', 'course_key', 'course_mode', 'processor'), patched_create_order.call_args[0])) + return dict(list(zip(('user', 'course_key', 'course_mode', 'processor'), patched_create_order.call_args[0]))) class TestCheckoutWithEcommerceService(ModuleStoreTestCase):