diff --git a/common/djangoapps/enrollment/management/commands/enroll_user_in_course.py b/common/djangoapps/enrollment/management/commands/enroll_user_in_course.py index 3f393c71c0..95ab5e18f0 100644 --- a/common/djangoapps/enrollment/management/commands/enroll_user_in_course.py +++ b/common/djangoapps/enrollment/management/commands/enroll_user_in_course.py @@ -1,6 +1,7 @@ """ Management command for enrolling a user into a course via the enrollment api """ +from __future__ import absolute_import from django.contrib.auth.models import User from django.core.management.base import BaseCommand from enrollment.data import CourseEnrollmentExistsError diff --git a/common/djangoapps/enrollment/management/tests/test_enroll_user_in_course.py b/common/djangoapps/enrollment/management/tests/test_enroll_user_in_course.py index 9f36019666..d643f9b5a1 100644 --- a/common/djangoapps/enrollment/management/tests/test_enroll_user_in_course.py +++ b/common/djangoapps/enrollment/management/tests/test_enroll_user_in_course.py @@ -1,5 +1,6 @@ """ Test the change_enrollment command line script.""" +from __future__ import absolute_import import ddt import unittest from uuid import uuid4 @@ -13,6 +14,8 @@ from student.tests.factories import UserFactory from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory +import six +from six.moves import range @ddt.ddt @@ -29,7 +32,7 @@ class EnrollManagementCommandTest(SharedModuleStoreTestCase): def setUp(self): super(EnrollManagementCommandTest, self).setUp() - self.course_id = unicode(self.course.id) + self.course_id = six.text_type(self.course.id) self.username = 'ralph' + uuid4().hex self.user_email = self.username + '@example.com' diff --git a/common/djangoapps/enrollment/tests/fake_data_api.py b/common/djangoapps/enrollment/tests/fake_data_api.py index 88edc70e5d..9d466c8f9e 100644 --- a/common/djangoapps/enrollment/tests/fake_data_api.py +++ b/common/djangoapps/enrollment/tests/fake_data_api.py @@ -1,6 +1,8 @@ """ A Fake Data API for testing purposes. """ +from __future__ import absolute_import + import copy import datetime diff --git a/common/djangoapps/enrollment/tests/test_api.py b/common/djangoapps/enrollment/tests/test_api.py index 80da9023ef..8b937452a5 100644 --- a/common/djangoapps/enrollment/tests/test_api.py +++ b/common/djangoapps/enrollment/tests/test_api.py @@ -1,6 +1,8 @@ """ Tests for student enrollment. """ +from __future__ import absolute_import + import unittest import ddt diff --git a/common/djangoapps/enrollment/tests/test_data.py b/common/djangoapps/enrollment/tests/test_data.py index 475070f57a..7d3e82e036 100644 --- a/common/djangoapps/enrollment/tests/test_data.py +++ b/common/djangoapps/enrollment/tests/test_data.py @@ -2,14 +2,18 @@ Test the Data Aggregation Layer for Course Enrollments. """ +from __future__ import absolute_import + import datetime import unittest import ddt import pytest +import six from django.conf import settings from mock import patch from pytz import UTC +from six.moves import range from course_modes.models import CourseMode from course_modes.tests.factories import CourseModeFactory @@ -23,7 +27,7 @@ from enrollment.errors import ( from enrollment.serializers import CourseEnrollmentSerializer from openedx.core.lib.exceptions import CourseNotFoundError from student.models import AlreadyEnrolledError, CourseEnrollment, CourseFullError, EnrollmentClosedError -from student.tests.factories import UserFactory, CourseAccessRoleFactory +from student.tests.factories import CourseAccessRoleFactory, UserFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory @@ -62,7 +66,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): self._create_course_modes(course_modes) enrollment = data.create_course_enrollment( self.user.username, - unicode(self.course.id), + six.text_type(self.course.id), enrollment_mode, True ) @@ -83,7 +87,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): enrollment = data.update_course_enrollment( self.user.username, - unicode(self.course.id), + six.text_type(self.course.id), is_active=False ) @@ -102,7 +106,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): ) def test_get_course_info(self, course_modes): self._create_course_modes(course_modes, course=self.course) - result_course = data.get_course_enrollment_info(unicode(self.course.id)) + result_course = data.get_course_enrollment_info(six.text_type(self.course.id)) result_slugs = [mode['slug'] for mode in result_course['course_modes']] for course_mode in course_modes: self.assertIn(course_mode, result_slugs) @@ -127,7 +131,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): # Create the original enrollment. created_enrollments.append(data.create_course_enrollment( self.user.username, - unicode(course.id), + six.text_type(course.id), 'honor', True )) @@ -165,7 +169,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): # Create the original enrollment. created_enrollments.append(data.create_course_enrollment( self.user.username, - unicode(course.id), + six.text_type(course.id), 'honor', True )) @@ -173,7 +177,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): # deactivate one enrollment data.update_course_enrollment( self.user.username, - unicode(created_courses[0].id), + six.text_type(created_courses[0].id), 'honor', False ) @@ -201,18 +205,18 @@ class EnrollmentDataTest(ModuleStoreTestCase): self._create_course_modes(course_modes) # Try to get an enrollment before it exists. - result = data.get_course_enrollment(self.user.username, unicode(self.course.id)) + result = data.get_course_enrollment(self.user.username, six.text_type(self.course.id)) self.assertIsNone(result) # Create the original enrollment. enrollment = data.create_course_enrollment( self.user.username, - unicode(self.course.id), + six.text_type(self.course.id), enrollment_mode, True ) # Get the enrollment and compare it to the original. - result = data.get_course_enrollment(self.user.username, unicode(self.course.id)) + result = data.get_course_enrollment(self.user.username, six.text_type(self.course.id)) self.assertEqual(self.user.username, result['user']) self.assertEqual(enrollment, result) @@ -236,7 +240,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): # Create 10 test users to enroll in the course users = [] - for i in xrange(10): + for i in range(10): users.append(UserFactory.create( username=self.USERNAME + str(i), email=self.EMAIL + str(i), @@ -248,7 +252,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): for user in users: created_enrollments.append(data.create_course_enrollment( user.username, - unicode(self.course.id), + six.text_type(self.course.id), enrollment_mode, True )) @@ -275,7 +279,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): def test_add_or_update_enrollment_attr(self, course_modes, enrollment_mode): # Create the course modes (if any) required for this test case self._create_course_modes(course_modes) - data.create_course_enrollment(self.user.username, unicode(self.course.id), enrollment_mode, True) + data.create_course_enrollment(self.user.username, six.text_type(self.course.id), enrollment_mode, True) enrollment_attributes = [ { "namespace": "credit", @@ -284,8 +288,8 @@ class EnrollmentDataTest(ModuleStoreTestCase): } ] - data.add_or_update_enrollment_attr(self.user.username, unicode(self.course.id), enrollment_attributes) - enrollment_attr = data.get_enrollment_attributes(self.user.username, unicode(self.course.id)) + data.add_or_update_enrollment_attr(self.user.username, six.text_type(self.course.id), enrollment_attributes) + enrollment_attr = data.get_enrollment_attributes(self.user.username, six.text_type(self.course.id)) self.assertEqual(enrollment_attr[0], enrollment_attributes[0]) enrollment_attributes = [ @@ -296,8 +300,8 @@ class EnrollmentDataTest(ModuleStoreTestCase): } ] - data.add_or_update_enrollment_attr(self.user.username, unicode(self.course.id), enrollment_attributes) - enrollment_attr = data.get_enrollment_attributes(self.user.username, unicode(self.course.id)) + data.add_or_update_enrollment_attr(self.user.username, six.text_type(self.course.id), enrollment_attributes) + enrollment_attr = data.get_enrollment_attributes(self.user.username, six.text_type(self.course.id)) self.assertEqual(enrollment_attr[0], enrollment_attributes[0]) def test_non_existent_course(self): @@ -316,7 +320,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): def test_enrollment_for_non_existent_user(self): with pytest.raises(UserNotFoundError): - data.create_course_enrollment("some_fake_user", unicode(self.course.id), 'honor', True) + data.create_course_enrollment("some_fake_user", six.text_type(self.course.id), 'honor', True) def test_enrollment_for_non_existent_course(self): with pytest.raises(CourseNotFoundError): @@ -326,23 +330,23 @@ class EnrollmentDataTest(ModuleStoreTestCase): def test_enrollment_for_closed_course(self, mock_enroll): mock_enroll.side_effect = EnrollmentClosedError("Bad things happened") with pytest.raises(CourseEnrollmentClosedError): - data.create_course_enrollment(self.user.username, unicode(self.course.id), 'honor', True) + data.create_course_enrollment(self.user.username, six.text_type(self.course.id), 'honor', True) @patch.object(CourseEnrollment, "enroll") def test_enrollment_for_full_course(self, mock_enroll): mock_enroll.side_effect = CourseFullError("Bad things happened") with pytest.raises(CourseEnrollmentFullError): - data.create_course_enrollment(self.user.username, unicode(self.course.id), 'honor', True) + data.create_course_enrollment(self.user.username, six.text_type(self.course.id), 'honor', True) @patch.object(CourseEnrollment, "enroll") def test_enrollment_for_enrolled_course(self, mock_enroll): mock_enroll.side_effect = AlreadyEnrolledError("Bad things happened") with pytest.raises(CourseEnrollmentExistsError): - data.create_course_enrollment(self.user.username, unicode(self.course.id), 'honor', True) + data.create_course_enrollment(self.user.username, six.text_type(self.course.id), 'honor', True) def test_update_for_non_existent_user(self): with pytest.raises(UserNotFoundError): - data.update_course_enrollment("some_fake_user", unicode(self.course.id), is_active=False) + data.update_course_enrollment("some_fake_user", six.text_type(self.course.id), is_active=False) def test_update_for_non_existent_course(self): enrollment = data.update_course_enrollment(self.user.username, "some/fake/course", is_active=False) @@ -371,7 +375,7 @@ class EnrollmentDataTest(ModuleStoreTestCase): def assert_enrollment_modes(self, expected_modes, include_expired): """Get enrollment data and assert response with expected modes.""" - result_course = data.get_course_enrollment_info(unicode(self.course.id), include_expired=include_expired) + result_course = data.get_course_enrollment_info(six.text_type(self.course.id), include_expired=include_expired) result_slugs = [mode['slug'] for mode in result_course['course_modes']] for course_mode in expected_modes: self.assertIn(course_mode, result_slugs) diff --git a/common/djangoapps/enrollment/tests/test_views.py b/common/djangoapps/enrollment/tests/test_views.py index 034b7bda3b..45d13e3a32 100644 --- a/common/djangoapps/enrollment/tests/test_views.py +++ b/common/djangoapps/enrollment/tests/test_views.py @@ -1,6 +1,8 @@ """ Tests for user enrollment. """ +from __future__ import absolute_import + import datetime import itertools import json @@ -9,19 +11,20 @@ import unittest import ddt import httpretty import pytz +import six from django.conf import settings from django.core.cache import cache from django.core.exceptions import ImproperlyConfigured from django.core.handlers.wsgi import WSGIRequest -from django.urls import reverse from django.test import Client from django.test.utils import override_settings +from django.urls import reverse from freezegun import freeze_time from mock import patch from rest_framework import status from rest_framework.test import APITestCase -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase -from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls_range +from six import text_type +from six.moves import range from course_modes.models import CourseMode from course_modes.tests.factories import CourseModeFactory @@ -33,20 +36,17 @@ from openedx.core.djangoapps.course_groups import cohorts from openedx.core.djangoapps.embargo.models import Country, CountryAccessRule, RestrictedCourse from openedx.core.djangoapps.embargo.test_utils import restrict_course from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user -from openedx.core.djangoapps.user_api.models import ( - RetirementState, - UserRetirementStatus, - UserOrgTag -) +from openedx.core.djangoapps.user_api.models import RetirementState, UserOrgTag, UserRetirementStatus from openedx.core.lib.django_test_client_utils import get_absolute_url from openedx.features.enterprise_support.tests import FAKE_ENTERPRISE_CUSTOMER from openedx.features.enterprise_support.tests.mixins.enterprise import EnterpriseServiceMockMixin from student.models import CourseEnrollment from student.roles import CourseStaffRole -from student.tests.factories import AdminFactory, UserFactory, SuperuserFactory +from student.tests.factories import AdminFactory, SuperuserFactory, UserFactory from util.models import RateLimitConfiguration from util.testing import UrlResetMixin -from six import text_type +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls_range class EnrollmentTestMixin(object): @@ -75,7 +75,7 @@ class EnrollmentTestMixin(object): Returns Response """ - course_id = course_id or unicode(self.course.id) + course_id = course_id or six.text_type(self.course.id) username = username or self.user.username data = { @@ -237,11 +237,11 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente # Create an enrollment self.assert_enrollment_status() resp = self.client.get( - reverse('courseenrollment', kwargs={'username': self.user.username, "course_id": unicode(self.course.id)}) + reverse('courseenrollment', kwargs={'username': self.user.username, "course_id": six.text_type(self.course.id)}) ) self.assertEqual(resp.status_code, status.HTTP_200_OK) data = json.loads(resp.content) - self.assertEqual(unicode(self.course.id), data['course_details']['course_id']) + self.assertEqual(six.text_type(self.course.id), data['course_details']['course_id']) self.assertEqual(self.course.display_name_with_default, data['course_details']['course_name']) self.assertEqual(CourseMode.DEFAULT_MODE_SLUG, data['mode']) self.assertTrue(data['is_active']) @@ -285,7 +285,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente # While the enrollment wrong is invalid, the response content should have # all the valid enrollment modes. data = json.loads(resp.content) - self.assertEqual(unicode(self.course.id), data['course_details']['course_id']) + self.assertEqual(six.text_type(self.course.id), data['course_details']['course_id']) self.assertEqual(1, len(data['course_details']['course_modes'])) self.assertEqual('professional', data['course_details']['course_modes'][0]['slug']) @@ -298,11 +298,11 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente # Create an enrollment self.assert_enrollment_status() resp = self.client.get( - reverse('courseenrollment', kwargs={"course_id": unicode(self.course.id)}) + reverse('courseenrollment', kwargs={"course_id": six.text_type(self.course.id)}) ) self.assertEqual(resp.status_code, status.HTTP_200_OK) data = json.loads(resp.content) - self.assertEqual(unicode(self.course.id), data['course_details']['course_id']) + self.assertEqual(six.text_type(self.course.id), data['course_details']['course_id']) self.assertEqual(CourseMode.DEFAULT_MODE_SLUG, data['mode']) self.assertTrue(data['is_active']) @@ -361,7 +361,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente data = json.loads(response.content) self.assertItemsEqual( [(datum['course_details']['course_id'], datum['course_details']['course_name']) for datum in data], - [(unicode(course.id), course.display_name_with_default) for course in courses] + [(six.text_type(course.id), course.display_name_with_default) for course in courses] ) def test_enrollment_list_permissions(self): @@ -373,12 +373,12 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente other_course = CourseFactory.create(emit_signals=True) for course in self.course, other_course: CourseModeFactory.create( - course_id=unicode(course.id), + course_id=six.text_type(course.id), mode_slug=CourseMode.DEFAULT_MODE_SLUG, mode_display_name=CourseMode.DEFAULT_MODE_SLUG, ) self.assert_enrollment_status( - course_id=unicode(course.id), + course_id=six.text_type(course.id), max_mongo_calls=0, ) # Verify the user himself can see both of his enrollments. @@ -411,7 +411,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente mode_display_name=CourseMode.HONOR, ) url = reverse('courseenrollment', - kwargs={'username': self.other_user.username, "course_id": unicode(self.course.id)}) + kwargs={'username': self.other_user.username, "course_id": six.text_type(self.course.id)}) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) @@ -436,12 +436,12 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente bulk_sku="BULK123" ) resp = self.client.get( - reverse('courseenrollmentdetails', kwargs={"course_id": unicode(self.course.id)}) + reverse('courseenrollmentdetails', kwargs={"course_id": six.text_type(self.course.id)}) ) self.assertEqual(resp.status_code, status.HTTP_200_OK) data = json.loads(resp.content) - self.assertEqual(unicode(self.course.id), data['course_id']) + self.assertEqual(six.text_type(self.course.id), data['course_id']) self.assertEqual(self.course.display_name_with_default, data['course_name']) mode = data['course_modes'][0] self.assertEqual(mode['slug'], CourseMode.HONOR) @@ -456,12 +456,12 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente mode_display_name=CourseMode.CREDIT_MODE, ) resp = self.client.get( - reverse('courseenrollmentdetails', kwargs={"course_id": unicode(self.course.id)}) + reverse('courseenrollmentdetails', kwargs={"course_id": six.text_type(self.course.id)}) ) self.assertEqual(resp.status_code, status.HTTP_200_OK) data = json.loads(resp.content) - self.assertEqual(unicode(self.course.id), data['course_id']) + self.assertEqual(six.text_type(self.course.id), data['course_id']) mode = data['course_modes'][0] self.assertEqual(mode['slug'], CourseMode.CREDIT_MODE) self.assertEqual(mode['name'], CourseMode.CREDIT_MODE) @@ -482,10 +482,10 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente # miss; the modulestore is queried and course metadata is cached. __ = CourseOverview.get_from_id(course.id) - self.assert_enrollment_status(course_id=unicode(course.id)) + self.assert_enrollment_status(course_id=six.text_type(course.id)) # Check course details - url = reverse('courseenrollmentdetails', kwargs={"course_id": unicode(course.id)}) + url = reverse('courseenrollmentdetails', kwargs={"course_id": six.text_type(course.id)}) resp = self.client.get(url) self.assertEqual(resp.status_code, status.HTTP_200_OK) @@ -494,7 +494,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente self.assertEqual(data['course_end'], expected_end) # Check enrollment course details - url = reverse('courseenrollment', kwargs={"course_id": unicode(course.id)}) + url = reverse('courseenrollment', kwargs={"course_id": six.text_type(course.id)}) resp = self.client.get(url) self.assertEqual(resp.status_code, status.HTTP_200_OK) @@ -528,7 +528,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente def test_get_enrollment_internal_error(self, mock_get_enrollment): mock_get_enrollment.side_effect = CourseEnrollmentError("Something bad happened.") resp = self.client.get( - reverse('courseenrollment', kwargs={'username': self.user.username, "course_id": unicode(self.course.id)}) + reverse('courseenrollment', kwargs={'username': self.user.username, "course_id": six.text_type(self.course.id)}) ) self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST) @@ -561,7 +561,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente mode_display_name=CourseMode.DEFAULT_MODE_SLUG, ) - for attempt in xrange(self.rate_limit + 2): + for attempt in range(self.rate_limit + 2): expected_status = status.HTTP_429_TOO_MANY_REQUESTS if attempt >= self.rate_limit else status.HTTP_200_OK self.assert_enrollment_status(expected_status=expected_status) @@ -636,7 +636,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente # Passes the include_expired parameter to the API call v_response = self.client.get( - reverse('courseenrollmentdetails', kwargs={"course_id": unicode(self.course.id)}), {'include_expired': True} + reverse('courseenrollmentdetails', kwargs={"course_id": six.text_type(self.course.id)}), {'include_expired': True} ) v_data = json.loads(v_response.content) @@ -644,7 +644,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente self.assertEqual(len(v_data['course_modes']), 2) # Omits the include_expired parameter from the API call - h_response = self.client.get(reverse('courseenrollmentdetails', kwargs={"course_id": unicode(self.course.id)})) + h_response = self.client.get(reverse('courseenrollmentdetails', kwargs={"course_id": six.text_type(self.course.id)})) h_data = json.loads(h_response.content) # Ensure that only one course mode is returned and that it is honor @@ -993,7 +993,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente ) consent_kwargs = { 'username': self.user.username, - 'course_id': unicode(self.course.id), + 'course_id': six.text_type(self.course.id), 'ec_uuid': 'this-is-a-real-uuid' } mock_enterprise_customer_from_api.return_value = FAKE_ENTERPRISE_CUSTOMER @@ -1109,7 +1109,7 @@ class EnrollmentEmbargoTest(EnrollmentTestMixin, UrlResetMixin, ModuleStoreTestC def _generate_data(self): return json.dumps({ 'course_details': { - 'course_id': unicode(self.course.id) + 'course_id': six.text_type(self.course.id) }, 'user': self.user.username }) @@ -1249,7 +1249,7 @@ class EnrollmentCrossDomainTest(ModuleStoreTestCase): def _get_csrf_cookie(self): """Retrieve the cross-domain CSRF cookie. """ url = reverse('courseenrollment', kwargs={ - 'course_id': unicode(self.course.id) + 'course_id': six.text_type(self.course.id) }) resp = self.client.get(url, HTTP_REFERER=self.REFERER) self.assertEqual(resp.status_code, 200) @@ -1261,7 +1261,7 @@ class EnrollmentCrossDomainTest(ModuleStoreTestCase): url = reverse('courseenrollments') params = json.dumps({ 'course_details': { - 'course_id': unicode(self.course.id), + 'course_id': six.text_type(self.course.id), }, 'user': self.user.username }) @@ -1578,31 +1578,31 @@ class CourseEnrollmentsApiListTest(APITestCase, ModuleStoreTestCase): with freeze_time(self.CREATED_DATA): data.create_course_enrollment( self.student1.username, - unicode(self.course.id), + six.text_type(self.course.id), 'honor', True ) data.create_course_enrollment( self.student2.username, - unicode(self.course.id), + six.text_type(self.course.id), 'honor', True ) data.create_course_enrollment( self.student3.username, - unicode(self.course2.id), + six.text_type(self.course2.id), 'verified', True ) data.create_course_enrollment( self.student2.username, - unicode(self.course2.id), + six.text_type(self.course2.id), 'honor', True ) data.create_course_enrollment( self.staff_user.username, - unicode(self.course2.id), + six.text_type(self.course2.id), 'verified', True )