refactor: Ran pyupgrade on openedx/core/djangoapps/enrollments (#26912)

Co-authored-by: Muhammad Soban Javed <58461728+iamsobanjaved@users.noreply.github.com>

Co-authored-by: Muhammad Soban Javed <58461728+iamsobanjaved@users.noreply.github.com>
This commit is contained in:
Usama Sadiq
2021-03-18 18:38:20 +05:00
committed by GitHub
parent 918c44e499
commit afc0a6b770
14 changed files with 154 additions and 169 deletions

View File

@@ -257,7 +257,7 @@ def update_enrollment(
}
"""
log.info(u'Starting Update Enrollment process for user {user} in course {course} to mode {mode}'.format(
log.info('Starting Update Enrollment process for user {user} in course {course} to mode {mode}'.format(
user=username,
course=course_id,
mode=mode,
@@ -266,13 +266,13 @@ def update_enrollment(
validate_course_mode(course_id, mode, is_active=is_active, include_expired=include_expired)
enrollment = _data_api().update_course_enrollment(username, course_id, mode=mode, is_active=is_active)
if enrollment is None: # lint-amnesty, pylint: disable=no-else-raise
msg = u"Course Enrollment not found for user {user} in course {course}".format(user=username, course=course_id)
msg = f"Course Enrollment not found for user {username} in course {course_id}"
log.warning(msg)
raise errors.EnrollmentNotFoundError(msg)
else:
if enrollment_attributes is not None:
set_enrollment_attributes(username, course_id, enrollment_attributes)
log.info(u'Course Enrollment updated for user {user} in course {course} to mode {mode}'.format(
log.info('Course Enrollment updated for user {user} in course {course} to mode {mode}'.format(
user=username,
course=course_id,
mode=mode
@@ -320,16 +320,13 @@ def get_course_enrollment_details(course_id, include_expired=False):
}
"""
cache_key = u'enrollment.course.details.{course_id}.{include_expired}'.format(
course_id=course_id,
include_expired=include_expired
)
cache_key = f'enrollment.course.details.{course_id}.{include_expired}'
cached_enrollment_data = None
try:
cached_enrollment_data = cache.get(cache_key)
except Exception: # pylint: disable=broad-except
# The cache backend could raise an exception (for example, memcache keys that contain spaces)
log.exception(u"Error occurred while retrieving course enrollment details from the cache")
log.exception("Error occurred while retrieving course enrollment details from the cache")
if cached_enrollment_data:
return cached_enrollment_data
@@ -341,8 +338,8 @@ def get_course_enrollment_details(course_id, include_expired=False):
cache.set(cache_key, course_enrollment_details, cache_time_out)
except Exception:
# Catch any unexpected errors during caching.
log.exception(u"Error occurred while caching course enrollment details for course %s", course_id)
raise errors.CourseEnrollmentError(u"An unexpected error occurred while retrieving course enrollment details.") # lint-amnesty, pylint: disable=raise-missing-from
log.exception("Error occurred while caching course enrollment details for course %s", course_id)
raise errors.CourseEnrollmentError("An unexpected error occurred while retrieving course enrollment details.") # lint-amnesty, pylint: disable=raise-missing-from
return course_enrollment_details
@@ -449,8 +446,8 @@ def validate_course_mode(course_id, mode, is_active=None, include_expired=False)
available_modes = [m['slug'] for m in course_modes]
if mode not in available_modes:
msg = (
u"Specified course mode '{mode}' unavailable for course {course_id}. "
u"Available modes were: {available}"
"Specified course mode '{mode}' unavailable for course {course_id}. "
"Available modes were: {available}"
).format(
mode=mode,
course_id=course_id,
@@ -550,5 +547,5 @@ def _data_api():
try:
return importlib.import_module(api_path)
except (ImportError, ValueError):
log.exception(u"Could not load module at '{path}'".format(path=api_path))
log.exception(f"Could not load module at '{api_path}'")
raise errors.EnrollmentApiLoadError(api_path) # lint-amnesty, pylint: disable=raise-missing-from

View File

@@ -1,4 +1,3 @@
"""
Enrollments Application Configuration
@@ -15,7 +14,7 @@ class EnrollmentsConfig(AppConfig):
"""
Application Configuration for Enrollments.
"""
name = u'openedx.core.djangoapps.enrollments'
name = 'openedx.core.djangoapps.enrollments'
def ready(self):
"""

View File

@@ -9,7 +9,6 @@ import logging
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.db import transaction
from opaque_keys.edx.keys import CourseKey
from six import text_type
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.enrollments.errors import (
@@ -69,8 +68,8 @@ def get_course_enrollments(username, include_inactive=False):
if deleted:
log.warning(
(
u"Course enrollments for user %s reference "
u"courses that do not exist (this can occur if a course is deleted)."
"Course enrollments for user %s reference "
"courses that do not exist (this can occur if a course is deleted)."
), username,
)
@@ -142,7 +141,7 @@ def create_course_enrollment(username, course_id, mode, is_active):
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
msg = u"Not user with username '{username}' found.".format(username=username)
msg = f"Not user with username '{username}' found."
log.warning(msg)
raise UserNotFoundError(msg) # lint-amnesty, pylint: disable=raise-missing-from
@@ -150,14 +149,14 @@ def create_course_enrollment(username, course_id, mode, is_active):
enrollment = CourseEnrollment.enroll(user, course_key, check_access=True)
return _update_enrollment(enrollment, is_active=is_active, mode=mode)
except NonExistentCourseError as err:
raise CourseNotFoundError(text_type(err)) # lint-amnesty, pylint: disable=raise-missing-from
raise CourseNotFoundError(str(err)) # lint-amnesty, pylint: disable=raise-missing-from
except EnrollmentClosedError as err:
raise CourseEnrollmentClosedError(text_type(err)) # lint-amnesty, pylint: disable=raise-missing-from
raise CourseEnrollmentClosedError(str(err)) # lint-amnesty, pylint: disable=raise-missing-from
except CourseFullError as err:
raise CourseEnrollmentFullError(text_type(err)) # lint-amnesty, pylint: disable=raise-missing-from
raise CourseEnrollmentFullError(str(err)) # lint-amnesty, pylint: disable=raise-missing-from
except AlreadyEnrolledError as err:
enrollment = get_course_enrollment(username, course_id)
raise CourseEnrollmentExistsError(text_type(err), enrollment) # lint-amnesty, pylint: disable=raise-missing-from
raise CourseEnrollmentExistsError(str(err), enrollment) # lint-amnesty, pylint: disable=raise-missing-from
def update_course_enrollment(username, course_id, mode=None, is_active=None):
@@ -180,7 +179,7 @@ def update_course_enrollment(username, course_id, mode=None, is_active=None):
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
msg = u"Not user with username '{username}' found.".format(username=username)
msg = f"Not user with username '{username}' found."
log.warning(msg)
raise UserNotFoundError(msg) # lint-amnesty, pylint: disable=raise-missing-from
@@ -257,7 +256,7 @@ def unenroll_user_from_all_courses(username):
for enrollment in enrollments:
_update_enrollment(enrollment, is_active=False)
return set([str(enrollment.course_id.org) for enrollment in enrollments]) # lint-amnesty, pylint: disable=consider-using-set-comprehension
return {str(enrollment.course_id.org) for enrollment in enrollments} # lint-amnesty, pylint: disable=consider-using-set-comprehension
def _get_user(username):
@@ -271,7 +270,7 @@ def _get_user(username):
try:
return User.objects.get(username=username)
except User.DoesNotExist:
msg = u"Not user with username '{username}' found.".format(username=username)
msg = f"Not user with username '{username}' found."
log.warning(msg)
raise UserNotFoundError(msg) # lint-amnesty, pylint: disable=raise-missing-from
@@ -294,17 +293,17 @@ def _invalid_attribute(attributes):
invalid_attributes = []
for attribute in attributes:
if "namespace" not in attribute:
msg = u"'namespace' not in enrollment attribute"
msg = "'namespace' not in enrollment attribute"
log.warning(msg)
invalid_attributes.append("namespace")
raise InvalidEnrollmentAttribute(msg)
if "name" not in attribute:
msg = u"'name' not in enrollment attribute"
msg = "'name' not in enrollment attribute"
log.warning(msg)
invalid_attributes.append("name")
raise InvalidEnrollmentAttribute(msg)
if "value" not in attribute:
msg = u"'value' not in enrollment attribute"
msg = "'value' not in enrollment attribute"
log.warning(msg)
invalid_attributes.append("value")
raise InvalidEnrollmentAttribute(msg)
@@ -335,7 +334,7 @@ def get_course_enrollment_info(course_id, include_expired=False):
try:
course = CourseOverview.get_from_id(course_key)
except CourseOverview.DoesNotExist:
msg = u"Requested enrollment information for unknown course {course}".format(course=course_id)
msg = f"Requested enrollment information for unknown course {course_id}"
log.warning(msg)
raise CourseNotFoundError(msg) # lint-amnesty, pylint: disable=raise-missing-from
else:

View File

@@ -8,7 +8,7 @@ class CourseEnrollmentError(Exception):
"""
def __init__(self, msg, data=None):
super(CourseEnrollmentError, self).__init__(msg) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(msg)
# Corresponding information to help resolve the error.
self.data = data
@@ -29,7 +29,7 @@ class CourseEnrollmentExistsError(CourseEnrollmentError): # lint-amnesty, pylin
enrollment = None
def __init__(self, message, enrollment):
super(CourseEnrollmentExistsError, self).__init__(message) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(message)
self.enrollment = enrollment

View File

@@ -28,7 +28,7 @@ class CourseEnrollmentsApiListForm(Form):
try:
return CourseKey.from_string(course_id)
except InvalidKeyError:
raise ValidationError(u"'{}' is not a valid course id.".format(course_id)) # lint-amnesty, pylint: disable=raise-missing-from
raise ValidationError(f"'{course_id}' is not a valid course id.") # lint-amnesty, pylint: disable=raise-missing-from
return course_id
def clean_username(self):
@@ -40,7 +40,7 @@ class CourseEnrollmentsApiListForm(Form):
usernames = usernames_csv_string.split(',')
if len(usernames) > self.MAX_USERNAME_COUNT:
raise ValidationError(
u"Too many usernames in a single request - {}. A maximum of {} is allowed".format(
"Too many usernames in a single request - {}. A maximum of {} is allowed".format(
len(usernames),
self.MAX_USERNAME_COUNT,
)

View File

@@ -14,8 +14,6 @@ from common.djangoapps.student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
import six # lint-amnesty, pylint: disable=wrong-import-order
from six.moves import range # lint-amnesty, pylint: disable=wrong-import-order
@ddt.ddt
@@ -27,12 +25,12 @@ class EnrollManagementCommandTest(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(EnrollManagementCommandTest, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create(org='fooX', number='007')
def setUp(self):
super(EnrollManagementCommandTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
self.course_id = six.text_type(self.course.id)
super().setUp()
self.course_id = str(self.course.id)
self.username = 'ralph' + uuid4().hex
self.user_email = self.username + '@example.com'

View File

@@ -45,13 +45,13 @@ class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-meth
invite_only = serializers.BooleanField(source="invitation_only")
course_modes = serializers.SerializerMethodField()
class Meta(object):
class Meta:
# For disambiguating within the drf-yasg swagger schema
ref_name = 'enrollment.Course'
def __init__(self, *args, **kwargs):
self.include_expired = kwargs.pop("include_expired", False)
super(CourseSerializer, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
def get_course_modes(self, obj):
"""
@@ -82,7 +82,7 @@ class CourseEnrollmentSerializer(serializers.ModelSerializer):
"""Retrieves the username from the associated model."""
return model.username
class Meta(object):
class Meta:
model = CourseEnrollment
fields = ('created', 'mode', 'is_active', 'course_details', 'user')
lookup_field = 'username'
@@ -96,7 +96,7 @@ class CourseEnrollmentsApiListSerializer(CourseEnrollmentSerializer):
course_id = serializers.CharField(source='course_overview.id')
def __init__(self, *args, **kwargs):
super(CourseEnrollmentsApiListSerializer, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
self.fields.pop('course_details')
class Meta(CourseEnrollmentSerializer.Meta):

View File

@@ -13,7 +13,7 @@ from common.djangoapps.student.models import CourseEnrollment
from xmodule.modulestore.django import modulestore
class EnrollmentsService(object):
class EnrollmentsService:
"""
Enrollments service

View File

@@ -4,12 +4,12 @@ Tests for student enrollment.
import unittest
from unittest.mock import Mock, patch
import ddt
import pytest
from django.conf import settings
from django.test.utils import override_settings
from mock import Mock, patch
from common.djangoapps.course_modes.models import CourseMode
from openedx.core.djangoapps.enrollments import api
@@ -33,7 +33,7 @@ class EnrollmentTest(CacheIsolationTestCase):
ENABLED_CACHES = ['default']
def setUp(self):
super(EnrollmentTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
fake_data_api.reset()
@ddt.data(

View File

@@ -6,14 +6,12 @@ Test the Data Aggregation Layer for Course Enrollments.
import datetime
import unittest
from unittest.mock import patch
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 common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
@@ -45,7 +43,7 @@ class EnrollmentDataTest(ModuleStoreTestCase):
def setUp(self):
"""Create a course and user, then log in. """
super(EnrollmentDataTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create()
self.user = UserFactory.create(username=self.USERNAME, email=self.EMAIL, password=self.PASSWORD)
self.client.login(username=self.USERNAME, password=self.PASSWORD)
@@ -66,7 +64,7 @@ class EnrollmentDataTest(ModuleStoreTestCase):
self._create_course_modes(course_modes)
enrollment = data.create_course_enrollment(
self.user.username,
six.text_type(self.course.id),
str(self.course.id),
enrollment_mode,
True
)
@@ -87,7 +85,7 @@ class EnrollmentDataTest(ModuleStoreTestCase):
enrollment = data.update_course_enrollment(
self.user.username,
six.text_type(self.course.id),
str(self.course.id),
is_active=False
)
@@ -106,7 +104,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(six.text_type(self.course.id))
result_course = data.get_course_enrollment_info(str(self.course.id))
result_slugs = [mode['slug'] for mode in result_course['course_modes']]
for course_mode in course_modes:
assert course_mode in result_slugs
@@ -131,7 +129,7 @@ class EnrollmentDataTest(ModuleStoreTestCase):
# Create the original enrollment.
created_enrollments.append(data.create_course_enrollment(
self.user.username,
six.text_type(course.id),
str(course.id),
'honor',
True
))
@@ -172,7 +170,7 @@ class EnrollmentDataTest(ModuleStoreTestCase):
# Create the original enrollment.
created_enrollments.append(data.create_course_enrollment(
self.user.username,
six.text_type(course.id),
str(course.id),
'honor',
True
))
@@ -180,7 +178,7 @@ class EnrollmentDataTest(ModuleStoreTestCase):
# deactivate one enrollment
data.update_course_enrollment(
self.user.username,
six.text_type(created_courses[0].id),
str(created_courses[0].id),
'honor',
False
)
@@ -208,18 +206,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, six.text_type(self.course.id))
result = data.get_course_enrollment(self.user.username, str(self.course.id))
assert result is None
# Create the original enrollment.
enrollment = data.create_course_enrollment(
self.user.username,
six.text_type(self.course.id),
str(self.course.id),
enrollment_mode,
True
)
# Get the enrollment and compare it to the original.
result = data.get_course_enrollment(self.user.username, six.text_type(self.course.id))
result = data.get_course_enrollment(self.user.username, str(self.course.id))
assert self.user.username == result['user']
assert enrollment == result
@@ -255,7 +253,7 @@ class EnrollmentDataTest(ModuleStoreTestCase):
for user in users:
created_enrollments.append(data.create_course_enrollment(
user.username,
six.text_type(self.course.id),
str(self.course.id),
enrollment_mode,
True
))
@@ -282,7 +280,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, six.text_type(self.course.id), enrollment_mode, True)
data.create_course_enrollment(self.user.username, str(self.course.id), enrollment_mode, True)
enrollment_attributes = [
{
"namespace": "credit",
@@ -291,8 +289,8 @@ class EnrollmentDataTest(ModuleStoreTestCase):
}
]
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))
data.add_or_update_enrollment_attr(self.user.username, str(self.course.id), enrollment_attributes)
enrollment_attr = data.get_enrollment_attributes(self.user.username, str(self.course.id))
assert enrollment_attr[0] == enrollment_attributes[0]
enrollment_attributes = [
@@ -303,8 +301,8 @@ class EnrollmentDataTest(ModuleStoreTestCase):
}
]
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))
data.add_or_update_enrollment_attr(self.user.username, str(self.course.id), enrollment_attributes)
enrollment_attr = data.get_enrollment_attributes(self.user.username, str(self.course.id))
assert enrollment_attr[0] == enrollment_attributes[0]
def test_non_existent_course(self):
@@ -323,7 +321,7 @@ class EnrollmentDataTest(ModuleStoreTestCase):
def test_enrollment_for_non_existent_user(self):
with pytest.raises(UserNotFoundError):
data.create_course_enrollment("some_fake_user", six.text_type(self.course.id), 'honor', True)
data.create_course_enrollment("some_fake_user", str(self.course.id), 'honor', True)
def test_enrollment_for_non_existent_course(self):
with pytest.raises(CourseNotFoundError):
@@ -333,23 +331,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, six.text_type(self.course.id), 'honor', True)
data.create_course_enrollment(self.user.username, str(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, six.text_type(self.course.id), 'honor', True)
data.create_course_enrollment(self.user.username, str(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, six.text_type(self.course.id), 'honor', True)
data.create_course_enrollment(self.user.username, str(self.course.id), 'honor', True)
def test_update_for_non_existent_user(self):
with pytest.raises(UserNotFoundError):
data.update_course_enrollment("some_fake_user", six.text_type(self.course.id), is_active=False)
data.update_course_enrollment("some_fake_user", str(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)
@@ -378,7 +376,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(six.text_type(self.course.id), include_expired=include_expired)
result_course = data.get_course_enrollment_info(str(self.course.id), include_expired=include_expired)
result_slugs = [mode['slug'] for mode in result_course['course_modes']]
for course_mode in expected_modes:
assert course_mode in result_slugs

View File

@@ -36,8 +36,8 @@ class EnrollmentsServiceTests(ModuleStoreTestCase):
CourseModeFactory.create(mode_slug=course_mode, course_id=course_id)
user = UserFactory(
username='user{}'.format(index),
email='LEARNER{}@example.com'.format(index)
username=f'user{index}',
email=f'LEARNER{index}@example.com'
)
CourseEnrollment.enroll(user, course_id, mode=course_mode)
@@ -186,7 +186,7 @@ class EnrollmentsServicePerformanceTests(ModuleStoreTestCase):
def create_and_enroll_users(self, num_users):
num_course_modes = len(self.course_modes)
for index in range(num_users):
user = UserFactory(username='user{}'.format(index))
user = UserFactory(username=f'user{index}')
CourseEnrollment.enroll(user, self.course.id, mode=self.course_modes[index % num_course_modes])
@ddt.data(10, 25, 50)

View File

@@ -8,11 +8,11 @@ import datetime
import itertools
import json
import unittest
from unittest.mock import patch
import pytest
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
@@ -21,11 +21,8 @@ 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 six import text_type
from six.moves import range
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
@@ -50,7 +47,7 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls_range
class EnrollmentTestMixin(object):
class EnrollmentTestMixin:
""" Mixin with methods useful for testing enrollments. """
API_KEY = "i am a key"
@@ -76,7 +73,7 @@ class EnrollmentTestMixin(object):
Returns
Response
"""
course_id = course_id or six.text_type(self.course.id)
course_id = course_id or str(self.course.id)
username = username or self.user.username
data = {
@@ -171,7 +168,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
def setUp(self):
""" Create a course and user, then log in. """
super(EnrollmentTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.rate_limit_config = RateLimitConfiguration.current()
self.rate_limit_config.enabled = False
@@ -240,19 +237,19 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
resp = self.client.get(
reverse(
'courseenrollment',
kwargs={'username': self.user.username, "course_id": six.text_type(self.course.id)},
kwargs={'username': self.user.username, "course_id": str(self.course.id)},
)
)
assert resp.status_code == status.HTTP_200_OK
data = json.loads(resp.content.decode('utf-8'))
assert six.text_type(self.course.id) == data['course_details']['course_id']
assert str(self.course.id) == data['course_details']['course_id']
assert self.course.display_name_with_default == data['course_details']['course_name']
assert CourseMode.DEFAULT_MODE_SLUG == data['mode']
assert data['is_active']
@ddt.data(
(True, u"True"),
(False, u"False"),
(True, "True"),
(False, "False"),
(None, None)
)
@ddt.unpack
@@ -289,7 +286,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.decode('utf-8'))
assert six.text_type(self.course.id) == data['course_details']['course_id']
assert str(self.course.id) == data['course_details']['course_id']
assert 1 == len(data['course_details']['course_modes'])
assert 'professional' == data['course_details']['course_modes'][0]['slug']
@@ -302,11 +299,11 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
# Create an enrollment
self.assert_enrollment_status()
resp = self.client.get(
reverse('courseenrollment', kwargs={"course_id": six.text_type(self.course.id)})
reverse('courseenrollment', kwargs={"course_id": str(self.course.id)})
)
assert resp.status_code == status.HTTP_200_OK
data = json.loads(resp.content.decode('utf-8'))
assert six.text_type(self.course.id) == data['course_details']['course_id']
assert str(self.course.id) == data['course_details']['course_id']
assert CourseMode.DEFAULT_MODE_SLUG == data['mode']
assert data['is_active']
@@ -363,10 +360,9 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
response = self.client.get(reverse('courseenrollments'), {'user': self.user.username}, **kwargs)
assert response.status_code == status.HTTP_200_OK
data = json.loads(response.content.decode('utf-8'))
six.assertCountEqual(
self,
self.assertCountEqual(
[(datum['course_details']['course_id'], datum['course_details']['course_name']) for datum in data],
[(six.text_type(course.id), course.display_name_with_default) for course in courses]
[(str(course.id), course.display_name_with_default) for course in courses]
)
def test_enrollment_list_permissions(self):
@@ -378,12 +374,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=six.text_type(course.id),
course_id=str(course.id),
mode_slug=CourseMode.DEFAULT_MODE_SLUG,
mode_display_name=CourseMode.DEFAULT_MODE_SLUG,
)
self.assert_enrollment_status(
course_id=six.text_type(course.id),
course_id=str(course.id),
max_mongo_calls=0,
)
# Verify the user himself can see both of his enrollments.
@@ -416,7 +412,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
mode_display_name=CourseMode.HONOR,
)
url = reverse('courseenrollment',
kwargs={'username': self.other_user.username, "course_id": six.text_type(self.course.id)})
kwargs={'username': self.other_user.username, "course_id": str(self.course.id)})
response = self.client.get(url)
assert response.status_code == status.HTTP_404_NOT_FOUND
@@ -441,12 +437,12 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
bulk_sku="BULK123"
)
resp = self.client.get(
reverse('courseenrollmentdetails', kwargs={"course_id": six.text_type(self.course.id)})
reverse('courseenrollmentdetails', kwargs={"course_id": str(self.course.id)})
)
assert resp.status_code == status.HTTP_200_OK
data = json.loads(resp.content.decode('utf-8'))
assert six.text_type(self.course.id) == data['course_id']
assert str(self.course.id) == data['course_id']
assert self.course.display_name_with_default == data['course_name']
mode = data['course_modes'][0]
assert mode['slug'] == CourseMode.HONOR
@@ -461,12 +457,12 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
mode_display_name=CourseMode.CREDIT_MODE,
)
resp = self.client.get(
reverse('courseenrollmentdetails', kwargs={"course_id": six.text_type(self.course.id)})
reverse('courseenrollmentdetails', kwargs={"course_id": str(self.course.id)})
)
assert resp.status_code == status.HTTP_200_OK
data = json.loads(resp.content.decode('utf-8'))
assert six.text_type(self.course.id) == data['course_id']
assert str(self.course.id) == data['course_id']
mode = data['course_modes'][0]
assert mode['slug'] == CourseMode.CREDIT_MODE
assert mode['name'] == CourseMode.CREDIT_MODE
@@ -492,10 +488,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=six.text_type(course.id))
self.assert_enrollment_status(course_id=str(course.id))
# Check course details
url = reverse('courseenrollmentdetails', kwargs={"course_id": six.text_type(course.id)})
url = reverse('courseenrollmentdetails', kwargs={"course_id": str(course.id)})
resp = self.client.get(url)
assert resp.status_code == status.HTTP_200_OK
@@ -504,7 +500,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
assert data['course_end'] == expected_end
# Check enrollment course details
url = reverse('courseenrollment', kwargs={"course_id": six.text_type(course.id)})
url = reverse('courseenrollment', kwargs={"course_id": str(course.id)})
resp = self.client.get(url)
assert resp.status_code == status.HTTP_200_OK
@@ -540,7 +536,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
resp = self.client.get(
reverse(
'courseenrollment',
kwargs={'username': self.user.username, "course_id": six.text_type(self.course.id)},
kwargs={'username': self.user.username, "course_id": str(self.course.id)},
)
)
assert resp.status_code == status.HTTP_400_BAD_REQUEST
@@ -592,7 +588,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
try:
throttle.parse_rate(throttle.get_rate())
except ImproperlyConfigured:
self.fail(u"No throttle rate set for {}".format(user_scope))
self.fail(f"No throttle rate set for {user_scope}")
def test_create_enrollment_with_cohort(self):
"""Enroll in the course, and also add to a cohort."""
@@ -654,7 +650,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
v_response = self.client.get(
reverse(
'courseenrollmentdetails',
kwargs={"course_id": six.text_type(self.course.id)}
kwargs={"course_id": str(self.course.id)}
),
{'include_expired': True},
)
@@ -665,7 +661,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
# Omits the include_expired parameter from the API call
h_response = self.client.get(
reverse('courseenrollmentdetails', kwargs={"course_id": six.text_type(self.course.id)}),
reverse('courseenrollmentdetails', kwargs={"course_id": str(self.course.id)}),
)
h_data = json.loads(h_response.content.decode('utf-8'))
@@ -1079,7 +1075,7 @@ class EnrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase, APITestCase, Ente
)
consent_kwargs = {
'username': self.user.username,
'course_id': six.text_type(self.course.id),
'course_id': str(self.course.id),
'ec_uuid': 'this-is-a-real-uuid'
}
mock_enterprise_customer_from_api.return_value = FAKE_ENTERPRISE_CUSTOMER
@@ -1158,7 +1154,7 @@ class EnrollmentEmbargoTest(EnrollmentTestMixin, UrlResetMixin, ModuleStoreTestC
@patch.dict(settings.FEATURES, {'EMBARGO': True})
def setUp(self):
""" Create a course and user, then log in. """
super(EnrollmentEmbargoTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create()
# Load a CourseOverview. This initial load should result in a cache
@@ -1172,7 +1168,7 @@ class EnrollmentEmbargoTest(EnrollmentTestMixin, UrlResetMixin, ModuleStoreTestC
def _generate_data(self):
return json.dumps({
'course_details': {
'course_id': six.text_type(self.course.id)
'course_id': str(self.course.id)
},
'user': self.user.username
})
@@ -1288,7 +1284,7 @@ class EnrollmentCrossDomainTest(ModuleStoreTestCase):
def setUp(self):
""" Create a course and user, then log in. """
super(EnrollmentCrossDomainTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create()
self.user = UserFactory.create(username=self.USERNAME, email=self.EMAIL, password=self.PASSWORD)
@@ -1312,7 +1308,7 @@ class EnrollmentCrossDomainTest(ModuleStoreTestCase):
def _get_csrf_cookie(self):
"""Retrieve the cross-domain CSRF cookie. """
url = reverse('courseenrollment', kwargs={
'course_id': six.text_type(self.course.id)
'course_id': str(self.course.id)
})
resp = self.client.get(url, HTTP_REFERER=self.REFERER)
assert resp.status_code == 200
@@ -1324,7 +1320,7 @@ class EnrollmentCrossDomainTest(ModuleStoreTestCase):
url = reverse('courseenrollments')
params = json.dumps({
'course_details': {
'course_id': six.text_type(self.course.id),
'course_id': str(self.course.id),
},
'user': self.user.username
})
@@ -1351,7 +1347,7 @@ class UnenrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase):
def setUp(self):
""" Create a course and user, then log in. """
super(UnenrollmentTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.superuser = SuperuserFactory()
# Pass emit_signals when creating the course so it would be cached
# as a CourseOverview. Enrollments require a cached CourseOverview.
@@ -1431,7 +1427,7 @@ class UnenrollmentTest(EnrollmentTestMixin, ModuleStoreTestCase):
response = self._submit_unenroll(self.superuser, None)
assert response.status_code == status.HTTP_404_NOT_FOUND
data = json.loads(response.content.decode('utf-8'))
assert data == u'Username not specified.'
assert data == 'Username not specified.'
self._assert_active()
def test_deactivate_enrollments_empty_username(self):
@@ -1495,7 +1491,7 @@ class UserRoleTest(ModuleStoreTestCase):
def setUp(self):
""" Create a course and user, then log in. """
super(UserRoleTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course1 = CourseFactory.create(emit_signals=True, org="org1", course="course1", run="run1")
self.course2 = CourseFactory.create(emit_signals=True, org="org2", course="course2", run="run2")
self.user = UserFactory.create(
@@ -1514,7 +1510,7 @@ class UserRoleTest(ModuleStoreTestCase):
def _create_expected_role_dict(self, course, role):
""" Creates the expected role dict object that the view should return """
return {
'course_id': text_type(course.id),
'course_id': str(course.id),
'org': course.org,
'role': role.ROLE,
}
@@ -1570,8 +1566,8 @@ class UserRoleTest(ModuleStoreTestCase):
role2 = CourseStaffRole(self.course2.id)
role2.add_users(self.user)
expected_role2 = self._create_expected_role_dict(self.course2, role2)
self._assert_roles([expected_role1], False, course_id=text_type(self.course1.id))
self._assert_roles([expected_role2], False, course_id=text_type(self.course2.id))
self._assert_roles([expected_role1], False, course_id=str(self.course1.id))
self._assert_roles([expected_role2], False, course_id=str(self.course2.id))
def test_roles_exception(self):
with patch('openedx.core.djangoapps.enrollments.api.get_user_roles') as mock_get_user_roles:
@@ -1580,7 +1576,7 @@ class UserRoleTest(ModuleStoreTestCase):
assert response.status_code == status.HTTP_400_BAD_REQUEST
expected_response = {
"message": (
u"An error occurred while retrieving roles for user '{username}"
"An error occurred while retrieving roles for user '{username}"
).format(username=self.user.username)
}
response_data = json.loads(response.content.decode('utf-8'))
@@ -1596,7 +1592,7 @@ class CourseEnrollmentsApiListTest(APITestCase, ModuleStoreTestCase):
CREATED_DATA = datetime.datetime(2018, 1, 1, 0, 0, 1, tzinfo=pytz.UTC)
def setUp(self):
super(CourseEnrollmentsApiListTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.rate_limit_config = RateLimitConfiguration.current()
self.rate_limit_config.enabled = False
self.rate_limit_config.save()
@@ -1641,31 +1637,31 @@ class CourseEnrollmentsApiListTest(APITestCase, ModuleStoreTestCase):
with freeze_time(self.CREATED_DATA):
data.create_course_enrollment(
self.student1.username,
six.text_type(self.course.id),
str(self.course.id),
'honor',
True
)
data.create_course_enrollment(
self.student2.username,
six.text_type(self.course.id),
str(self.course.id),
'honor',
True
)
data.create_course_enrollment(
self.student3.username,
six.text_type(self.course2.id),
str(self.course2.id),
'verified',
True
)
data.create_course_enrollment(
self.student2.username,
six.text_type(self.course2.id),
str(self.course2.id),
'honor',
True
)
data.create_course_enrollment(
self.staff_user.username,
six.text_type(self.course2.id),
str(self.course2.id),
'verified',
True
)
@@ -1742,4 +1738,4 @@ class CourseEnrollmentsApiListTest(APITestCase, ModuleStoreTestCase):
content = self._assert_list_of_enrollments(query_params, status.HTTP_200_OK)
results = content['results']
six.assertCountEqual(self, results, expected_results)
self.assertCountEqual(results, expected_results)

View File

@@ -21,11 +21,11 @@ urlpatterns = [
username=settings.USERNAME_PATTERN,
course_key=settings.COURSE_ID_PATTERN),
EnrollmentView.as_view(), name='courseenrollment'),
url(r'^enrollment/{course_key}$'.format(course_key=settings.COURSE_ID_PATTERN),
url(fr'^enrollment/{settings.COURSE_ID_PATTERN}$',
EnrollmentView.as_view(), name='courseenrollment'),
url(r'^enrollment$', EnrollmentListView.as_view(), name='courseenrollments'),
url(r'^enrollments/?$', CourseEnrollmentsApiListView.as_view(), name='courseenrollmentsapilist'),
url(r'^course/{course_key}$'.format(course_key=settings.COURSE_ID_PATTERN),
url(fr'^course/{settings.COURSE_ID_PATTERN}$',
EnrollmentCourseDetailView.as_view(), name='courseenrollmentdetails'),
url(r'^unenroll/$', UnenrollmentView.as_view(), name='unenrollment'),
url(r'^roles/$', EnrollmentUserRolesView.as_view(), name='roles'),

View File

@@ -7,8 +7,6 @@ consist primarily of authentication, request validation, and serialization.
import logging
from six import text_type
from common.djangoapps.course_modes.models import CourseMode
from django.core.exceptions import ObjectDoesNotExist, ValidationError # lint-amnesty, pylint: disable=wrong-import-order
from django.utils.decorators import method_decorator # lint-amnesty, pylint: disable=wrong-import-order
@@ -62,7 +60,7 @@ class EnrollmentCrossDomainSessionAuth(SessionAuthenticationAllowInactiveUser, S
pass # lint-amnesty, pylint: disable=unnecessary-pass
class ApiKeyPermissionMixIn(object):
class ApiKeyPermissionMixIn:
"""
This mixin is used to provide a convenience function for doing individual permission checks
for the presence of API keys.
@@ -99,7 +97,7 @@ class EnrollmentUserThrottle(UserRateThrottle, ApiKeyPermissionMixIn):
self.rate = self.get_rate()
self.num_requests, self.duration = self.parse_rate(self.rate)
return self.has_api_key_permissions(request) or super(EnrollmentUserThrottle, self).allow_request(request, view) # lint-amnesty, pylint: disable=super-with-arguments
return self.has_api_key_permissions(request) or super().allow_request(request, view)
@can_disable_rate_limit
@@ -210,8 +208,8 @@ class EnrollmentView(APIView, ApiKeyPermissionMixIn):
status=status.HTTP_400_BAD_REQUEST,
data={
"message": (
u"An error occurred while retrieving enrollments for user "
u"'{username}' in course '{course_id}'"
"An error occurred while retrieving enrollments for user "
"'{username}' in course '{course_id}'"
).format(username=username, course_id=course_id)
}
)
@@ -258,13 +256,13 @@ class EnrollmentUserRolesView(APIView):
course_id = request.GET.get('course_id')
roles_data = api.get_user_roles(request.user.username)
if course_id:
roles_data = [role for role in roles_data if text_type(role.course_id) == course_id]
roles_data = [role for role in roles_data if str(role.course_id) == course_id]
except Exception: # pylint: disable=broad-except
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
"message": (
u"An error occurred while retrieving roles for user '{username}"
"An error occurred while retrieving roles for user '{username}"
).format(username=request.user.username)
}
)
@@ -272,7 +270,7 @@ class EnrollmentUserRolesView(APIView):
'roles': [
{
"org": role.org,
"course_id": text_type(role.course_id),
"course_id": str(role.course_id),
"role": role.role
}
for role in roles_data],
@@ -370,7 +368,7 @@ class EnrollmentCourseDetailView(APIView):
status=status.HTTP_400_BAD_REQUEST,
data={
"message": (
u"No course found for course ID '{course_id}'"
"No course found for course ID '{course_id}'"
).format(course_id=course_id)
}
)
@@ -429,11 +427,11 @@ class UnenrollmentView(APIView):
return Response(status=status.HTTP_204_NO_CONTENT)
return Response(api.unenroll_user_from_all_courses(username))
except KeyError:
return Response(u'Username not specified.', status=status.HTTP_404_NOT_FOUND)
return Response('Username not specified.', status=status.HTTP_404_NOT_FOUND)
except UserRetirementStatus.DoesNotExist:
return Response(u'No retirement request status for username.', status=status.HTTP_404_NOT_FOUND)
return Response('No retirement request status for username.', status=status.HTTP_404_NOT_FOUND)
except Exception as exc: # pylint: disable=broad-except
return Response(text_type(exc), status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response(str(exc), status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@can_disable_rate_limit
@@ -647,7 +645,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
status=status.HTTP_400_BAD_REQUEST,
data={
"message": (
u"An error occurred while retrieving enrollments for user '{username}'"
"An error occurred while retrieving enrollments for user '{username}'"
).format(username=username)
}
)
@@ -676,7 +674,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
if not course_id:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={"message": u"Course ID must be specified to create a new enrollment."}
data={"message": "Course ID must be specified to create a new enrollment."}
)
try:
@@ -685,7 +683,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
"message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
"message": f"No course '{course_id}' found for enrollment"
}
)
@@ -707,7 +705,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
return Response(
status=status.HTTP_403_FORBIDDEN,
data={
"message": u"User does not have permission to create enrollment with mode [{mode}].".format(
"message": "User does not have permission to create enrollment with mode [{mode}].".format(
mode=mode
)
}
@@ -720,7 +718,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
return Response(
status=status.HTTP_406_NOT_ACCEPTABLE,
data={
'message': u'The user {} does not exist.'.format(username)
'message': f'The user {username} does not exist.'
}
)
@@ -736,7 +734,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
'message': (u"'{value}' is an invalid enrollment activation status.").format(value=is_active)
'message': ("'{value}' is an invalid enrollment activation status.").format(value=is_active)
}
)
@@ -745,26 +743,26 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
enterprise_api_client = EnterpriseApiServiceClient()
consent_client = ConsentApiServiceClient()
try:
enterprise_api_client.post_enterprise_course_enrollment(username, text_type(course_id), None)
enterprise_api_client.post_enterprise_course_enrollment(username, str(course_id), None)
except EnterpriseApiException as error:
log.exception(u"An unexpected error occurred while creating the new EnterpriseCourseEnrollment "
u"for user [%s] in course run [%s]", username, course_id)
raise CourseEnrollmentError(text_type(error)) # lint-amnesty, pylint: disable=raise-missing-from
log.exception("An unexpected error occurred while creating the new EnterpriseCourseEnrollment "
"for user [%s] in course run [%s]", username, course_id)
raise CourseEnrollmentError(str(error)) # lint-amnesty, pylint: disable=raise-missing-from
kwargs = {
'username': username,
'course_id': text_type(course_id),
'course_id': str(course_id),
'enterprise_customer_uuid': explicit_linked_enterprise,
}
consent_client.provide_consent(**kwargs)
enrollment_attributes = request.data.get('enrollment_attributes')
enrollment = api.get_enrollment(username, text_type(course_id))
enrollment = api.get_enrollment(username, str(course_id))
mode_changed = enrollment and mode is not None and enrollment['mode'] != mode
active_changed = enrollment and is_active is not None and enrollment['is_active'] != is_active
missing_attrs = []
if enrollment_attributes:
actual_attrs = [
u"{namespace}:{name}".format(**attr)
"{namespace}:{name}".format(**attr)
for attr in enrollment_attributes
]
missing_attrs = set(REQUIRED_ATTRIBUTES.get(mode, [])) - set(actual_attrs)
@@ -773,14 +771,14 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
# if the requester wanted to deactivate but specified the wrong mode, fail
# the request (on the assumption that the requester had outdated information
# about the currently active enrollment).
msg = u"Enrollment mode mismatch: active mode={}, requested mode={}. Won't deactivate.".format(
msg = "Enrollment mode mismatch: active mode={}, requested mode={}. Won't deactivate.".format(
enrollment["mode"], mode
)
log.warning(msg)
return Response(status=status.HTTP_400_BAD_REQUEST, data={"message": msg})
if missing_attrs:
msg = u"Missing enrollment attributes: requested mode={} required attributes={}".format(
msg = "Missing enrollment attributes: requested mode={} required attributes={}".format(
mode, REQUIRED_ATTRIBUTES.get(mode)
)
log.warning(msg)
@@ -788,7 +786,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
response = api.update_enrollment(
username,
text_type(course_id),
str(course_id),
mode=mode,
is_active=is_active,
enrollment_attributes=enrollment_attributes,
@@ -799,7 +797,7 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
# Will reactivate inactive enrollments.
response = api.add_enrollment(
username,
text_type(course_id),
str(course_id),
mode=mode,
is_active=is_active,
enrollment_attributes=enrollment_attributes
@@ -818,14 +816,14 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
org = course_id.org
update_email_opt_in(request.user, org, email_opt_in)
log.info(u'The user [%s] has already been enrolled in course run [%s].', username, course_id)
log.info('The user [%s] has already been enrolled in course run [%s].', username, course_id)
return Response(response)
except CourseModeNotFoundError as error:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
"message": (
u"The [{mode}] course mode is expired or otherwise unavailable for course run [{course_id}]."
"The [{mode}] course mode is expired or otherwise unavailable for course run [{course_id}]."
).format(mode=mode, course_id=course_id),
"course_details": error.data
})
@@ -833,38 +831,38 @@ class EnrollmentListView(APIView, ApiKeyPermissionMixIn):
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
"message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
"message": f"No course '{course_id}' found for enrollment"
}
)
except CourseEnrollmentExistsError as error:
log.warning(u'An enrollment already exists for user [%s] in course run [%s].', username, course_id)
log.warning('An enrollment already exists for user [%s] in course run [%s].', username, course_id)
return Response(data=error.enrollment)
except CourseEnrollmentError:
log.exception(u"An error occurred while creating the new course enrollment for user "
u"[%s] in course run [%s]", username, course_id)
log.exception("An error occurred while creating the new course enrollment for user "
"[%s] in course run [%s]", username, course_id)
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
"message": (
u"An error occurred while creating the new course enrollment for user "
u"'{username}' in course '{course_id}'"
"An error occurred while creating the new course enrollment for user "
"'{username}' in course '{course_id}'"
).format(username=username, course_id=course_id)
}
)
except CourseUserGroup.DoesNotExist:
log.exception(u'Missing cohort [%s] in course run [%s]', cohort_name, course_id)
log.exception('Missing cohort [%s] in course run [%s]', cohort_name, course_id)
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
"message": u"An error occured while adding to cohort [%s]" % cohort_name
"message": "An error occured while adding to cohort [%s]" % cohort_name
})
finally:
# Assumes that the ecommerce service uses an API key to authenticate.
if has_api_key_permissions:
current_enrollment = api.get_enrollment(username, text_type(course_id))
current_enrollment = api.get_enrollment(username, str(course_id))
audit_log(
'enrollment_change_requested',
course_id=text_type(course_id),
course_id=str(course_id),
requested_mode=mode,
actual_mode=current_enrollment['mode'] if current_enrollment else None,
requested_activation=is_active,