diff --git a/lms/djangoapps/instructor/access.py b/lms/djangoapps/instructor/access.py
index 2619b7aaf0..ece469ea63 100644
--- a/lms/djangoapps/instructor/access.py
+++ b/lms/djangoapps/instructor/access.py
@@ -12,12 +12,15 @@ TO DO sync instructor and staff flags
import logging
+from common.djangoapps.student.roles import (
+ CourseBetaTesterRole,
+ CourseCcxCoachRole,
+ CourseDataResearcherRole,
+ CourseInstructorRole,
+ CourseStaffRole
+)
from lms.djangoapps.instructor.enrollment import enroll_email, get_email_params
from openedx.core.djangoapps.django_comment_common.models import Role
-from common.djangoapps.student.roles import (
- CourseBetaTesterRole, CourseCcxCoachRole, CourseDataResearcherRole,
- CourseInstructorRole, CourseStaffRole
-)
log = logging.getLogger(__name__)
@@ -72,7 +75,7 @@ def _change_access(course, user, level, action, send_email=True):
try:
role = ROLES[level](course.id)
except KeyError:
- raise ValueError(u"unrecognized level '{}'".format(level)) # lint-amnesty, pylint: disable=raise-missing-from
+ raise ValueError(f"unrecognized level '{level}'") # lint-amnesty, pylint: disable=raise-missing-from
if action == 'allow':
if level == 'ccx_coach':
@@ -88,7 +91,7 @@ def _change_access(course, user, level, action, send_email=True):
elif action == 'revoke':
role.remove_users(user)
else:
- raise ValueError(u"unrecognized action '{}'".format(action))
+ raise ValueError(f"unrecognized action '{action}'")
def update_forum_role(course_id, user, rolename, action):
@@ -108,4 +111,4 @@ def update_forum_role(course_id, user, rolename, action):
elif action == 'revoke':
role.users.remove(user)
else:
- raise ValueError(u"unrecognized action '{}'".format(action))
+ raise ValueError(f"unrecognized action '{action}'")
diff --git a/lms/djangoapps/instructor/apps.py b/lms/djangoapps/instructor/apps.py
index 5ed76baca4..6b7b05bd23 100644
--- a/lms/djangoapps/instructor/apps.py
+++ b/lms/djangoapps/instructor/apps.py
@@ -16,22 +16,22 @@ class InstructorConfig(AppConfig):
"""
Application Configuration for Instructor.
"""
- name = u'lms.djangoapps.instructor'
+ name = 'lms.djangoapps.instructor'
plugin_app = {
PluginURLs.CONFIG: {
ProjectType.LMS: {
- PluginURLs.NAMESPACE: u'',
- PluginURLs.REGEX: u'^courses/{}/instructor/api/'.format(COURSE_ID_PATTERN),
- PluginURLs.RELATIVE_PATH: u'views.api_urls',
+ PluginURLs.NAMESPACE: '',
+ PluginURLs.REGEX: f'^courses/{COURSE_ID_PATTERN}/instructor/api/',
+ PluginURLs.RELATIVE_PATH: 'views.api_urls',
}
},
PluginSettings.CONFIG: {
ProjectType.LMS: {
- SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: u'settings.devstack'},
- SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: u'settings.production'},
- SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: u'settings.common'},
- SettingsType.TEST: {PluginSettings.RELATIVE_PATH: u'settings.test'},
+ SettingsType.DEVSTACK: {PluginSettings.RELATIVE_PATH: 'settings.devstack'},
+ SettingsType.PRODUCTION: {PluginSettings.RELATIVE_PATH: 'settings.production'},
+ SettingsType.COMMON: {PluginSettings.RELATIVE_PATH: 'settings.common'},
+ SettingsType.TEST: {PluginSettings.RELATIVE_PATH: 'settings.test'},
}
}
}
diff --git a/lms/djangoapps/instructor/enrollment.py b/lms/djangoapps/instructor/enrollment.py
index e010a8b4ac..53bf7da318 100644
--- a/lms/djangoapps/instructor/enrollment.py
+++ b/lms/djangoapps/instructor/enrollment.py
@@ -10,7 +10,6 @@ import logging
from datetime import datetime
import pytz
-import six
from django.conf import settings
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.mail import send_mail # lint-amnesty, pylint: disable=unused-import
@@ -20,11 +19,21 @@ from django.utils.translation import override as override_language
from edx_ace import ace
from edx_ace.recipient import Recipient
from eventtracking import tracker
-from six import text_type
from submissions import api as sub_api # installed from the edx-submissions repository
from submissions.models import score_set
from common.djangoapps.course_modes.models import CourseMode
+from common.djangoapps.student.models import ( # lint-amnesty, pylint: disable=line-too-long
+ CourseEnrollment,
+ CourseEnrollmentAllowed,
+ anonymous_id_for_user,
+ is_email_retired
+)
+from common.djangoapps.track.event_transaction_utils import (
+ create_new_event_transaction_id,
+ get_event_transaction_id,
+ set_event_transaction_type
+)
from lms.djangoapps.courseware.models import StudentModule
from lms.djangoapps.grades.api import constants as grades_constants
from lms.djangoapps.grades.api import disconnect_submissions_signal_receiver
@@ -43,19 +52,13 @@ from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_api.models import UserPreference
from openedx.core.djangolib.markup import Text
-from common.djangoapps.student.models import CourseEnrollment, CourseEnrollmentAllowed, anonymous_id_for_user, is_email_retired # lint-amnesty, pylint: disable=line-too-long
-from common.djangoapps.track.event_transaction_utils import (
- create_new_event_transaction_id,
- get_event_transaction_id,
- set_event_transaction_type
-)
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError
log = logging.getLogger(__name__)
-class EmailEnrollmentState(object):
+class EmailEnrollmentState:
""" Store the complete enrollment state of an email in a class """
def __init__(self, course_id, email):
# N.B. retired users are not a concern here because they should be
@@ -221,7 +224,7 @@ def send_beta_role_email(action, user, email_params):
email_params['email_address'] = user.email
email_params['full_name'] = user.profile.name
else:
- raise ValueError(u"Unexpected action received '{}' - expected 'add' or 'remove'".format(action))
+ raise ValueError(f"Unexpected action received '{action}' - expected 'add' or 'remove'")
trying_to_add_inactive_user = not user.is_active and action == 'add'
if not trying_to_add_inactive_user:
send_mail_to_student(user.email, email_params, language=get_user_email_language(user))
@@ -267,8 +270,8 @@ def reset_student_attempts(course_id, student, module_state_key, requesting_user
with disconnect_submissions_signal_receiver(score_set):
clear_student_state(
user_id=user_id,
- course_id=six.text_type(course_id),
- item_id=six.text_type(module_state_key),
+ course_id=str(course_id),
+ item_id=str(module_state_key),
requesting_user_id=requesting_user_id
)
submission_cleared = True
@@ -277,7 +280,7 @@ def reset_student_attempts(course_id, student, module_state_key, requesting_user
selected_teamset_id = getattr(block, 'selected_teamset_id', None)
except ItemNotFoundError:
block = None
- log.warning(u"Could not find %s in modulestore when attempting to reset attempts.", module_state_key)
+ log.warning("Could not find %s in modulestore when attempting to reset attempts.", module_state_key)
# Reset the student's score in the submissions API, if xblock.clear_student_state has not done so already.
# We need to do this before retrieving the `StudentModule` model, because a score may exist with no student module.
@@ -287,8 +290,8 @@ def reset_student_attempts(course_id, student, module_state_key, requesting_user
if delete_module and not submission_cleared:
sub_api.reset_score(
user_id,
- text_type(course_id),
- text_type(module_state_key),
+ str(course_id),
+ str(module_state_key),
)
def _reset_or_delete_module(studentmodule):
@@ -297,14 +300,14 @@ def reset_student_attempts(course_id, student, module_state_key, requesting_user
create_new_event_transaction_id()
set_event_transaction_type(grades_events.STATE_DELETED_EVENT_TYPE)
tracker.emit(
- six.text_type(grades_events.STATE_DELETED_EVENT_TYPE),
+ str(grades_events.STATE_DELETED_EVENT_TYPE),
{
- 'user_id': six.text_type(student.id),
- 'course_id': six.text_type(course_id),
- 'problem_id': six.text_type(module_state_key),
- 'instructor_id': six.text_type(requesting_user.id),
- 'event_transaction_id': six.text_type(get_event_transaction_id()),
- 'event_transaction_type': six.text_type(grades_events.STATE_DELETED_EVENT_TYPE),
+ 'user_id': str(student.id),
+ 'course_id': str(course_id),
+ 'problem_id': str(module_state_key),
+ 'instructor_id': str(requesting_user.id),
+ 'event_transaction_id': str(get_event_transaction_id()),
+ 'event_transaction_type': str(grades_events.STATE_DELETED_EVENT_TYPE),
}
)
if not submission_cleared:
@@ -376,8 +379,8 @@ def _fire_score_changed_for_block(
raw_possible=max_score,
weight=getattr(block, 'weight', None),
user_id=student.id,
- course_id=six.text_type(course_id),
- usage_id=six.text_type(module_state_key),
+ course_id=str(course_id),
+ usage_id=str(module_state_key),
score_deleted=True,
only_if_higher=False,
modified=datetime.now().replace(tzinfo=pytz.UTC),
@@ -394,7 +397,7 @@ def get_email_params(course, auto_enroll, secure=True, course_key=None, display_
"""
protocol = 'https' if secure else 'http'
- course_key = course_key or text_type(course.id)
+ course_key = course_key or str(course.id)
display_name = display_name or Text(course.display_name_with_default)
stripped_site_name = configuration_helpers.get_value(
@@ -403,12 +406,12 @@ def get_email_params(course, auto_enroll, secure=True, course_key=None, display_
)
# TODO: Use request.build_absolute_uri rather than '{proto}://{site}{path}'.format
# and check with the Services team that this works well with microsites
- registration_url = u'{proto}://{site}{path}'.format(
+ registration_url = '{proto}://{site}{path}'.format(
proto=protocol,
site=stripped_site_name,
path=reverse('register_user')
)
- course_url = u'{proto}://{site}{path}'.format(
+ course_url = '{proto}://{site}{path}'.format(
proto=protocol,
site=stripped_site_name,
path=reverse('course_root', kwargs={'course_id': course_key})
@@ -417,7 +420,7 @@ def get_email_params(course, auto_enroll, secure=True, course_key=None, display_
# We can't get the url to the course's About page if the marketing site is enabled.
course_about_url = None
if not settings.FEATURES.get('ENABLE_MKTG_SITE', False):
- course_about_url = u'{proto}://{site}{path}'.format(
+ course_about_url = '{proto}://{site}{path}'.format(
proto=protocol,
site=stripped_site_name,
path=reverse('about_course', kwargs={'course_id': course_key})
diff --git a/lms/djangoapps/instructor/message_types.py b/lms/djangoapps/instructor/message_types.py
index 6b14a4fe5d..6354cfb54f 100644
--- a/lms/djangoapps/instructor/message_types.py
+++ b/lms/djangoapps/instructor/message_types.py
@@ -15,7 +15,7 @@ class AccountCreationAndEnrollment(BaseMessageType):
APP_LABEL = 'instructor'
def __init__(self, *args, **kwargs):
- super(AccountCreationAndEnrollment, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__(*args, **kwargs)
self.options['transactional'] = True
@@ -26,7 +26,7 @@ class AddBetaTester(BaseMessageType):
APP_LABEL = 'instructor'
def __init__(self, *args, **kwargs):
- super(AddBetaTester, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__(*args, **kwargs)
self.options['transactional'] = True
@@ -37,7 +37,7 @@ class AllowedEnroll(BaseMessageType):
APP_LABEL = 'instructor'
def __init__(self, *args, **kwargs):
- super(AllowedEnroll, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__(*args, **kwargs)
self.options['transactional'] = True
@@ -48,7 +48,7 @@ class AllowedUnenroll(BaseMessageType):
APP_LABEL = 'instructor'
def __init__(self, *args, **kwargs):
- super(AllowedUnenroll, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__(*args, **kwargs)
self.options['transactional'] = True
@@ -59,7 +59,7 @@ class EnrollEnrolled(BaseMessageType):
APP_LABEL = 'instructor'
def __init__(self, *args, **kwargs):
- super(EnrollEnrolled, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__(*args, **kwargs)
self.options['transactional'] = True
@@ -70,7 +70,7 @@ class EnrolledUnenroll(BaseMessageType):
APP_LABEL = 'instructor'
def __init__(self, *args, **kwargs):
- super(EnrolledUnenroll, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__(*args, **kwargs)
self.options['transactional'] = True
@@ -81,5 +81,5 @@ class RemoveBetaTester(BaseMessageType):
APP_LABEL = 'instructor'
def __init__(self, *args, **kwargs):
- super(RemoveBetaTester, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__(*args, **kwargs)
self.options['transactional'] = True
diff --git a/lms/djangoapps/instructor/permissions.py b/lms/djangoapps/instructor/permissions.py
index e766dedc0b..20426761e6 100644
--- a/lms/djangoapps/instructor/permissions.py
+++ b/lms/djangoapps/instructor/permissions.py
@@ -4,8 +4,8 @@ Permissions for the instructor dashboard and associated actions
from bridgekeeper import perms
from bridgekeeper.rules import is_staff
-from lms.djangoapps.courseware.rules import HasAccessRule, HasRolesRule
+from lms.djangoapps.courseware.rules import HasAccessRule, HasRolesRule
ALLOW_STUDENT_TO_BYPASS_ENTRANCE_EXAM = 'instructor.allow_student_to_bypass_entrance_exam'
ASSIGN_TO_COHORTS = 'instructor.assign_to_cohorts'
diff --git a/lms/djangoapps/instructor/services.py b/lms/djangoapps/instructor/services.py
index 6d38ac6cf8..39c26605ee 100644
--- a/lms/djangoapps/instructor/services.py
+++ b/lms/djangoapps/instructor/services.py
@@ -12,17 +12,17 @@ from opaque_keys.edx.keys import CourseKey, UsageKey
from opaque_keys.edx.locator import CourseLocator
import lms.djangoapps.instructor.enrollment as enrollment
-from lms.djangoapps.courseware.models import StudentModule
-from lms.djangoapps.commerce.utils import create_zendesk_ticket
-from lms.djangoapps.instructor.views.tools import get_student_from_identifier
from common.djangoapps.student import auth
from common.djangoapps.student.roles import CourseStaffRole
+from lms.djangoapps.commerce.utils import create_zendesk_ticket
+from lms.djangoapps.courseware.models import StudentModule
+from lms.djangoapps.instructor.views.tools import get_student_from_identifier
from xmodule.modulestore.django import modulestore
log = logging.getLogger(__name__)
-class InstructorService(object):
+class InstructorService:
"""
Instructor service for deleting the students attempt(s) of an exam. This service has been created
for the edx_proctoring's dependency injection to cater for a requirement where edx_proctoring
@@ -49,7 +49,7 @@ class InstructorService(object):
except ObjectDoesNotExist:
err_msg = (
'Error occurred while attempting to reset student attempts for user '
- u'{student_identifier} for content_id {content_id}. '
+ '{student_identifier} for content_id {content_id}. '
'User does not exist!'.format(
student_identifier=student_identifier,
content_id=content_id
@@ -62,7 +62,7 @@ class InstructorService(object):
module_state_key = UsageKey.from_string(content_id)
except InvalidKeyError:
err_msg = (
- u'Invalid content_id {content_id}!'.format(content_id=content_id)
+ f'Invalid content_id {content_id}!'
)
log.error(err_msg)
return
@@ -79,7 +79,7 @@ class InstructorService(object):
except (StudentModule.DoesNotExist, enrollment.sub_api.SubmissionError):
err_msg = (
'Error occurred while attempting to reset student attempts for user '
- u'{student_identifier} for content_id {content_id}.'.format(
+ '{student_identifier} for content_id {content_id}.'.format(
student_identifier=student_identifier,
content_id=content_id
)
@@ -108,17 +108,17 @@ class InstructorService(object):
if course.create_zendesk_tickets:
requester_name = "edx-proctoring"
email = "edx-proctoring@edx.org"
- subject = _(u"Proctored Exam Review: {review_status}").format(review_status=review_status)
+ subject = _("Proctored Exam Review: {review_status}").format(review_status=review_status)
body = _(
- u"A proctored exam attempt for {exam_name} in {course_name} by username: {student_username} "
- u"was reviewed as {review_status} by the proctored exam review provider.\n"
- u"Review link: {review_url}"
+ "A proctored exam attempt for {exam_name} in {course_name} by username: {student_username} "
+ "was reviewed as {review_status} by the proctored exam review provider.\n"
+ "Review link: {review_url}"
).format(
exam_name=exam_name,
course_name=course.display_name,
student_username=student_username,
review_status=review_status,
- review_url=review_url or u'not available',
+ review_url=review_url or 'not available',
)
tags = ["proctoring"]
create_zendesk_ticket(requester_name, email, subject, body, tags)
diff --git a/lms/djangoapps/instructor/tests/test_access.py b/lms/djangoapps/instructor/tests/test_access.py
index 7f83d4dcf8..961a4d7203 100644
--- a/lms/djangoapps/instructor/tests/test_access.py
+++ b/lms/djangoapps/instructor/tests/test_access.py
@@ -4,13 +4,12 @@ Test instructor.access
import pytest
-from six.moves import range
+from common.djangoapps.student.roles import CourseBetaTesterRole, CourseCcxCoachRole, CourseStaffRole
+from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.instructor.access import allow_access, list_with_level, revoke_access, update_forum_role
from openedx.core.djangoapps.ace_common.tests.mixins import EmailTemplateTagMixin
from openedx.core.djangoapps.django_comment_common.models import FORUM_ROLE_MODERATOR, Role
-from common.djangoapps.student.roles import CourseBetaTesterRole, CourseCcxCoachRole, CourseStaffRole
-from common.djangoapps.student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -19,11 +18,11 @@ class TestInstructorAccessList(SharedModuleStoreTestCase):
""" Test access listings. """
@classmethod
def setUpClass(cls):
- super(TestInstructorAccessList, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestInstructorAccessList, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.instructors = [UserFactory.create() for _ in range(4)]
for user in self.instructors:
allow_access(self.course, user, 'instructor')
@@ -44,11 +43,11 @@ class TestInstructorAccessAllow(EmailTemplateTagMixin, SharedModuleStoreTestCase
""" Test access allow. """
@classmethod
def setUpClass(cls):
- super(TestInstructorAccessAllow, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestInstructorAccessAllow, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.course = CourseFactory.create()
@@ -89,11 +88,11 @@ class TestInstructorAccessRevoke(SharedModuleStoreTestCase):
""" Test access revoke. """
@classmethod
def setUpClass(cls):
- super(TestInstructorAccessRevoke, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestInstructorAccessRevoke, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.staff = [UserFactory.create() for _ in range(4)]
for user in self.staff:
allow_access(self.course, user, 'staff')
@@ -128,11 +127,11 @@ class TestInstructorAccessForum(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(TestInstructorAccessForum, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestInstructorAccessForum, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.mod_role = Role.objects.create(
course_id=self.course.id,
name=FORUM_ROLE_MODERATOR
diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py
index aac2719b33..5a74c5f81c 100644
--- a/lms/djangoapps/instructor/tests/test_api.py
+++ b/lms/djangoapps/instructor/tests/test_api.py
@@ -1,9 +1,6 @@
-# -*- coding: utf-8 -*-
"""
Unit tests for instructor.api methods.
"""
-
-
import datetime
import functools
import io
@@ -11,6 +8,7 @@ import json
import random
import shutil
import tempfile
+from unittest.mock import Mock, NonCallableMock, patch
import ddt
import pytest
@@ -24,20 +22,44 @@ from django.http import HttpRequest, HttpResponse
from django.test import RequestFactory, TestCase
from django.urls import reverse as django_reverse
from django.utils.translation import ugettext as _
+from edx_toggles.toggles.testutils import \
+ override_waffle_flag # lint-amnesty, pylint: disable=unused-import, wrong-import-order
from edx_when.api import get_dates_for_course, get_overrides_for_user, set_date_for_block
from freezegun import freeze_time
-from mock import Mock, NonCallableMock, patch
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locator import UsageKey
from pytz import UTC
-from six import text_type, unichr
-from six.moves import range, zip
from testfixtures import LogCapture
-from lms.djangoapps.bulk_email.models import BulkEmailFlag, CourseEmail, CourseEmailTemplate
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
-from edx_toggles.toggles.testutils import override_waffle_flag # lint-amnesty, pylint: disable=unused-import, wrong-import-order
+from common.djangoapps.student.models import (
+ ALLOWEDTOENROLL_TO_ENROLLED,
+ ALLOWEDTOENROLL_TO_UNENROLLED,
+ ENROLLED_TO_ENROLLED,
+ ENROLLED_TO_UNENROLLED,
+ UNENROLLED_TO_ALLOWEDTOENROLL,
+ UNENROLLED_TO_ENROLLED,
+ UNENROLLED_TO_UNENROLLED,
+ CourseEnrollment,
+ CourseEnrollmentAllowed,
+ ManualEnrollmentAudit,
+ NonExistentCourseError,
+ get_retired_email_by_email,
+ get_retired_username_by_username
+)
+from common.djangoapps.student.roles import ( # lint-amnesty, pylint: disable=unused-import
+ CourseBetaTesterRole,
+ CourseDataResearcherRole,
+ CourseFinanceAdminRole,
+ CourseInstructorRole,
+ CourseSalesAdminRole
+)
+from common.djangoapps.student.tests.factories import ( # lint-amnesty, pylint: disable=unused-import
+ AdminFactory,
+ UserFactory
+)
+from lms.djangoapps.bulk_email.models import BulkEmailFlag, CourseEmail, CourseEmailTemplate
from lms.djangoapps.certificates.api import generate_user_certificates
from lms.djangoapps.certificates.models import CertificateStatuses
from lms.djangoapps.certificates.tests.factories import GeneratedCertificateFactory
@@ -73,29 +95,6 @@ from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
from openedx.core.lib.teams_config import TeamsConfig
from openedx.core.lib.xblock_utils import grade_histogram
from openedx.features.course_experience import RELATIVE_DATES_FLAG
-from common.djangoapps.student.models import (
- ALLOWEDTOENROLL_TO_ENROLLED,
- ALLOWEDTOENROLL_TO_UNENROLLED,
- ENROLLED_TO_ENROLLED,
- ENROLLED_TO_UNENROLLED,
- UNENROLLED_TO_ALLOWEDTOENROLL,
- UNENROLLED_TO_ENROLLED,
- UNENROLLED_TO_UNENROLLED,
- CourseEnrollment,
- CourseEnrollmentAllowed,
- ManualEnrollmentAudit,
- NonExistentCourseError,
- get_retired_email_by_email,
- get_retired_username_by_username
-)
-from common.djangoapps.student.roles import ( # lint-amnesty, pylint: disable=unused-import
- CourseBetaTesterRole,
- CourseDataResearcherRole,
- CourseFinanceAdminRole,
- CourseInstructorRole,
- CourseSalesAdminRole
-)
-from common.djangoapps.student.tests.factories import AdminFactory, UserFactory # lint-amnesty, pylint: disable=unused-import
from xmodule.fields import Date
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
@@ -144,11 +143,11 @@ REPORTS_DATA = (
)
-INSTRUCTOR_GET_ENDPOINTS = set([
+INSTRUCTOR_GET_ENDPOINTS = {
'get_anon_ids',
'get_issued_certificates',
-])
-INSTRUCTOR_POST_ENDPOINTS = set([
+}
+INSTRUCTOR_POST_ENDPOINTS = {
'add_users_to_cohorts',
'bulk_beta_modify_access',
'calculate_grades_csv',
@@ -183,7 +182,7 @@ INSTRUCTOR_POST_ENDPOINTS = set([
'students_update_enrollment',
'update_forum_role_membership',
'override_problem_score',
-])
+}
def reverse(endpoint, args=None, kwargs=None, is_dashboard_endpoint=True):
@@ -207,7 +206,7 @@ def reverse(endpoint, args=None, kwargs=None, is_dashboard_endpoint=True):
if is_dashboard_endpoint and is_endpoint_declared is False:
# Verify that all endpoints are declared so we can ensure they are
# properly validated elsewhere.
- raise ValueError(u"The endpoint {} must be declared in ENDPOINTS before use.".format(endpoint))
+ raise ValueError(f"The endpoint {endpoint} must be declared in ENDPOINTS before use.")
return django_reverse(endpoint, args=args, kwargs=kwargs)
@@ -234,7 +233,7 @@ def view_alreadyrunningerror_unicode(request):
"""
A dummy view that raises an AlreadyRunningError exception with unicode message
"""
- raise AlreadyRunningError(u'Text with unicode chárácters')
+ raise AlreadyRunningError('Text with unicode chárácters')
@common_exceptions_400
@@ -252,7 +251,7 @@ class TestCommonExceptions400(TestCase):
"""
def setUp(self):
- super(TestCommonExceptions400, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.request = Mock(spec=HttpRequest)
self.request.META = {}
@@ -282,7 +281,7 @@ class TestCommonExceptions400(TestCase):
resp = view_alreadyrunningerror_unicode(self.request)
self.assertContains(
resp,
- u'Text with unicode chárácters',
+ 'Text with unicode chárácters',
status_code=400,
)
@@ -312,14 +311,14 @@ class TestEndpointHttpMethods(SharedModuleStoreTestCase, LoginEnrollmentTestCase
"""
Set up test course.
"""
- super(TestEndpointHttpMethods, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
"""
Set up global staff role so authorization will not fail.
"""
- super(TestEndpointHttpMethods, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
global_user = GlobalStaffFactory()
self.client.login(username=global_user.username, password='test')
@@ -328,7 +327,7 @@ class TestEndpointHttpMethods(SharedModuleStoreTestCase, LoginEnrollmentTestCase
"""
Tests that POST endpoints are rejected with 405 when using GET.
"""
- url = reverse(data, kwargs={'course_id': text_type(self.course.id)})
+ url = reverse(data, kwargs={'course_id': str(self.course.id)})
response = self.client.get(url)
assert response.status_code == 405, \
@@ -339,7 +338,7 @@ class TestEndpointHttpMethods(SharedModuleStoreTestCase, LoginEnrollmentTestCase
"""
Tests that GET endpoints are not rejected with 405 when using GET.
"""
- url = reverse(data, kwargs={'course_id': text_type(self.course.id)})
+ url = reverse(data, kwargs={'course_id': str(self.course.id)})
response = self.client.get(url)
assert response.status_code != 405, \
@@ -354,7 +353,7 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
@classmethod
def setUpClass(cls):
- super(TestInstructorAPIDenyLevels, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
cls.chapter = ItemFactory.create(
parent=cls.course,
@@ -386,16 +385,16 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
publish_item=True,
)
- cls.problem_urlname = text_type(cls.problem.location)
+ cls.problem_urlname = str(cls.problem.location)
BulkEmailFlag.objects.create(enabled=True, require_course_email_auth=False)
@classmethod
def tearDownClass(cls):
- super(TestInstructorAPIDenyLevels, cls).tearDownClass()
+ super().tearDownClass()
BulkEmailFlag.objects.all().delete()
def setUp(self):
- super(TestInstructorAPIDenyLevels, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.user = UserFactory.create()
CourseEnrollment.enroll(self.user, self.course.id)
@@ -460,7 +459,7 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
status_code: expected HTTP status code response
msg: message to display if assertion fails.
"""
- url = reverse(endpoint, kwargs={'course_id': text_type(self.course.id)})
+ url = reverse(endpoint, kwargs={'course_id': str(self.course.id)})
if endpoint in INSTRUCTOR_GET_ENDPOINTS:
response = self.client.get(url, args)
else:
@@ -497,7 +496,7 @@ class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTest
msg: message to display if assertion fails.
"""
- mock_problem_key = NonCallableMock(return_value=u'')
+ mock_problem_key = NonCallableMock(return_value='')
mock_problem_key.course_key = self.course.id
with patch.object(UsageKey, 'from_string') as patched_method:
patched_method.return_value = mock_problem_key
@@ -587,7 +586,7 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
"""
@classmethod
def setUpClass(cls):
- super(TestInstructorAPIBulkAccountCreationAndEnrollment, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
# Create a course with mode 'audit'
@@ -595,14 +594,14 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
CourseModeFactory.create(course_id=cls.audit_course.id, mode_slug=CourseMode.AUDIT)
cls.url = reverse(
- 'register_and_enroll_students', kwargs={'course_id': text_type(cls.course.id)}
+ 'register_and_enroll_students', kwargs={'course_id': str(cls.course.id)}
)
cls.audit_course_url = reverse(
- 'register_and_enroll_students', kwargs={'course_id': text_type(cls.audit_course.id)}
+ 'register_and_enroll_students', kwargs={'course_id': str(cls.audit_course.id)}
)
def setUp(self):
- super(TestInstructorAPIBulkAccountCreationAndEnrollment, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
# Create a course with mode 'honor' and with price
self.white_label_course = CourseFactory.create()
@@ -614,7 +613,7 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
)
self.white_label_course_url = reverse(
- 'register_and_enroll_students', kwargs={'course_id': text_type(self.white_label_course.id)}
+ 'register_and_enroll_students', kwargs={'course_id': str(self.white_label_course.id)}
)
self.request = RequestFactory().request()
@@ -650,7 +649,7 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
assert manual_enrollments[0].state_transition == UNENROLLED_TO_ENROLLED
# test the log for email that's send to new created user.
- info_log.assert_called_with(u'email sent to new created user at %s', 'test_student@example.com')
+ info_log.assert_called_with('email sent to new created user at %s', 'test_student@example.com')
@patch('lms.djangoapps.instructor.views.api.log.info')
def test_account_creation_and_enrollment_with_csv_with_blank_lines(self, info_log):
@@ -671,7 +670,7 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
assert manual_enrollments[0].state_transition == UNENROLLED_TO_ENROLLED
# test the log for email that's send to new created user.
- info_log.assert_called_with(u'email sent to new created user at %s', 'test_student@example.com')
+ info_log.assert_called_with('email sent to new created user at %s', 'test_student@example.com')
@patch('lms.djangoapps.instructor.views.api.log.info')
def test_email_and_username_already_exist(self, info_log):
@@ -695,7 +694,7 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
# test the log for email that's send to new created user.
info_log.assert_called_with(
- u"user already exists with username '%s' and email '%s'",
+ "user already exists with username '%s' and email '%s'",
'test_student_1',
'test_student@example.com'
)
@@ -760,7 +759,7 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
assert len(data['row_errors']) != 0
assert len(data['warnings']) == 0
assert len(data['general_errors']) == 0
- assert data['row_errors'][0]['response'] == u'Invalid email {0}.'.format('test_student.example.com')
+ assert data['row_errors'][0]['response'] == 'Invalid email {0}.'.format('test_student.example.com')
manual_enrollments = ManualEnrollmentAudit.objects.all()
assert manual_enrollments.count() == 0
@@ -776,8 +775,8 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
response = self.client.post(self.url, {'students_list': uploaded_file})
assert response.status_code == 200
info_log.assert_called_with(
- u'user %s enrolled in the course %s',
- u'NotEnrolledStudent',
+ 'user %s enrolled in the course %s',
+ 'NotEnrolledStudent',
self.course.id
)
manual_enrollments = ManualEnrollmentAudit.objects.all()
@@ -796,8 +795,8 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
response = self.client.post(self.url, {'students_list': uploaded_file})
assert response.status_code == 200
data = json.loads(response.content.decode('utf-8'))
- warning_message = u'An account with email {email} exists but the provided username {username} ' \
- u'is different. Enrolling anyway with {email}.'.format(email='test_student@example.com', username='test_student_2') # lint-amnesty, pylint: disable=line-too-long
+ warning_message = 'An account with email {email} exists but the provided username {username} ' \
+ 'is different. Enrolling anyway with {email}.'.format(email='test_student@example.com', username='test_student_2') # lint-amnesty, pylint: disable=line-too-long
assert len(data['warnings']) != 0
assert data['warnings'][0]['response'] == warning_message
user = User.objects.get(email='test_student@example.com')
@@ -830,7 +829,7 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
assert response.status_code == 200
data = json.loads(response.content.decode('utf-8'))
assert len(data['row_errors']) != 0
- assert data['row_errors'][0]['response'] == u'Invalid email {email}.'.format(email=conflicting_email)
+ assert data['row_errors'][0]['response'] == f'Invalid email {conflicting_email}.'
assert not User.objects.filter(email=conflicting_email).exists()
def test_user_with_already_existing_username_in_csv(self):
@@ -847,7 +846,7 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
assert response.status_code == 200
data = json.loads(response.content.decode('utf-8'))
assert len(data['row_errors']) != 0
- assert data['row_errors'][0]['response'] == u'Username {user} already exists.'.format(user='test_student_1')
+ assert data['row_errors'][0]['response'] == 'Username {user} already exists.'.format(user='test_student_1')
# lint-amnesty, pylint: disable=line-too-long
def test_csv_file_not_attached(self):
@@ -916,8 +915,8 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCas
assert response.status_code == 200
data = json.loads(response.content.decode('utf-8'))
assert len(data['row_errors']) != 0
- assert data['row_errors'][0]['response'] == u'Username {user} already exists.'.format(user='test_student_1')
- assert data['row_errors'][1]['response'] == u'Invalid email {email}.'.format(email='test_student4@example.com')
+ assert data['row_errors'][0]['response'] == 'Username {user} already exists.'.format(user='test_student_1')
+ assert data['row_errors'][1]['response'] == 'Invalid email {email}.'.format(email='test_student4@example.com')
assert User.objects.filter(username='test_student_1', email='test_student1@example.com').exists()
assert User.objects.filter(username='test_student_2', email='test_student2@example.com').exists()
assert not User.objects.filter(email='test_student3@example.com').exists()
@@ -1015,7 +1014,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
@classmethod
def setUpClass(cls):
- super(TestInstructorAPIEnrollment, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
# Email URL values
@@ -1023,11 +1022,11 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
'SITE_NAME',
settings.SITE_NAME
)
- cls.about_path = '/courses/{}/about'.format(cls.course.id)
- cls.course_path = '/courses/{}/'.format(cls.course.id)
+ cls.about_path = f'/courses/{cls.course.id}/about'
+ cls.course_path = f'/courses/{cls.course.id}/'
def setUp(self):
- super(TestInstructorAPIEnrollment, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.request = RequestFactory().request()
self.instructor = InstructorFactory(course_key=self.course.id)
@@ -1056,19 +1055,19 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
def test_missing_params(self):
""" Test missing all query parameters. """
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url)
assert response.status_code == 400
def test_bad_action(self):
""" Test with an invalid action. """
action = 'robot-not-an-action'
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.enrolled_student.email, 'action': action})
assert response.status_code == 400
def test_invalid_email(self):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': 'percivaloctavius@', 'action': 'enroll', 'email_students': False}) # lint-amnesty, pylint: disable=line-too-long
assert response.status_code == 200
@@ -1088,7 +1087,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert res_json == expected
def test_invalid_username(self):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url,
{'identifiers': 'percivaloctavius', 'action': 'enroll', 'email_students': False})
assert response.status_code == 200
@@ -1109,7 +1108,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert res_json == expected
def test_enroll_with_username(self):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.notenrolled_student.username, 'action': 'enroll',
'email_students': False})
assert response.status_code == 200
@@ -1143,10 +1142,10 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert res_json == expected
def test_enroll_without_email(self):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.notenrolled_student.email, 'action': 'enroll',
'email_students': False})
- print(u"type(self.notenrolled_student.email): {}".format(type(self.notenrolled_student.email)))
+ print("type(self.notenrolled_student.email): {}".format(type(self.notenrolled_student.email)))
assert response.status_code == 200
# test that the user is now enrolled
@@ -1187,12 +1186,12 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
@ddt.data('http', 'https')
def test_enroll_with_email(self, protocol):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
params = {'identifiers': self.notenrolled_student.email, 'action': 'enroll', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.post(url, params, **environ)
- print(u"type(self.notenrolled_student.email): {}".format(type(self.notenrolled_student.email)))
+ print("type(self.notenrolled_student.email): {}".format(type(self.notenrolled_student.email)))
assert response.status_code == 200
# test that the user is now enrolled
@@ -1227,7 +1226,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
# Check the outbox
assert len(mail.outbox) == 1
- assert mail.outbox[0].subject == u'You have been enrolled in {}'.format(self.course.display_name)
+ assert mail.outbox[0].subject == f'You have been enrolled in {self.course.display_name}'
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
@@ -1246,7 +1245,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
@ddt.data('http', 'https')
def test_enroll_with_email_not_registered(self, protocol):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.post(url, params, **environ)
@@ -1257,21 +1256,21 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
# Check the outbox
assert len(mail.outbox) == 1
- assert mail.outbox[0].subject == u'You have been invited to register for {}'.format(self.course.display_name)
+ assert mail.outbox[0].subject == f'You have been invited to register for {self.course.display_name}'
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
- register_url = '{proto}://{site}/register'.format(proto=protocol, site=self.site_name)
+ register_url = f'{protocol}://{self.site_name}/register'
assert text_body.startswith('Dear student,')
- assert u'To finish your registration, please visit {register_url}'.format(
+ assert 'To finish your registration, please visit {register_url}'.format(
register_url=register_url,
) in text_body
assert 'Please finish your registration and fill out' in html_body
assert register_url in html_body
for body in [text_body, html_body]:
- assert u'You have been invited to join {course} at edx.org by a member of the course staff.'.format(
+ assert 'You have been invited to join {course} at edx.org by a member of the course staff.'.format(
course=self.course.display_name
) in body
@@ -1291,7 +1290,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
@ddt.data('http', 'https')
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
def test_enroll_email_not_registered_mktgsite(self, protocol):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.post(url, params, **environ)
@@ -1309,7 +1308,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert 'Please finish your registration and fill' in html_body
for body in [text_body, html_body]:
- assert u'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
+ assert 'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
display_name=self.course.display_name
) in body
@@ -1321,7 +1320,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert ('fill out the registration form making sure to use '
'robot-not-an-email-yet@robot.org in the Email field') in body
- assert u'You can then enroll in {display_name}.'.format(
+ assert 'You can then enroll in {display_name}.'.format(
display_name=self.course.display_name
) in body
@@ -1329,17 +1328,17 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
@ddt.data('http', 'https')
def test_enroll_with_email_not_registered_autoenroll(self, protocol):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True,
'auto_enroll': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.post(url, params, **environ)
- print(u"type(self.notregistered_email): {}".format(type(self.notregistered_email)))
+ print("type(self.notregistered_email): {}".format(type(self.notregistered_email)))
assert response.status_code == 200
# Check the outbox
assert len(mail.outbox) == 1
- assert mail.outbox[0].subject == u'You have been invited to register for {}'.format(self.course.display_name)
+ assert mail.outbox[0].subject == f'You have been invited to register for {self.course.display_name}'
manual_enrollments = ManualEnrollmentAudit.objects.all()
assert manual_enrollments.count() == 1
assert manual_enrollments[0].state_transition == UNENROLLED_TO_ALLOWEDTOENROLL
@@ -1352,7 +1351,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
)
assert text_body.startswith('Dear student,')
- assert u'To finish your registration, please visit {register_url}'.format(
+ assert 'To finish your registration, please visit {register_url}'.format(
register_url=register_url,
) in text_body
assert 'Please finish your registration and fill out the registration' in html_body
@@ -1360,7 +1359,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert register_url in html_body
for body in [text_body, html_body]:
- assert u'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
+ assert 'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
display_name=self.course.display_name
) in body
@@ -1368,18 +1367,18 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
'out the registration form making sure to use robot-not-an-email-yet@robot.org '
'in the Email field') in body
- assert (u'Once you have registered and activated your account, '
- u'you will see {display_name} listed on your dashboard.').format(
+ assert ('Once you have registered and activated your account, '
+ 'you will see {display_name} listed on your dashboard.').format(
display_name=self.course.display_name
) in body
assert 'This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org' in body
def test_unenroll_without_email(self):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.enrolled_student.email, 'action': 'unenroll',
'email_students': False})
- print(u"type(self.enrolled_student.email): {}".format(type(self.enrolled_student.email)))
+ print("type(self.enrolled_student.email): {}".format(type(self.enrolled_student.email)))
assert response.status_code == 200
# test that the user is now unenrolled
@@ -1419,10 +1418,10 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert len(mail.outbox) == 0
def test_unenroll_with_email(self):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.enrolled_student.email, 'action': 'unenroll',
'email_students': True})
- print(u"type(self.enrolled_student.email): {}".format(type(self.enrolled_student.email)))
+ print("type(self.enrolled_student.email): {}".format(type(self.enrolled_student.email)))
assert response.status_code == 200
# test that the user is now unenrolled
@@ -1460,8 +1459,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
# Check the outbox
assert len(mail.outbox) == 1
- assert mail.outbox[0].subject ==\
- u'You have been unenrolled from {display_name}'.format(display_name=self.course.display_name)
+ assert mail.outbox[0].subject == f'You have been unenrolled from {self.course.display_name}'
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
@@ -1469,7 +1467,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert text_body.startswith('Dear Enrolled Student')
for body in [text_body, html_body]:
- assert u'You have been unenrolled from {display_name} at edx.org by a member of the course staff.'.format(
+ assert 'You have been unenrolled from {display_name} at edx.org by a member of the course staff.'.format(
display_name=self.course.display_name,
) in body
@@ -1478,7 +1476,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert 'This email was automatically sent from edx.org to Enrolled Student' in body
def test_unenroll_with_email_allowed_student(self):
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url,
{'identifiers': self.allowed_email, 'action': 'unenroll', 'email_students': True})
print(u"type(self.allowed_email): {}".format(type(self.allowed_email)))
@@ -1515,15 +1513,14 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
# Check the outbox
assert len(mail.outbox) == 1
- assert mail.outbox[0].subject ==\
- u'You have been unenrolled from {display_name}'.format(display_name=self.course.display_name)
+ assert mail.outbox[0].subject == f'You have been unenrolled from {self.course.display_name}'
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
assert text_body.startswith('Dear Student,')
for body in [text_body, html_body]:
- assert u'You have been unenrolled from the course {display_name} by a member of the course staff.'.format(
+ assert 'You have been unenrolled from the course {display_name} by a member of the course staff.'.format(
display_name=self.course.display_name,
) in body
@@ -1535,7 +1532,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
def test_enroll_with_email_not_registered_with_shib(self, protocol, mock_uses_shib):
mock_uses_shib.return_value = True
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.post(url, params, **environ)
@@ -1543,8 +1540,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
# Check the outbox
assert len(mail.outbox) == 1
- assert mail.outbox[0].subject == u'You have been invited to register for {display_name}'\
- .format(display_name=self.course.display_name)
+ assert mail.outbox[0].subject == f'You have been invited to register for {self.course.display_name}'
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
@@ -1554,14 +1550,14 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
about_path=self.about_path,
)
assert text_body.startswith('Dear student,')
- assert u'To access this course visit {course_url} and register for this course.'.format(
+ assert 'To access this course visit {course_url} and register for this course.'.format(
course_url=course_url,
) in text_body
assert 'To access this course visit it and register:' in html_body
assert course_url in html_body
for body in [text_body, html_body]:
- assert u'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
+ assert 'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
display_name=self.course.display_name,
) in body
@@ -1573,7 +1569,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
# Try with marketing site enabled and shib on
mock_uses_shib.return_value = True
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
# Try with marketing site enabled
with patch.dict('django.conf.settings.FEATURES', {'ENABLE_MKTG_SITE': True}):
response = self.client.post(url, {'identifiers': self.notregistered_email, 'action': 'enroll',
@@ -1586,7 +1582,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert text_body.startswith('Dear student,')
for body in [text_body, html_body]:
- assert u'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
+ assert 'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
display_name=self.course.display_name,
) in body
@@ -1597,18 +1593,17 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
def test_enroll_with_email_not_registered_with_shib_autoenroll(self, protocol, mock_uses_shib):
mock_uses_shib.return_value = True
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': True,
'auto_enroll': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.post(url, params, **environ)
- print(u"type(self.notregistered_email): {}".format(type(self.notregistered_email)))
+ print("type(self.notregistered_email): {}".format(type(self.notregistered_email)))
assert response.status_code == 200
# Check the outbox
assert len(mail.outbox) == 1
- assert mail.outbox[0].subject ==\
- u'You have been invited to register for {display_name}'.format(display_name=self.course.display_name)
+ assert mail.outbox[0].subject == f'You have been invited to register for {self.course.display_name}'
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
@@ -1618,11 +1613,11 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
assert text_body.startswith('Dear student,')
assert course_url in html_body
- assert u'To access this course visit {course_url} and login.'.format(course_url=course_url) in text_body
+ assert f'To access this course visit {course_url} and login.' in text_body
assert 'To access this course click on the button below and login:' in html_body
for body in [text_body, html_body]:
- assert u'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
+ assert 'You have been invited to join {display_name} at edx.org by a member of the course staff.'.format(
display_name=self.course.display_name,
) in body
@@ -1637,9 +1632,9 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
user=self.enrolled_student, course_id=self.course.id
)
# make this enrollment "verified"
- course_enrollment.mode = u'verified'
+ course_enrollment.mode = 'verified'
course_enrollment.save()
- assert course_enrollment.mode == u'verified'
+ assert course_enrollment.mode == 'verified'
# now re-enroll the student through the instructor dash
self._change_student_enrollment(self.enrolled_student, self.course, 'enroll')
@@ -1651,7 +1646,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
manual_enrollments = ManualEnrollmentAudit.objects.all()
assert manual_enrollments.count() == 1
assert manual_enrollments[0].state_transition == ENROLLED_TO_ENROLLED
- assert course_enrollment.mode == u'verified'
+ assert course_enrollment.mode == 'verified'
def create_paid_course(self):
"""
@@ -1667,7 +1662,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
test to unenroll allow to enroll user.
"""
paid_course = self.create_paid_course()
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(paid_course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(paid_course.id)})
params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': False,
'auto_enroll': False, 'reason': 'testing..', 'role': 'Learner'}
response = self.client.post(url, params)
@@ -1678,7 +1673,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
# now registered the user
UserFactory(email=self.notregistered_email)
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(paid_course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(paid_course.id)})
params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': False,
'auto_enroll': False, 'reason': 'testing', 'role': 'Learner'}
response = self.client.post(url, params)
@@ -1722,7 +1717,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
)
assert course_enrollment.count() == 0
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(paid_course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(paid_course.id)})
params = {'identifiers': self.notregistered_email, 'action': 'unenroll', 'email_students': False,
'auto_enroll': False, 'reason': 'testing', 'role': 'Learner'}
@@ -1768,9 +1763,9 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
user=self.enrolled_student, course_id=self.course.id
)
# upgrade enrollment
- course_enrollment.mode = u'verified'
+ course_enrollment.mode = 'verified'
course_enrollment.save()
- assert course_enrollment.mode == u'verified'
+ assert course_enrollment.mode == 'verified'
self._change_student_enrollment(self.enrolled_student, self.course, 'unenroll')
@@ -1786,7 +1781,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
test that role and reason fields are persisted in the database
"""
paid_course = self.create_paid_course()
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(paid_course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(paid_course.id)})
params = {'identifiers': self.notregistered_email, 'action': 'enroll', 'email_students': False,
'auto_enroll': False, 'reason': 'testing', 'role': 'Learner'}
response = self.client.post(url, params)
@@ -1803,7 +1798,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
"""
url = reverse(
'students_update_enrollment',
- kwargs={'course_id': text_type(course.id)},
+ kwargs={'course_id': str(course.id)},
)
params = {
'identifiers': user.email,
@@ -1822,7 +1817,7 @@ class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTest
# enrolled, active
url = reverse(
'get_student_enrollment_status',
- kwargs={'course_id': text_type(self.course.id)},
+ kwargs={'course_id': str(self.course.id)},
)
params = {
'unique_student_identifier': 'EnrolledStudent'
@@ -1871,18 +1866,18 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
"""
@classmethod
def setUpClass(cls):
- super(TestInstructorAPIBulkBetaEnrollment, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
# Email URL values
cls.site_name = configuration_helpers.get_value(
'SITE_NAME',
settings.SITE_NAME
)
- cls.about_path = '/courses/{}/about'.format(cls.course.id)
- cls.course_path = '/courses/{}/'.format(cls.course.id)
+ cls.about_path = f'/courses/{cls.course.id}/about'
+ cls.course_path = f'/courses/{cls.course.id}/'
def setUp(self):
- super(TestInstructorAPIBulkBetaEnrollment, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
@@ -1912,8 +1907,8 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
in which he/she is a beta-tester.
"""
with LogCapture() as capture:
- message = u'Cancelling course certificate generation for user [{}] against course [{}], ' \
- u'user is a Beta Tester.'
+ message = 'Cancelling course certificate generation for user [{}] against course [{}], ' \
+ 'user is a Beta Tester.'
message = message.format(self.beta_tester.username, self.course.id)
generate_user_certificates(self.beta_tester, self.course.id, self.course)
@@ -1921,14 +1916,14 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
def test_missing_params(self):
""" Test missing all query parameters. """
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url)
assert response.status_code == 400
def test_bad_action(self):
""" Test with an invalid action. """
action = 'robot-not-an-action'
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.beta_tester.email, 'action': action})
assert response.status_code == 400
@@ -1965,32 +1960,32 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
assert len(mail.outbox) == 0
def test_add_notenrolled_email(self):
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.notenrolled_student.email, 'action': 'add', 'email_students': False}) # lint-amnesty, pylint: disable=line-too-long
self.add_notenrolled(response, self.notenrolled_student.email)
assert not CourseEnrollment.is_enrolled(self.notenrolled_student, self.course.id)
def test_add_notenrolled_email_autoenroll(self):
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.notenrolled_student.email, 'action': 'add', 'email_students': False, 'auto_enroll': True}) # lint-amnesty, pylint: disable=line-too-long
self.add_notenrolled(response, self.notenrolled_student.email)
assert CourseEnrollment.is_enrolled(self.notenrolled_student, self.course.id)
def test_add_notenrolled_username(self):
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.notenrolled_student.username, 'action': 'add', 'email_students': False}) # lint-amnesty, pylint: disable=line-too-long
self.add_notenrolled(response, self.notenrolled_student.username)
assert not CourseEnrollment.is_enrolled(self.notenrolled_student, self.course.id)
def test_add_notenrolled_username_autoenroll(self):
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.notenrolled_student.username, 'action': 'add', 'email_students': False, 'auto_enroll': True}) # lint-amnesty, pylint: disable=line-too-long
self.add_notenrolled(response, self.notenrolled_student.username)
assert CourseEnrollment.is_enrolled(self.notenrolled_student, self.course.id)
@ddt.data('http', 'https')
def test_add_notenrolled_with_email(self, protocol):
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
params = {'identifiers': self.notenrolled_student.email, 'action': 'add', 'email_students': True}
environ = {'wsgi.url_scheme': protocol}
response = self.client.post(url, params, **environ)
@@ -2014,17 +2009,16 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
# Check the outbox
assert len(mail.outbox) == 1
- assert mail.outbox[0].subject ==\
- u'You have been invited to a beta test for {display_name}'.format(display_name=self.course.display_name)
+ assert mail.outbox[0].subject == f'You have been invited to a beta test for {self.course.display_name}'
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
student_name = self.notenrolled_student.profile.name
- assert text_body.startswith(u'Dear {student_name}'.format(student_name=student_name))
- assert u'Visit {display_name}'.format(display_name=self.course.display_name) in html_body
+ assert text_body.startswith(f'Dear {student_name}')
+ assert f'Visit {self.course.display_name}' in html_body
for body in [text_body, html_body]:
- assert u'You have been invited to be a beta tester for {display_name} at edx.org'.format(
+ assert 'You have been invited to be a beta tester for {display_name} at edx.org'.format(
display_name=self.course.display_name,
) in body
@@ -2037,13 +2031,13 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
about_path=self.about_path,
) in body
- assert u'This email was automatically sent from edx.org to {student_email}'.format(
+ assert 'This email was automatically sent from edx.org to {student_email}'.format(
student_email=self.notenrolled_student.email,
) in body
@ddt.data('http', 'https')
def test_add_notenrolled_with_email_autoenroll(self, protocol):
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
params = {'identifiers': self.notenrolled_student.email, 'action': 'add', 'email_students': True,
'auto_enroll': True}
environ = {'wsgi.url_scheme': protocol}
@@ -2068,16 +2062,15 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
# Check the outbox
assert len(mail.outbox) == 1
- assert mail.outbox[0].subject ==\
- u'You have been invited to a beta test for {display_name}'.format(display_name=self.course.display_name)
+ assert mail.outbox[0].subject == f'You have been invited to a beta test for {self.course.display_name}'
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
student_name = self.notenrolled_student.profile.name
- assert text_body.startswith(u'Dear {student_name}'.format(student_name=student_name))
+ assert text_body.startswith(f'Dear {student_name}')
for body in [text_body, html_body]:
- assert u'You have been invited to be a beta tester for {display_name} at edx.org'.format(
+ assert 'You have been invited to be a beta tester for {display_name} at edx.org'.format(
display_name=self.course.display_name,
) in body
@@ -2090,14 +2083,14 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
course_path=self.course_path
)
- assert u'This email was automatically sent from edx.org to {student_email}'.format(
+ assert 'This email was automatically sent from edx.org to {student_email}'.format(
student_email=self.notenrolled_student.email,
) in body
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
def test_add_notenrolled_email_mktgsite(self):
# Try with marketing site enabled
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'identifiers': self.notenrolled_student.email, 'action': 'add', 'email_students': True}) # lint-amnesty, pylint: disable=line-too-long
assert response.status_code == 200
@@ -2105,23 +2098,23 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
student_name = self.notenrolled_student.profile.name
- assert text_body.startswith(u'Dear {student_name}'.format(student_name=student_name))
+ assert text_body.startswith(f'Dear {student_name}')
for body in [text_body, html_body]:
- assert u'You have been invited to be a beta tester for {display_name} at edx.org'.format(
+ assert 'You have been invited to be a beta tester for {display_name} at edx.org'.format(
display_name=self.course.display_name,
) in body
assert 'by a member of the course staff.' in body
assert 'Visit edx.org' in body
assert 'enroll in this course and begin the beta test' in body
- assert u'This email was automatically sent from edx.org to {student_email}'.format(
+ assert 'This email was automatically sent from edx.org to {student_email}'.format(
student_email=self.notenrolled_student.email,
) in body
def test_enroll_with_email_not_registered(self):
# User doesn't exist
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url,
{'identifiers': self.notregistered_email, 'action': 'add', 'email_students': True,
'reason': 'testing'})
@@ -2145,7 +2138,7 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
assert len(mail.outbox) == 0
def test_remove_without_email(self):
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url,
{'identifiers': self.beta_tester.email, 'action': 'remove', 'email_students': False,
'reason': 'testing'})
@@ -2176,7 +2169,7 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
assert len(mail.outbox) == 0
def test_remove_with_email(self):
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url,
{'identifiers': self.beta_tester.email, 'action': 'remove', 'email_students': True,
'reason': 'testing'})
@@ -2208,10 +2201,10 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
text_body = mail.outbox[0].body
html_body = mail.outbox[0].alternatives[0][0]
- assert text_body.startswith(u'Dear {name}'.format(name=self.beta_tester.profile.name))
+ assert text_body.startswith(f'Dear {self.beta_tester.profile.name}')
for body in [text_body, html_body]:
- assert u'You have been removed as a beta tester for {display_name} at edx.org'.format(
+ assert 'You have been removed as a beta tester for {display_name} at edx.org'.format(
display_name=self.course.display_name,
) in body
@@ -2220,7 +2213,7 @@ class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnroll
assert 'Your other courses have not been affected.' in body
- assert u'This email was automatically sent from edx.org to {email_address}'.format(
+ assert 'This email was automatically sent from edx.org to {email_address}'.format(
email_address=self.beta_tester.email,
) in body
@@ -2238,11 +2231,11 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
"""
@classmethod
def setUpClass(cls):
- super(TestInstructorAPILevelsAccess, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestInstructorAPILevelsAccess, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
@@ -2253,13 +2246,13 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
def test_modify_access_noparams(self):
""" Test missing all query parameters. """
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url)
assert response.status_code == 400
def test_modify_access_bad_action(self):
""" Test with an invalid action parameter. """
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.other_staff.email,
'rolename': 'staff',
@@ -2269,7 +2262,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
def test_modify_access_bad_role(self):
""" Test with an invalid action parameter. """
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.other_staff.email,
'rolename': 'robot-not-a-roll',
@@ -2278,7 +2271,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
assert response.status_code == 400
def test_modify_access_allow(self):
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.other_user.email,
'rolename': 'staff',
@@ -2287,7 +2280,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
assert response.status_code == 200
def test_modify_access_allow_with_uname(self):
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.other_instructor.username,
'rolename': 'staff',
@@ -2296,7 +2289,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
assert response.status_code == 200
def test_modify_access_revoke(self):
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.other_staff.email,
'rolename': 'staff',
@@ -2305,7 +2298,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
assert response.status_code == 200
def test_modify_access_revoke_with_username(self):
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.other_staff.username,
'rolename': 'staff',
@@ -2314,7 +2307,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
assert response.status_code == 200
def test_modify_access_with_fake_user(self):
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': 'GandalfTheGrey',
'rolename': 'staff',
@@ -2331,7 +2324,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
def test_modify_access_with_inactive_user(self):
self.other_user.is_active = False
self.other_user.save()
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.other_user.username,
'rolename': 'beta',
@@ -2347,7 +2340,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
def test_modify_access_revoke_not_allowed(self):
""" Test revoking access that a user does not have. """
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.other_staff.email,
'rolename': 'instructor',
@@ -2359,7 +2352,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
"""
Test that an instructor cannot remove instructor privelages from themself.
"""
- url = reverse('modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('modify_access', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.instructor.email,
'rolename': 'instructor',
@@ -2378,20 +2371,20 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
def test_list_course_role_members_noparams(self):
""" Test missing all query parameters. """
- url = reverse('list_course_role_members', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_course_role_members', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url)
assert response.status_code == 400
def test_list_course_role_members_bad_rolename(self):
""" Test with an invalid rolename parameter. """
- url = reverse('list_course_role_members', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_course_role_members', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'rolename': 'robot-not-a-rolename',
})
assert response.status_code == 400
def test_list_course_role_members_staff(self):
- url = reverse('list_course_role_members', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_course_role_members', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'rolename': 'staff',
})
@@ -2399,7 +2392,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
# check response content
expected = {
- 'course_id': text_type(self.course.id),
+ 'course_id': str(self.course.id),
'staff': [
{
'username': self.other_staff.username,
@@ -2413,7 +2406,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
assert res_json == expected
def test_list_course_role_members_beta(self):
- url = reverse('list_course_role_members', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_course_role_members', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'rolename': 'beta',
})
@@ -2421,7 +2414,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
# check response content
expected = {
- 'course_id': text_type(self.course.id),
+ 'course_id': str(self.course.id),
'beta': []
}
res_json = json.loads(response.content.decode('utf-8'))
@@ -2446,7 +2439,7 @@ class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTe
Test update forum role membership.
Get unique_student_identifier, rolename and action and update forum role.
"""
- url = reverse('update_forum_role_membership', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('update_forum_role_membership', kwargs={'course_id': str(self.course.id)})
response = self.client.post(
url,
{
@@ -2473,11 +2466,11 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
"""
@classmethod
def setUpClass(cls):
- super(TestInstructorAPILevelsDataDump, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestInstructorAPILevelsDataDump, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.course_mode = CourseMode(course_id=self.course.id,
mode_slug="honor",
mode_display_name="honor cert",
@@ -2504,7 +2497,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
"""
url = reverse(
'get_problem_responses',
- kwargs={'course_id': text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
problem_location = ''
@@ -2524,7 +2517,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
problem key that the get_problem_responses endpoint can
work with.
"""
- mock_problem_key = NonCallableMock(return_value=u'')
+ mock_problem_key = NonCallableMock(return_value='')
mock_problem_key.course_key = self.course.id
with patch.object(UsageKey, 'from_string') as patched_method:
patched_method.return_value = mock_problem_key
@@ -2539,7 +2532,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
"""
url = reverse(
'get_problem_responses',
- kwargs={'course_id': text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
problem_location = ''
@@ -2559,7 +2552,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
"""
url = reverse(
'get_problem_responses',
- kwargs={'course_id': text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
task_type = 'problem_responses_csv'
already_running_status = generate_already_running_error_message(task_type)
@@ -2576,9 +2569,9 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
correctly in the response to get_students_features.
"""
for student in self.students:
- student.profile.city = u"Mos Eisley {}".format(student.id)
+ student.profile.city = f"Mos Eisley {student.id}"
student.profile.save()
- url = reverse('get_students_features', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_students_features', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {})
res_json = json.loads(response.content.decode('utf-8'))
assert 'students' in res_json
@@ -2598,7 +2591,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
Test that get_students_features includes cohort info when the course is
cohorted, and does not when the course is not cohorted.
"""
- url = reverse('get_students_features', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_students_features', kwargs={'course_id': str(self.course.id)})
set_course_cohorted(self.course.id, is_cohorted)
response = self.client.post(url, {})
@@ -2620,7 +2613,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
CourseDataResearcherRole(self.course.id).add_users(course_instructor)
self.client.login(username=course_instructor.username, password='test')
- url = reverse('get_students_features', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_students_features', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {})
res_json = json.loads(response.content.decode('utf-8'))
@@ -2635,7 +2628,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
"""
url = reverse(
'get_students_who_may_enroll',
- kwargs={'course_id': text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
# Successful case:
response = self.client.post(url, {})
@@ -2656,7 +2649,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
"""
url = reverse(
'get_proctored_exam_results',
- kwargs={'course_id': text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
# Successful case:
@@ -2712,7 +2705,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
decorated_func = require_finance_admin(func)
request = self.mock_request()
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
- decorated_func(request, text_type(self.course.id))
+ decorated_func(request, str(self.course.id))
assert func.called
@patch('lms.djangoapps.instructor.views.api.anonymous_id_for_user', Mock(return_value='42'))
@@ -2722,7 +2715,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
Test the CSV output for the anonymized user ids.
"""
base_time = datetime.datetime.now(UTC)
- url = reverse('get_anon_ids', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_anon_ids', kwargs={'course_id': str(self.course.id)})
with freeze_time(base_time):
response = self.client.post(url, {})
@@ -2756,11 +2749,11 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
"""
ex_status = 503
ex_reason = 'Slow Down'
- url = reverse('list_report_downloads', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_report_downloads', kwargs={'course_id': str(self.course.id)})
with patch('storages.backends.s3boto.S3BotoStorage.listdir', side_effect=BotoServerError(ex_status, ex_reason)):
response = self.client.post(url, {})
mock_error.assert_called_with(
- u'Fetching files failed for course: %s, status: %s, reason: %s',
+ 'Fetching files failed for course: %s, status: %s, reason: %s',
self.course.id,
ex_status,
ex_reason,
@@ -2770,7 +2763,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
assert res_json == {'downloads': []}
def test_list_report_downloads(self):
- url = reverse('list_report_downloads', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_report_downloads', kwargs={'course_id': str(self.course.id)})
with patch('lms.djangoapps.instructor_task.models.DjangoStorageReportStore.links_for') as mock_links_for:
mock_links_for.return_value = [
('mock_file_name_1', 'https://1.mock.url'),
@@ -2801,10 +2794,10 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
def test_calculate_report_csv_success(
self, report_type, instructor_api_endpoint, task_api_endpoint, extra_instructor_api_kwargs
):
- kwargs = {'course_id': text_type(self.course.id)}
+ kwargs = {'course_id': str(self.course.id)}
kwargs.update(extra_instructor_api_kwargs)
url = reverse(instructor_api_endpoint, kwargs=kwargs)
- success_status = u"The {report_type} report is being created.".format(report_type=report_type)
+ success_status = f"The {report_type} report is being created."
with patch(task_api_endpoint) as mock_task_api_endpoint:
if report_type == 'problem responses':
mock_task_api_endpoint.return_value = Mock(task_id='task-id-1138')
@@ -2816,7 +2809,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
self.assertContains(response, success_status)
def test_get_ora2_responses_success(self):
- url = reverse('export_ora2_data', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('export_ora2_data', kwargs={'course_id': str(self.course.id)})
with patch('lms.djangoapps.instructor_task.api.submit_export_ora2_data') as mock_submit_ora2_task:
mock_submit_ora2_task.return_value = True
@@ -2825,7 +2818,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
self.assertContains(response, success_status)
def test_get_ora2_responses_already_running(self):
- url = reverse('export_ora2_data', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('export_ora2_data', kwargs={'course_id': str(self.course.id)})
task_type = 'export_ora2_data'
already_running_status = generate_already_running_error_message(task_type)
@@ -2836,7 +2829,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
self.assertContains(response, already_running_status, status_code=400)
def test_get_ora2_submission_files_success(self):
- url = reverse('export_ora2_submission_files', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('export_ora2_submission_files', kwargs={'course_id': str(self.course.id)})
with patch(
'lms.djangoapps.instructor_task.api.submit_export_ora2_submission_files'
@@ -2849,7 +2842,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
self.assertContains(response, success_status)
def test_get_ora2_submission_files_already_running(self):
- url = reverse('export_ora2_submission_files', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('export_ora2_submission_files', kwargs={'course_id': str(self.course.id)})
task_type = 'export_ora2_submission_files'
already_running_status = generate_already_running_error_message(task_type)
@@ -2863,7 +2856,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
def test_get_student_progress_url(self):
""" Test that progress_url is in the successful response. """
- url = reverse('get_student_progress_url', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_student_progress_url', kwargs={'course_id': str(self.course.id)})
data = {'unique_student_identifier': self.students[0].email}
response = self.client.post(url, data)
assert response.status_code == 200
@@ -2872,7 +2865,7 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
def test_get_student_progress_url_from_uname(self):
""" Test that progress_url is in the successful response. """
- url = reverse('get_student_progress_url', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_student_progress_url', kwargs={'course_id': str(self.course.id)})
data = {'unique_student_identifier': self.students[0].username}
response = self.client.post(url, data)
assert response.status_code == 200
@@ -2881,13 +2874,13 @@ class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollment
def test_get_student_progress_url_noparams(self):
""" Test that the endpoint 404's without the required query params. """
- url = reverse('get_student_progress_url', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_student_progress_url', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url)
assert response.status_code == 400
def test_get_student_progress_url_nostudent(self):
""" Test that the endpoint 400's when requesting an unknown email. """
- url = reverse('get_student_progress_url', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_student_progress_url', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url)
assert response.status_code == 400
@@ -2902,16 +2895,16 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
"""
@classmethod
def setUpClass(cls):
- super(TestInstructorAPIRegradeTask, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
cls.problem_location = msk_from_problem_urlname(
cls.course.id,
'robot-some-problem-urlname'
)
- cls.problem_urlname = text_type(cls.problem_location)
+ cls.problem_urlname = str(cls.problem_location)
def setUp(self):
- super(TestInstructorAPIRegradeTask, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
@@ -2927,7 +2920,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
def test_reset_student_attempts_deletall(self):
""" Make sure no one can delete all students state on a problem. """
- url = reverse('reset_student_attempts', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('reset_student_attempts', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'problem_to_reset': self.problem_urlname,
'all_students': True,
@@ -2937,7 +2930,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
def test_reset_student_attempts_single(self):
""" Test reset single student attempts. """
- url = reverse('reset_student_attempts', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('reset_student_attempts', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'problem_to_reset': self.problem_urlname,
'unique_student_identifier': self.student.email,
@@ -2951,7 +2944,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
@patch('lms.djangoapps.instructor_task.api.submit_reset_problem_attempts_for_all_students')
def test_reset_student_attempts_all(self, act):
""" Test reset all student attempts. """
- url = reverse('reset_student_attempts', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('reset_student_attempts', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'problem_to_reset': self.problem_urlname,
'all_students': True,
@@ -2961,7 +2954,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
def test_reset_student_attempts_missingmodule(self):
""" Test reset for non-existant problem. """
- url = reverse('reset_student_attempts', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('reset_student_attempts', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'problem_to_reset': 'robot-not-a-real-module',
'unique_student_identifier': self.student.email,
@@ -2971,7 +2964,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
@patch('lms.djangoapps.grades.signals.handlers.PROBLEM_WEIGHTED_SCORE_CHANGED.send')
def test_reset_student_attempts_delete(self, _mock_signal):
""" Test delete single student state. """
- url = reverse('reset_student_attempts', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('reset_student_attempts', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'problem_to_reset': self.problem_urlname,
'unique_student_identifier': self.student.email,
@@ -2984,7 +2977,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
def test_reset_student_attempts_nonsense(self):
""" Test failure with both unique_student_identifier and all_students. """
- url = reverse('reset_student_attempts', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('reset_student_attempts', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'problem_to_reset': self.problem_urlname,
'unique_student_identifier': self.student.email,
@@ -2995,7 +2988,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
@patch('lms.djangoapps.instructor_task.api.submit_rescore_problem_for_student')
def test_rescore_problem_single(self, act):
""" Test rescoring of a single student. """
- url = reverse('rescore_problem', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('rescore_problem', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'problem_to_reset': self.problem_urlname,
'unique_student_identifier': self.student.email,
@@ -3006,7 +2999,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
@patch('lms.djangoapps.instructor_task.api.submit_rescore_problem_for_student')
def test_rescore_problem_single_from_uname(self, act):
""" Test rescoring of a single student. """
- url = reverse('rescore_problem', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('rescore_problem', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'problem_to_reset': self.problem_urlname,
'unique_student_identifier': self.student.username,
@@ -3017,7 +3010,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
@patch('lms.djangoapps.instructor_task.api.submit_rescore_problem_for_all_students')
def test_rescore_problem_all(self, act):
""" Test rescoring for all students. """
- url = reverse('rescore_problem', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('rescore_problem', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'problem_to_reset': self.problem_urlname,
'all_students': True,
@@ -3029,7 +3022,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
def test_course_has_entrance_exam_in_student_attempts_reset(self):
""" Test course has entrance exam id set while resetting attempts"""
url = reverse('reset_student_attempts_for_entrance_exam',
- kwargs={'course_id': text_type(self.course.id)})
+ kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'all_students': True,
'delete_module': False,
@@ -3039,7 +3032,7 @@ class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTes
@patch.dict(settings.FEATURES, {'ENTRANCE_EXAMS': True})
def test_rescore_entrance_exam_with_invalid_exam(self):
""" Test course has entrance exam id set while re-scoring. """
- url = reverse('rescore_entrance_exam', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('rescore_entrance_exam', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
})
@@ -3055,7 +3048,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
"""
@classmethod
def setUpClass(cls):
- super(TestEntranceExamInstructorAPIRegradeTask, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create(
org='test_org',
course='test_course',
@@ -3092,7 +3085,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
)
def setUp(self):
- super(TestEntranceExamInstructorAPIRegradeTask, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
# Add instructor to invalid ee course
@@ -3142,7 +3135,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_reset_entrance_exam_student_attempts_delete_all(self):
""" Make sure no one can delete all students state on entrance exam. """
url = reverse('reset_student_attempts_for_entrance_exam',
- kwargs={'course_id': text_type(self.course.id)})
+ kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'all_students': True,
'delete_module': True,
@@ -3152,7 +3145,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_reset_entrance_exam_student_attempts_single(self):
""" Test reset single student attempts for entrance exam. """
url = reverse('reset_student_attempts_for_entrance_exam',
- kwargs={'course_id': text_type(self.course.id)})
+ kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
})
@@ -3167,7 +3160,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_reset_entrance_exam_all_student_attempts(self, act):
""" Test reset all student attempts for entrance exam. """
url = reverse('reset_student_attempts_for_entrance_exam',
- kwargs={'course_id': text_type(self.course.id)})
+ kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'all_students': True,
})
@@ -3177,7 +3170,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_reset_student_attempts_invalid_entrance_exam(self):
""" Test reset for invalid entrance exam. """
url = reverse('reset_student_attempts_for_entrance_exam',
- kwargs={'course_id': text_type(self.course_with_invalid_ee.id)})
+ kwargs={'course_id': str(self.course_with_invalid_ee.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
})
@@ -3186,7 +3179,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_entrance_exam_student_delete_state(self):
""" Test delete single student entrance exam state. """
url = reverse('reset_student_attempts_for_entrance_exam',
- kwargs={'course_id': text_type(self.course.id)})
+ kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
'delete_module': True,
@@ -3202,7 +3195,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
staff_user = StaffFactory(course_key=self.course.id)
self.client.login(username=staff_user.username, password='test')
url = reverse('reset_student_attempts_for_entrance_exam',
- kwargs={'course_id': text_type(self.course.id)})
+ kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
'delete_module': True,
@@ -3212,7 +3205,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_entrance_exam_reset_student_attempts_nonsense(self):
""" Test failure with both unique_student_identifier and all_students. """
url = reverse('reset_student_attempts_for_entrance_exam',
- kwargs={'course_id': text_type(self.course.id)})
+ kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
'all_students': True,
@@ -3222,7 +3215,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
@patch('lms.djangoapps.instructor_task.api.submit_rescore_entrance_exam_for_student')
def test_rescore_entrance_exam_single_student(self, act):
""" Test re-scoring of entrance exam for single student. """
- url = reverse('rescore_entrance_exam', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('rescore_entrance_exam', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
})
@@ -3231,7 +3224,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_rescore_entrance_exam_all_student(self):
""" Test rescoring for all students. """
- url = reverse('rescore_entrance_exam', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('rescore_entrance_exam', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'all_students': True,
})
@@ -3239,7 +3232,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_rescore_entrance_exam_if_higher_all_student(self):
""" Test rescoring for all students only if higher. """
- url = reverse('rescore_entrance_exam', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('rescore_entrance_exam', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'all_students': True,
'only_if_higher': True,
@@ -3248,7 +3241,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_rescore_entrance_exam_all_student_and_single(self):
""" Test re-scoring with both all students and single student parameters. """
- url = reverse('rescore_entrance_exam', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('rescore_entrance_exam', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
'all_students': True,
@@ -3257,7 +3250,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_rescore_entrance_exam_with_invalid_exam(self):
""" Test re-scoring of entrance exam with invalid exam. """
- url = reverse('rescore_entrance_exam', kwargs={'course_id': text_type(self.course_with_invalid_ee.id)})
+ url = reverse('rescore_entrance_exam', kwargs={'course_id': str(self.course_with_invalid_ee.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
})
@@ -3266,13 +3259,13 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_list_entrance_exam_instructor_tasks_student(self):
""" Test list task history for entrance exam AND student. """
# create a re-score entrance exam task
- url = reverse('rescore_entrance_exam', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('rescore_entrance_exam', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
})
assert response.status_code == 200
- url = reverse('list_entrance_exam_instructor_tasks', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_entrance_exam_instructor_tasks', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
})
@@ -3285,7 +3278,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_list_entrance_exam_instructor_tasks_all_student(self):
""" Test list task history for entrance exam AND all student. """
- url = reverse('list_entrance_exam_instructor_tasks', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_entrance_exam_instructor_tasks', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {})
assert response.status_code == 200
@@ -3296,7 +3289,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_list_entrance_exam_instructor_with_invalid_exam_key(self):
""" Test list task history for entrance exam failure if course has invalid exam. """
url = reverse('list_entrance_exam_instructor_tasks',
- kwargs={'course_id': text_type(self.course_with_invalid_ee.id)})
+ kwargs={'course_id': str(self.course_with_invalid_ee.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
})
@@ -3305,13 +3298,13 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
def test_skip_entrance_exam_student(self):
""" Test skip entrance exam api for student. """
# create a re-score entrance exam task
- url = reverse('mark_student_can_skip_entrance_exam', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('mark_student_can_skip_entrance_exam', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'unique_student_identifier': self.student.email,
})
assert response.status_code == 200
# check response
- message = _(u'This student (%s) will skip the entrance exam.') % self.student.email
+ message = _('This student (%s) will skip the entrance exam.') % self.student.email
self.assertContains(response, message)
# post again with same student
@@ -3320,7 +3313,7 @@ class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginE
})
# This time response message should be different
- message = _(u'This student (%s) is already allowed to skip the entrance exam.') % self.student.email
+ message = _('This student (%s) is already allowed to skip the entrance exam.') % self.student.email
self.assertContains(response, message)
@@ -3333,10 +3326,10 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
"""
@classmethod
def setUpClass(cls):
- super(TestInstructorSendEmail, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
- test_subject = u'\u1234 test subject'
- test_message = u'\u6824 test message'
+ test_subject = '\u1234 test subject'
+ test_message = '\u6824 test message'
cls.full_test_message = {
'send_to': '["myself", "staff"]',
'subject': test_subject,
@@ -3346,23 +3339,23 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
@classmethod
def tearDownClass(cls):
- super(TestInstructorSendEmail, cls).tearDownClass()
+ super().tearDownClass()
BulkEmailFlag.objects.all().delete()
def setUp(self):
- super(TestInstructorSendEmail, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
def test_send_email_as_logged_in_instructor(self):
- url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('send_email', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, self.full_test_message)
assert response.status_code == 200
def test_send_email_but_not_logged_in(self):
self.client.logout()
- url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('send_email', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, self.full_test_message)
assert response.status_code == 403
@@ -3370,7 +3363,7 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
self.client.logout()
student = UserFactory()
self.client.login(username=student.username, password='test')
- url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('send_email', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, self.full_test_message)
assert response.status_code == 403
@@ -3380,7 +3373,7 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
assert response.status_code != 200
def test_send_email_no_sendto(self):
- url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('send_email', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'subject': 'test subject',
'message': 'test message',
@@ -3388,7 +3381,7 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
assert response.status_code == 400
def test_send_email_invalid_sendto(self):
- url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('send_email', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'send_to': '["invalid_target", "staff"]',
'subject': 'test subject',
@@ -3397,7 +3390,7 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
assert response.status_code == 400
def test_send_email_no_subject(self):
- url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('send_email', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'send_to': '["staff"]',
'message': 'test message',
@@ -3405,7 +3398,7 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
assert response.status_code == 400
def test_send_email_no_message(self):
- url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('send_email', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'send_to': '["staff"]',
'subject': 'test subject',
@@ -3416,7 +3409,7 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
site_email = self.site_configuration.site_values.get('course_email_from_addr')
site_template = self.site_configuration.site_values.get('course_email_template_name')
CourseEmailTemplate.objects.create(name=site_template)
- url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('send_email', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, self.full_test_message)
assert response.status_code == 200
assert 1 == CourseEmail.objects.filter(course_id=self.course.id, sender=self.instructor,
@@ -3433,7 +3426,7 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
'course_email_template_name': {self.course.id.org: org_template}
})
self.site_configuration.save()
- url = reverse('send_email', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('send_email', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, self.full_test_message)
assert response.status_code == 200
assert 1 == CourseEmail.objects.filter(course_id=self.course.id, sender=self.instructor,
@@ -3442,7 +3435,7 @@ class TestInstructorSendEmail(SiteMixin, SharedModuleStoreTestCase, LoginEnrollm
template_name=org_template, from_addr=org_email).count()
-class MockCompletionInfo(object):
+class MockCompletionInfo:
"""Mock for get_task_completion_info"""
times_called = 0
@@ -3459,7 +3452,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
Test instructor task list endpoint.
"""
- class FakeTask(object):
+ class FakeTask:
""" Fake task object """
FEATURES = [
'task_type',
@@ -3504,7 +3497,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
@classmethod
def setUpClass(cls):
- super(TestInstructorAPITaskLists, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create(
entrance_exam_id='i4x://{}/{}/chapter/Entrance_exam'.format('test_org', 'test_course')
)
@@ -3512,10 +3505,10 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
cls.course.id,
'robot-some-problem-urlname'
)
- cls.problem_urlname = text_type(cls.problem_location)
+ cls.problem_urlname = str(cls.problem_location)
def setUp(self):
- super(TestInstructorAPITaskLists, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
@@ -3536,7 +3529,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
def test_list_instructor_tasks_running(self, act):
""" Test list of all running tasks. """
act.return_value = self.tasks
- url = reverse('list_instructor_tasks', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_instructor_tasks', kwargs={'course_id': str(self.course.id)})
mock_factory = MockCompletionInfo()
with patch(
'lms.djangoapps.instructor.views.instructor_task_helpers.get_task_completion_info'
@@ -3557,7 +3550,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
def test_list_background_email_tasks(self, act):
"""Test list of background email tasks."""
act.return_value = self.tasks
- url = reverse('list_background_email_tasks', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_background_email_tasks', kwargs={'course_id': str(self.course.id)})
mock_factory = MockCompletionInfo()
with patch(
'lms.djangoapps.instructor.views.instructor_task_helpers.get_task_completion_info'
@@ -3578,7 +3571,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
def test_list_instructor_tasks_problem(self, act):
""" Test list task history for problem. """
act.return_value = self.tasks
- url = reverse('list_instructor_tasks', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_instructor_tasks', kwargs={'course_id': str(self.course.id)})
mock_factory = MockCompletionInfo()
with patch(
'lms.djangoapps.instructor.views.instructor_task_helpers.get_task_completion_info'
@@ -3601,7 +3594,7 @@ class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestC
def test_list_instructor_tasks_problem_student(self, act):
""" Test list task history for problem AND student. """
act.return_value = self.tasks
- url = reverse('list_instructor_tasks', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_instructor_tasks', kwargs={'course_id': str(self.course.id)})
mock_factory = MockCompletionInfo()
with patch(
'lms.djangoapps.instructor.views.instructor_task_helpers.get_task_completion_info'
@@ -3630,11 +3623,11 @@ class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentT
"""
@classmethod
def setUpClass(cls):
- super(TestInstructorEmailContentList, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestInstructorEmailContentList, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
@@ -3664,7 +3657,7 @@ class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentT
""" Calls the list_email_content endpoint and returns the repsonse """
self.setup_fake_email_info(num_emails, with_failures)
task_history_request.return_value = list(self.tasks.values())
- url = reverse('list_email_content', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_email_content', kwargs={'course_id': str(self.course.id)})
with patch('lms.djangoapps.instructor.views.api.CourseEmail.objects.get') as mock_email_info:
mock_email_info.side_effect = self.get_matching_mock_email
response = self.client.post(url, {})
@@ -3696,7 +3689,7 @@ class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentT
# Email content should be what's expected
expected_message = self.emails[0].html_message
returned_email_info = email_info[0]
- received_message = returned_email_info[u'email'][u'html_message']
+ received_message = returned_email_info['email']['html_message']
assert expected_message == received_message
def test_content_list_no_emails(self, task_history_request):
@@ -3717,7 +3710,7 @@ class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentT
invalid_task = FakeContentTask(0, 0, 0, 'test')
invalid_task.make_invalid_input()
task_history_request.return_value = [invalid_task]
- url = reverse('list_email_content', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_email_content', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {})
assert response.status_code == 200
@@ -3741,7 +3734,7 @@ class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentT
email = FakeEmail(0)
email_info = FakeEmailInfo(email, 0, 10)
task_history_request.return_value = [task_info]
- url = reverse('list_email_content', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('list_email_content', kwargs={'course_id': str(self.course.id)})
with patch('lms.djangoapps.instructor.views.api.CourseEmail.objects.get') as mock_email_info:
mock_email_info.return_value = email
response = self.client.post(url, {})
@@ -3772,16 +3765,16 @@ class TestInstructorAPIHelpers(TestCase):
def test_split_input_list_unicode(self):
assert _split_input_list('robot@robot.edu, robot2@robot.edu') == ['robot@robot.edu', 'robot2@robot.edu']
- assert _split_input_list(u'robot@robot.edu, robot2@robot.edu') == ['robot@robot.edu', 'robot2@robot.edu']
- assert _split_input_list(u'robot@robot.edu, robot2@robot.edu') == [u'robot@robot.edu', 'robot2@robot.edu']
- scary_unistuff = unichr(40960) + u'abcd' + unichr(1972)
+ assert _split_input_list('robot@robot.edu, robot2@robot.edu') == ['robot@robot.edu', 'robot2@robot.edu']
+ assert _split_input_list('robot@robot.edu, robot2@robot.edu') == ['robot@robot.edu', 'robot2@robot.edu']
+ scary_unistuff = chr(40960) + 'abcd' + chr(1972)
assert _split_input_list(scary_unistuff) == [scary_unistuff]
def test_msk_from_problem_urlname(self):
course_id = CourseKey.from_string('MITx/6.002x/2013_Spring')
name = 'L2Node1'
output = 'i4x://MITx/6.002x/problem/L2Node1'
- assert text_type(msk_from_problem_urlname(course_id, name)) == output
+ assert str(msk_from_problem_urlname(course_id, name)) == output
def test_msk_from_problem_urlname_error(self):
args = ('notagoodcourse', 'L2Node1')
@@ -3794,10 +3787,10 @@ def get_extended_due(course, unit, user):
Gets the overridden due date for the given user on the given unit. Returns
`None` if there is no override set.
"""
- location = text_type(unit.location)
+ location = str(unit.location)
dates = get_overrides_for_user(course.id, user)
for override in dates:
- if text_type(override['location']) == location:
+ if str(override['location']) == location:
return override['actual_date']
return None
@@ -3817,7 +3810,7 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
@classmethod
def setUpClass(cls):
- super(TestDueDateExtensions, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
cls.due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=UTC)
@@ -3826,21 +3819,21 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
cls.week2 = ItemFactory.create(due=cls.due)
cls.week3 = ItemFactory.create() # No due date
cls.course.children = [
- text_type(cls.week1.location),
- text_type(cls.week2.location),
- text_type(cls.week3.location)
+ str(cls.week1.location),
+ str(cls.week2.location),
+ str(cls.week3.location)
]
cls.homework = ItemFactory.create(
parent_location=cls.week1.location,
due=cls.due
)
- cls.week1.children = [text_type(cls.homework.location)]
+ cls.week1.children = [str(cls.homework.location)]
def setUp(self):
"""
Fixtures.
"""
- super(TestDueDateExtensions, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
user1 = UserFactory.create()
StudentModule(
@@ -3897,10 +3890,10 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
extract_dates(None, self.course.id)
def test_change_due_date(self):
- url = reverse('change_due_date', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': text_type(self.week1.location),
+ 'url': str(self.week1.location),
'due_datetime': '12/30/2013 00:00'
})
assert response.status_code == 200, response.content
@@ -3908,20 +3901,20 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
get_extended_due(self.course, self.week1, self.user1)
def test_change_to_invalid_due_date(self):
- url = reverse('change_due_date', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': text_type(self.week1.location),
+ 'url': str(self.week1.location),
'due_datetime': '01/01/2009 00:00'
})
assert response.status_code == 400, response.content
assert get_extended_due(self.course, self.week1, self.user1) is None
def test_change_nonexistent_due_date(self):
- url = reverse('change_due_date', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': text_type(self.week3.location),
+ 'url': str(self.week3.location),
'due_datetime': '12/30/2013 00:00'
})
assert response.status_code == 400, response.content
@@ -3930,10 +3923,10 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
@override_experiment_waffle_flag(RELATIVE_DATES_FLAG, active=True)
def test_reset_date(self):
self.test_change_due_date()
- url = reverse('reset_due_date', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('reset_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': text_type(self.week1.location),
+ 'url': str(self.week1.location),
})
assert response.status_code == 200, response.content
assert self.due == get_extended_due(self.course, self.week1, self.user1)
@@ -3952,10 +3945,10 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
assert get_date_for_block(self.course, self.week3, self.user1) == override
# Now test that we noticed the edx-when date
- url = reverse('reset_due_date', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('reset_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': text_type(self.week3.location),
+ 'url': str(self.week3.location),
})
self.assertContains(response, 'Successfully reset due date for student')
assert get_date_for_block(self.course, self.week3, self.user1) == original_due
@@ -3963,25 +3956,25 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
def test_show_unit_extensions(self):
self.test_change_due_date()
url = reverse('show_unit_extensions',
- kwargs={'course_id': text_type(self.course.id)})
- response = self.client.post(url, {'url': text_type(self.week1.location)})
+ kwargs={'course_id': str(self.course.id)})
+ response = self.client.post(url, {'url': str(self.week1.location)})
assert response.status_code == 200, response.content
assert json.loads(response.content.decode('utf-8')) ==\
- {u'data': [{u'Extended Due Date': u'2013-12-30 00:00',
- u'Full Name': self.user1.profile.name, u'Username': self.user1.username}],
- u'header': [u'Username', u'Full Name', u'Extended Due Date'],
- u'title': (u'Users with due date extensions for %s' % self.week1.display_name)}
+ {u'data': [{'Extended Due Date': '2013-12-30 00:00',
+ 'Full Name': self.user1.profile.name, 'Username': self.user1.username}],
+ u'header': ['Username', 'Full Name', 'Extended Due Date'],
+ u'title': ('Users with due date extensions for %s' % self.week1.display_name)}
def test_show_student_extensions(self):
self.test_change_due_date()
url = reverse('show_student_extensions',
- kwargs={'course_id': text_type(self.course.id)})
+ kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {'student': self.user1.username})
assert response.status_code == 200, response.content
assert json.loads(response.content.decode('utf-8')) ==\
- {u'data': [{u'Extended Due Date': u'2013-12-30 00:00', u'Unit': self.week1.display_name}],
- u'header': [u'Unit', u'Extended Due Date'],
- u'title': (u'Due date extensions for %s (%s)' % (self.user1.profile.name, self.user1.username))}
+ {'data': [{'Extended Due Date': '2013-12-30 00:00', 'Unit': self.week1.display_name}],
+ 'header': ['Unit', 'Extended Due Date'],
+ 'title': ('Due date extensions for %s (%s)' % (self.user1.profile.name, self.user1.username))}
class TestDueDateExtensionsDeletedDate(ModuleStoreTestCase, LoginEnrollmentTestCase):
@@ -3993,7 +3986,7 @@ class TestDueDateExtensionsDeletedDate(ModuleStoreTestCase, LoginEnrollmentTestC
"""
Fixtures.
"""
- super(TestDueDateExtensionsDeletedDate, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.course = CourseFactory.create()
self.due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=UTC)
@@ -4003,15 +3996,15 @@ class TestDueDateExtensionsDeletedDate(ModuleStoreTestCase, LoginEnrollmentTestC
self.week2 = ItemFactory.create(due=self.due)
self.week3 = ItemFactory.create() # No due date
self.course.children = [
- text_type(self.week1.location),
- text_type(self.week2.location),
- text_type(self.week3.location)
+ str(self.week1.location),
+ str(self.week2.location),
+ str(self.week3.location)
]
self.homework = ItemFactory.create(
parent_location=self.week1.location,
due=self.due
)
- self.week1.children = [text_type(self.homework.location)]
+ self.week1.children = [str(self.homework.location)]
user1 = UserFactory.create()
StudentModule(
@@ -4074,10 +4067,10 @@ class TestDueDateExtensionsDeletedDate(ModuleStoreTestCase, LoginEnrollmentTestC
due date, without causing an error.
"""
- url = reverse('change_due_date', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': text_type(self.week1.location),
+ 'url': str(self.week1.location),
'due_datetime': '12/30/2013 00:00'
})
assert response.status_code == 200, response.content
@@ -4088,10 +4081,10 @@ class TestDueDateExtensionsDeletedDate(ModuleStoreTestCase, LoginEnrollmentTestC
self.week1 = self.store.update_item(self.week1, self.user1.id)
extract_dates(None, self.course.id)
# Now, week1's normal due date is deleted but the extension still exists.
- url = reverse('reset_due_date', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('reset_due_date', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, {
'student': self.user1.username,
- 'url': text_type(self.week1.location),
+ 'url': str(self.week1.location),
})
assert response.status_code == 200, response.content
assert self.due == get_extended_due(self.course, self.week1, self.user1)
@@ -4103,11 +4096,11 @@ class TestCourseIssuedCertificatesData(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(TestCourseIssuedCertificatesData, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestCourseIssuedCertificatesData, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
@@ -4127,7 +4120,7 @@ class TestCourseIssuedCertificatesData(SharedModuleStoreTestCase):
"""
Test certificates with status 'downloadable' should be in the response.
"""
- url = reverse('get_issued_certificates', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_issued_certificates', kwargs={'course_id': str(self.course.id)})
# firstly generating downloadable certificates with 'honor' mode
certificate_count = 3
for __ in range(certificate_count):
@@ -4149,7 +4142,7 @@ class TestCourseIssuedCertificatesData(SharedModuleStoreTestCase):
"""
Test for certificate csv features against mode. Certificates should be group by 'mode' in reponse.
"""
- url = reverse('get_issued_certificates', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_issued_certificates', kwargs={'course_id': str(self.course.id)})
# firstly generating downloadable certificates with 'honor' mode
certificate_count = 3
for __ in range(certificate_count):
@@ -4190,13 +4183,13 @@ class TestCourseIssuedCertificatesData(SharedModuleStoreTestCase):
"""
Test for certificate csv features.
"""
- url = reverse('get_issued_certificates', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('get_issued_certificates', kwargs={'course_id': str(self.course.id)})
# firstly generating downloadable certificates with 'honor' mode
certificate_count = 3
for __ in range(certificate_count):
self.generate_certificate(course_id=self.course.id, mode='honor', status=CertificateStatuses.downloadable)
- current_date = datetime.date.today().strftime(u"%B %d, %Y")
+ current_date = datetime.date.today().strftime("%B %d, %Y")
response = self.client.get(url, {'csv': 'true'})
assert response['Content-Type'] == 'text/csv'
assert response['Content-Disposition'] == u'attachment; filename={0}'.format('issued_certificates.csv')
@@ -4211,11 +4204,11 @@ class TestBulkCohorting(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(TestBulkCohorting, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestBulkCohorting, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.staff_user = StaffFactory(course_key=self.course.id)
self.non_staff_user = UserFactory.create()
self.tempdir = tempfile.mkdtemp()
@@ -4229,8 +4222,8 @@ class TestBulkCohorting(SharedModuleStoreTestCase):
__, file_name = tempfile.mkstemp(suffix=suffix, dir=self.tempdir)
with open(file_name, 'w') as file_pointer:
file_pointer.write(csv_data)
- with open(file_name, 'r') as file_pointer:
- url = reverse('add_users_to_cohorts', kwargs={'course_id': text_type(self.course.id)})
+ with open(file_name) as file_pointer:
+ url = reverse('add_users_to_cohorts', kwargs={'course_id': str(self.course.id)})
return self.client.post(url, {'uploaded-file': file_pointer})
def expect_error_on_file_content(self, file_content, error, file_suffix='.csv'):
diff --git a/lms/djangoapps/instructor/tests/test_api_email_localization.py b/lms/djangoapps/instructor/tests/test_api_email_localization.py
index febed0910d..f25b0d026c 100644
--- a/lms/djangoapps/instructor/tests/test_api_email_localization.py
+++ b/lms/djangoapps/instructor/tests/test_api_email_localization.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
"""
Unit tests for the localization of emails sent by instructor.api methods.
"""
@@ -7,13 +6,12 @@ Unit tests for the localization of emails sent by instructor.api methods.
from django.core import mail
from django.test.utils import override_settings
from django.urls import reverse
-from six import text_type
+from common.djangoapps.student.models import CourseEnrollment
+from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.courseware.tests.factories import InstructorFactory
from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY
from openedx.core.djangoapps.user_api.preferences.api import delete_user_preference, set_user_preference
-from common.djangoapps.student.models import CourseEnrollment
-from common.djangoapps.student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -26,11 +24,11 @@ class TestInstructorAPIEnrollmentEmailLocalization(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(TestInstructorAPIEnrollmentEmailLocalization, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(TestInstructorAPIEnrollmentEmailLocalization, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
# Platform language is English, instructor's language is Chinese,
# student's language is Esperanto, so the emails should all be sent in
@@ -46,7 +44,7 @@ class TestInstructorAPIEnrollmentEmailLocalization(SharedModuleStoreTestCase):
"""
Update the current student enrollment status.
"""
- url = reverse('students_update_enrollment', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('students_update_enrollment', kwargs={'course_id': str(self.course.id)})
args = {'identifiers': student_email, 'email_students': 'true', 'action': action, 'reason': 'testing'}
response = self.client.post(url, args)
return response
@@ -56,7 +54,7 @@ class TestInstructorAPIEnrollmentEmailLocalization(SharedModuleStoreTestCase):
Check that the email outbox contains exactly one message for which both
the message subject and body contain a certain Esperanto string.
"""
- return self.check_outbox(u"Ýöü hävé ßéén")
+ return self.check_outbox("Ýöü hävé ßéén")
def check_outbox(self, expected_message):
"""
@@ -82,7 +80,7 @@ class TestInstructorAPIEnrollmentEmailLocalization(SharedModuleStoreTestCase):
self.check_outbox_is_esperanto()
def test_set_beta_role(self):
- url = reverse('bulk_beta_modify_access', kwargs={'course_id': text_type(self.course.id)})
+ url = reverse('bulk_beta_modify_access', kwargs={'course_id': str(self.course.id)})
self.client.post(url, {'identifiers': self.student.email, 'action': 'add', 'email_students': 'true'})
self.check_outbox_is_esperanto()
diff --git a/lms/djangoapps/instructor/tests/test_certificates.py b/lms/djangoapps/instructor/tests/test_certificates.py
index b3c642ae27..c60c81f7c6 100644
--- a/lms/djangoapps/instructor/tests/test_certificates.py
+++ b/lms/djangoapps/instructor/tests/test_certificates.py
@@ -5,11 +5,11 @@ import contextlib
import io
import json
from datetime import datetime, timedelta
-import pytest
+from unittest import mock
+
import ddt
-import mock
+import pytest
import pytz
-import six
from config_models.models import cache
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
@@ -19,7 +19,7 @@ from django.urls import reverse
from capa.xqueue_interface import XQueueInterface
from common.djangoapps.course_modes.models import CourseMode
-from lms.djangoapps.courseware.tests.factories import GlobalStaffFactory, InstructorFactory, UserFactory
+from common.djangoapps.student.models import CourseEnrollment
from lms.djangoapps.certificates import api as certs_api
from lms.djangoapps.certificates.models import (
CertificateGenerationConfiguration,
@@ -33,10 +33,10 @@ from lms.djangoapps.certificates.tests.factories import (
CertificateWhitelistFactory,
GeneratedCertificateFactory
)
+from lms.djangoapps.courseware.tests.factories import GlobalStaffFactory, InstructorFactory, UserFactory
from lms.djangoapps.grades.tests.utils import mock_passing_grade
from lms.djangoapps.verify_student.services import IDVerificationService
from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory
-from common.djangoapps.student.models import CourseEnrollment
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -50,15 +50,15 @@ class CertificatesInstructorDashTest(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(CertificatesInstructorDashTest, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
cls.url = reverse(
'instructor_dashboard',
- kwargs={'course_id': six.text_type(cls.course.id)}
+ kwargs={'course_id': str(cls.course.id)}
)
def setUp(self):
- super(CertificatesInstructorDashTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.global_staff = GlobalStaffFactory()
self.instructor = InstructorFactory(course_key=self.course.id)
@@ -187,7 +187,7 @@ class CertificatesInstructorDashTest(SharedModuleStoreTestCase):
response = self.client.get(self.url)
if expected_status == 'started':
- expected = u'Generating example {name} certificate'.format(name=cert_name)
+ expected = f'Generating example {cert_name} certificate'
self.assertContains(response, expected)
elif expected_status == 'error':
expected = self.ERROR_REASON
@@ -196,7 +196,7 @@ class CertificatesInstructorDashTest(SharedModuleStoreTestCase):
expected = self.DOWNLOAD_URL
self.assertContains(response, expected)
else:
- self.fail(u"Invalid certificate status: {status}".format(status=expected_status))
+ self.fail(f"Invalid certificate status: {expected_status}")
def _assert_enable_certs_button_is_disabled(self):
"""Check that the "enable student-generated certificates" button is disabled. """
@@ -220,11 +220,11 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
"""Tests for the certificates end-points in the instructor dash API. """
@classmethod
def setUpClass(cls):
- super(CertificatesInstructorApiTest, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(CertificatesInstructorApiTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.global_staff = GlobalStaffFactory()
self.instructor = InstructorFactory(course_key=self.course.id)
self.user = UserFactory()
@@ -252,7 +252,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
self.client.login(username=self.global_staff.username, password='test')
url = reverse(
'generate_example_certificates',
- kwargs={'course_id': six.text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
response = self.client.post(url)
@@ -270,7 +270,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
self.client.login(username=self.global_staff.username, password='test')
url = reverse(
'enable_certificate_generation',
- kwargs={'course_id': six.text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
params = {'certificates-enabled': 'true' if is_enabled else 'false'}
response = self.client.post(url, data=params)
@@ -286,7 +286,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
"""Check that the response redirects to the certificates section. """
expected_redirect = reverse(
'instructor_dashboard',
- kwargs={'course_id': six.text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
expected_redirect += '#view-certificates'
self.assertRedirects(response, expected_redirect)
@@ -300,7 +300,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
self.client.login(username=user.username, password='test')
url = reverse(
'start_certificate_generation',
- kwargs={'course_id': six.text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
response = self.client.post(url)
@@ -318,7 +318,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
self.client.login(username=self.global_staff.username, password='test')
url = reverse(
'start_certificate_generation',
- kwargs={'course_id': six.text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
response = self.client.post(url)
@@ -343,7 +343,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
# Login the client and access the url with 'certificate_statuses'
self.client.login(username=self.global_staff.username, password='test')
- url = reverse('start_certificate_regeneration', kwargs={'course_id': six.text_type(self.course.id)})
+ url = reverse('start_certificate_regeneration', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, data={'certificate_statuses': [CertificateStatuses.downloadable]})
# Assert 200 status code in response
@@ -355,8 +355,8 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
# Assert success message
assert res_json['message'] ==\
- u'Certificate regeneration task has been started.' \
- u' You can view the status of the generation task in the "Pending Tasks" section.'
+ 'Certificate regeneration task has been started.' \
+ ' You can view the status of the generation task in the "Pending Tasks" section.'
@override_settings(AUDIT_CERT_CUTOFF_DATE=datetime.now(pytz.UTC) - timedelta(days=1))
@ddt.data(
@@ -406,7 +406,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
self.client.login(username=self.global_staff.username, password='test')
url = reverse(
'start_certificate_regeneration',
- kwargs={'course_id': six.text_type(self.course.id)}
+ kwargs={'course_id': str(self.course.id)}
)
with mock.patch.object(XQueueInterface, 'send_to_queue') as mock_send:
@@ -425,8 +425,8 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
# Assert success message
assert res_json['message'] ==\
- u'Certificate regeneration task has been started.' \
- u' You can view the status of the generation task in the "Pending Tasks" section.'
+ 'Certificate regeneration task has been started.' \
+ ' You can view the status of the generation task in the "Pending Tasks" section.'
# Now, check whether user has audit certificate.
cert = certs_api.get_certificate_for_user(self.user.username, self.course.id)
@@ -451,7 +451,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
# Login the client and access the url without 'certificate_statuses'
self.client.login(username=self.global_staff.username, password='test')
- url = reverse('start_certificate_regeneration', kwargs={'course_id': six.text_type(self.course.id)})
+ url = reverse('start_certificate_regeneration', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url)
# Assert 400 status code in response
@@ -460,10 +460,10 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
# Assert Error Message
assert res_json['message'] ==\
- u'Please select one or more certificate statuses that require certificate regeneration.'
+ 'Please select one or more certificate statuses that require certificate regeneration.'
# Access the url passing 'certificate_statuses' that are not present in db
- url = reverse('start_certificate_regeneration', kwargs={'course_id': six.text_type(self.course.id)})
+ url = reverse('start_certificate_regeneration', kwargs={'course_id': str(self.course.id)})
response = self.client.post(url, data={'certificate_statuses': [CertificateStatuses.generating]})
# Assert 400 status code in response
@@ -471,7 +471,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
res_json = json.loads(response.content.decode('utf-8'))
# Assert Error Message
- assert res_json['message'] == u'Please select certificate statuses from the list only.'
+ assert res_json['message'] == 'Please select certificate statuses from the list only.'
@override_settings(CERT_QUEUE='certificates')
@@ -480,18 +480,18 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
"""Tests for the generate certificates end-points in the instructor dash API. """
@classmethod
def setUpClass(cls):
- super(CertificateExceptionViewInstructorApiTest, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(CertificateExceptionViewInstructorApiTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.global_staff = GlobalStaffFactory()
self.instructor = InstructorFactory(course_key=self.course.id)
self.user = UserFactory()
self.user2 = UserFactory()
CourseEnrollment.enroll(self.user, self.course.id)
CourseEnrollment.enroll(self.user2, self.course.id)
- self.url = reverse('certificate_exception_view', kwargs={'course_id': six.text_type(self.course.id)})
+ self.url = reverse('certificate_exception_view', kwargs={'course_id': str(self.course.id)})
certificate_white_list_item = CertificateWhitelistFactory.create(
user=self.user2,
@@ -503,7 +503,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
notes="Test Notes for Test Certificate Exception",
user_email='',
user_id='',
- user_name=six.text_type(self.user.username)
+ user_name=str(self.user.username)
)
self.certificate_exception_in_db = dict(
@@ -582,8 +582,8 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
# Assert Error Message
assert res_json['message'] ==\
- u'Student username/email field is required and can not be empty.' \
- u' Kindly fill in username/email and then press "Add to Exception List" button.'
+ 'Student username/email field is required and can not be empty.' \
+ ' Kindly fill in username/email and then press "Add to Exception List" button.'
def test_certificate_exception_duplicate_user_error(self):
"""
@@ -628,7 +628,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
course2 = CourseFactory.create()
url_course2 = reverse(
'certificate_exception_view',
- kwargs={'course_id': six.text_type(course2.id)}
+ kwargs={'course_id': str(course2.id)}
)
# add certificate exception for same user in a different course
@@ -667,7 +667,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
assert not res_json['success']
# Assert Error Message
- assert res_json['message'] == u'{user} is not enrolled in this course. Please check your spelling and retry.'\
+ assert res_json['message'] == '{user} is not enrolled in this course. Please check your spelling and retry.'\
.format(user=self.certificate_exception['user_name'])
def test_certificate_exception_removed_successfully(self):
@@ -718,7 +718,7 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
assert not res_json['success']
# Assert Error Message
assert res_json['message'] ==\
- u'The record is not in the correct format. Please add a valid username or email address.'
+ 'The record is not in the correct format. Please add a valid username or email address.'
def test_remove_certificate_exception_non_existing_error(self):
"""
@@ -740,8 +740,8 @@ class CertificateExceptionViewInstructorApiTest(SharedModuleStoreTestCase):
assert not res_json['success']
# Assert Error Message
assert res_json['message'] ==\
- u'Certificate exception (user={user}) does not exist in certificate white list.' \
- u' Please refresh the page and try again.'.format(user=self.certificate_exception['user_name'])
+ 'Certificate exception (user={user}) does not exist in certificate white list.' \
+ ' Please refresh the page and try again.'.format(user=self.certificate_exception['user_name'])
@override_settings(CERT_QUEUE='certificates')
@@ -750,11 +750,11 @@ class GenerateCertificatesInstructorApiTest(SharedModuleStoreTestCase):
"""Tests for the generate certificates end-points in the instructor dash API. """
@classmethod
def setUpClass(cls):
- super(GenerateCertificatesInstructorApiTest, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
- super(GenerateCertificatesInstructorApiTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.global_staff = GlobalStaffFactory()
self.instructor = InstructorFactory(course_key=self.course.id)
self.user = UserFactory()
@@ -784,7 +784,7 @@ class GenerateCertificatesInstructorApiTest(SharedModuleStoreTestCase):
"""
url = reverse(
'generate_certificate_exceptions',
- kwargs={'course_id': six.text_type(self.course.id), 'generate_for': 'all'}
+ kwargs={'course_id': str(self.course.id), 'generate_for': 'all'}
)
response = self.client.post(
@@ -799,7 +799,7 @@ class GenerateCertificatesInstructorApiTest(SharedModuleStoreTestCase):
# Assert Request is successful
assert res_json['success']
# Assert Message
- assert res_json['message'] == u'Certificate generation started for white listed students.'
+ assert res_json['message'] == 'Certificate generation started for white listed students.'
def test_generate_certificate_exceptions_whitelist_not_generated(self):
"""
@@ -808,7 +808,7 @@ class GenerateCertificatesInstructorApiTest(SharedModuleStoreTestCase):
"""
url = reverse(
'generate_certificate_exceptions',
- kwargs={'course_id': six.text_type(self.course.id), 'generate_for': 'new'}
+ kwargs={'course_id': str(self.course.id), 'generate_for': 'new'}
)
response = self.client.post(
@@ -824,7 +824,7 @@ class GenerateCertificatesInstructorApiTest(SharedModuleStoreTestCase):
# Assert Request is successful
assert res_json['success']
# Assert Message
- assert res_json['message'] == u'Certificate generation started for white listed students.'
+ assert res_json['message'] == 'Certificate generation started for white listed students.'
def test_generate_certificate_exceptions_generate_for_incorrect_value(self):
"""
@@ -833,7 +833,7 @@ class GenerateCertificatesInstructorApiTest(SharedModuleStoreTestCase):
"""
url = reverse(
'generate_certificate_exceptions',
- kwargs={'course_id': six.text_type(self.course.id), 'generate_for': ''}
+ kwargs={'course_id': str(self.course.id), 'generate_for': ''}
)
response = self.client.post(
@@ -849,7 +849,7 @@ class GenerateCertificatesInstructorApiTest(SharedModuleStoreTestCase):
# Assert Request is not successful
assert not res_json['success']
# Assert Message
- assert res_json['message'] == u'Invalid data, generate_for must be "new" or "all".'
+ assert res_json['message'] == 'Invalid data, generate_for must be "new" or "all".'
@ddt.ddt
@@ -859,13 +859,13 @@ class TestCertificatesInstructorApiBulkWhiteListExceptions(SharedModuleStoreTest
"""
@classmethod
def setUpClass(cls):
- super(TestCertificatesInstructorApiBulkWhiteListExceptions, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
cls.url = reverse('generate_bulk_certificate_exceptions',
kwargs={'course_id': cls.course.id})
def setUp(self):
- super(TestCertificatesInstructorApiBulkWhiteListExceptions, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.global_staff = GlobalStaffFactory()
self.enrolled_user_1 = UserFactory(
username='TestStudent1',
@@ -1016,14 +1016,14 @@ class CertificateInvalidationViewTests(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(CertificateInvalidationViewTests, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
cls.url = reverse('certificate_invalidation_view',
kwargs={'course_id': cls.course.id})
cls.notes = "Test notes."
def setUp(self):
- super(CertificateInvalidationViewTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.global_staff = GlobalStaffFactory()
self.enrolled_user_1 = UserFactory(
username='TestStudent1',
@@ -1115,8 +1115,8 @@ class CertificateInvalidationViewTests(SharedModuleStoreTestCase):
# Assert Error Message
assert res_json['message'] == \
- u'Student username/email field is required and can not be empty.' \
- u' Kindly fill in username/email and then press "Invalidate Certificate" button.'
+ 'Student username/email field is required and can not be empty.' \
+ ' Kindly fill in username/email and then press "Invalidate Certificate" button.'
def test_invalid_user_name_error(self):
"""
@@ -1156,7 +1156,7 @@ class CertificateInvalidationViewTests(SharedModuleStoreTestCase):
res_json = json.loads(response.content.decode('utf-8'))
# Assert Error Message
- assert res_json['message'] == u'{user} is not enrolled in this course. Please check your spelling and retry.'\
+ assert res_json['message'] == '{user} is not enrolled in this course. Please check your spelling and retry.'\
.format(user=self.not_enrolled_student.username)
def test_no_generated_certificate_error(self):
@@ -1176,7 +1176,7 @@ class CertificateInvalidationViewTests(SharedModuleStoreTestCase):
res_json = json.loads(response.content.decode('utf-8'))
# Assert Error Message
- assert res_json['message'] == u'The student {student} does not have certificate for the course {course}. Kindly verify student username/email and the selected course are correct and try again.'.format(student=self.enrolled_user_2.username, course=self.course.number) # pylint: disable=line-too-long
+ assert res_json['message'] == 'The student {student} does not have certificate for the course {course}. Kindly verify student username/email and the selected course are correct and try again.'.format(student=self.enrolled_user_2.username, course=self.course.number) # pylint: disable=line-too-long
def test_certificate_already_invalid_error(self):
"""
@@ -1196,7 +1196,7 @@ class CertificateInvalidationViewTests(SharedModuleStoreTestCase):
res_json = json.loads(response.content.decode('utf-8'))
# Assert Error Message
- assert res_json['message'] == u'Certificate for student {user} is already invalid, kindly verify that certificate was generated for this student and then proceed.'.format(user=self.enrolled_user_1.username) # pylint: disable=line-too-long
+ assert res_json['message'] == 'Certificate for student {user} is already invalid, kindly verify that certificate was generated for this student and then proceed.'.format(user=self.enrolled_user_1.username) # pylint: disable=line-too-long
def test_duplicate_certificate_invalidation_error(self):
"""
@@ -1220,7 +1220,7 @@ class CertificateInvalidationViewTests(SharedModuleStoreTestCase):
res_json = json.loads(response.content.decode('utf-8'))
# Assert Error Message
- assert res_json['message'] == u'Certificate of {user} has already been invalidated. Please check your spelling and retry.'.format(user=self.enrolled_user_1.username) # pylint: disable=line-too-long
+ assert res_json['message'] == 'Certificate of {user} has already been invalidated. Please check your spelling and retry.'.format(user=self.enrolled_user_1.username) # pylint: disable=line-too-long
def test_remove_certificate_invalidation(self):
"""
@@ -1271,4 +1271,4 @@ class CertificateInvalidationViewTests(SharedModuleStoreTestCase):
res_json = json.loads(response.content.decode('utf-8'))
# Assert Error Message
- assert res_json['message'] == u'Certificate Invalidation does not exist, Please refresh the page and try again.'
+ assert res_json['message'] == 'Certificate Invalidation does not exist, Please refresh the page and try again.'
diff --git a/lms/djangoapps/instructor/tests/test_email.py b/lms/djangoapps/instructor/tests/test_email.py
index e990d8037b..1b2fc5e980 100644
--- a/lms/djangoapps/instructor/tests/test_email.py
+++ b/lms/djangoapps/instructor/tests/test_email.py
@@ -8,11 +8,10 @@ that the view is conditionally available when Course Auth is turned on.
from django.urls import reverse
from opaque_keys.edx.keys import CourseKey
-from six import text_type
+from common.djangoapps.student.tests.factories import AdminFactory
from lms.djangoapps.bulk_email.api import is_bulk_email_enabled_for_course, is_bulk_email_feature_enabled
from lms.djangoapps.bulk_email.models import BulkEmailFlag, CourseAuthorization
-from common.djangoapps.student.tests.factories import AdminFactory
from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_MODULESTORE, SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -25,23 +24,23 @@ class TestNewInstructorDashboardEmailViewMongoBacked(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(TestNewInstructorDashboardEmailViewMongoBacked, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
# URL for instructor dash
- cls.url = reverse('instructor_dashboard', kwargs={'course_id': text_type(cls.course.id)})
+ cls.url = reverse('instructor_dashboard', kwargs={'course_id': str(cls.course.id)})
# URL for email view
cls.email_link = ''
def setUp(self):
- super(TestNewInstructorDashboardEmailViewMongoBacked, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
# Create instructor account
instructor = AdminFactory.create()
self.client.login(username=instructor.username, password="test")
def tearDown(self):
- super(TestNewInstructorDashboardEmailViewMongoBacked, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
+ super().tearDown()
BulkEmailFlag.objects.all().delete()
# In order for bulk email to work, we must have both the BulkEmailFlag.is_enabled()
@@ -119,28 +118,28 @@ class TestNewInstructorDashboardEmailViewXMLBacked(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(TestNewInstructorDashboardEmailViewXMLBacked, cls).setUpClass()
+ super().setUpClass()
cls.course_key = CourseKey.from_string('edX/toy/2012_Fall')
# URL for instructor dash
- cls.url = reverse('instructor_dashboard', kwargs={'course_id': text_type(cls.course_key)})
+ cls.url = reverse('instructor_dashboard', kwargs={'course_id': str(cls.course_key)})
# URL for email view
cls.email_link = ''
def setUp(self):
- super(TestNewInstructorDashboardEmailViewXMLBacked, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
# Create instructor account
instructor = AdminFactory.create()
self.client.login(username=instructor.username, password="test")
# URL for instructor dash
- self.url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course_key)})
+ self.url = reverse('instructor_dashboard', kwargs={'course_id': str(self.course_key)})
# URL for email view
self.email_link = ''
def tearDown(self):
- super(TestNewInstructorDashboardEmailViewXMLBacked, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
+ super().tearDown()
BulkEmailFlag.objects.all().delete()
# The flag is enabled, and since REQUIRE_COURSE_EMAIL_AUTH is False, all courses should
diff --git a/lms/djangoapps/instructor/tests/test_enrollment.py b/lms/djangoapps/instructor/tests/test_enrollment.py
index c4aaf04c7d..d3f2cf018a 100644
--- a/lms/djangoapps/instructor/tests/test_enrollment.py
+++ b/lms/djangoapps/instructor/tests/test_enrollment.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
"""
Unit tests for instructor.enrollment methods.
"""
@@ -6,25 +5,27 @@ Unit tests for instructor.enrollment methods.
import json
from abc import ABCMeta
-import pytest
+from unittest.mock import patch
+
import ddt
-import six
+import pytest
from ccx_keys.locator import CCXLocator
from crum import set_current_request
from django.conf import settings
from django.utils.translation import get_language
from django.utils.translation import override as override_language
-from mock import patch
from opaque_keys.edx.locator import CourseLocator
-from six import text_type
from submissions import api as sub_api
from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory
+from common.djangoapps.student.models import CourseEnrollment, CourseEnrollmentAllowed, anonymous_id_for_user
+from common.djangoapps.student.roles import CourseCcxCoachRole
+from common.djangoapps.student.tests.factories import AdminFactory, UserFactory
+from lms.djangoapps.ccx.tests.factories import CcxFactory
+from lms.djangoapps.course_blocks.api import get_course_blocks
from lms.djangoapps.courseware.models import StudentModule
from lms.djangoapps.grades.subsection_grade_factory import SubsectionGradeFactory
from lms.djangoapps.grades.tests.utils import answer_problem
-from lms.djangoapps.ccx.tests.factories import CcxFactory
-from lms.djangoapps.course_blocks.api import get_course_blocks
from lms.djangoapps.instructor.enrollment import (
EmailEnrollmentState,
enroll_email,
@@ -38,9 +39,6 @@ from lms.djangoapps.teams.models import CourseTeamMembership
from lms.djangoapps.teams.tests.factories import CourseTeamFactory
from openedx.core.djangoapps.ace_common.tests.mixins import EmailTemplateTagMixin
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, get_mock_request
-from common.djangoapps.student.models import CourseEnrollment, CourseEnrollmentAllowed, anonymous_id_for_user
-from common.djangoapps.student.roles import CourseCcxCoachRole
-from common.djangoapps.student.tests.factories import AdminFactory, UserFactory
from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@@ -48,7 +46,7 @@ from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
class TestSettableEnrollmentState(CacheIsolationTestCase):
""" Test the basis class for enrollment tests. """
def setUp(self):
- super(TestSettableEnrollmentState, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.course_key = CourseLocator('Robot', 'fAKE', 'C--se--ID')
def test_mes_create(self):
@@ -67,7 +65,7 @@ class TestSettableEnrollmentState(CacheIsolationTestCase):
assert mes == ees
-class TestEnrollmentChangeBase(six.with_metaclass(ABCMeta, CacheIsolationTestCase)):
+class TestEnrollmentChangeBase(CacheIsolationTestCase, metaclass=ABCMeta):
"""
Test instructor enrollment administration against database effects.
@@ -77,7 +75,7 @@ class TestEnrollmentChangeBase(six.with_metaclass(ABCMeta, CacheIsolationTestCas
"""
def setUp(self):
- super(TestEnrollmentChangeBase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.course_key = CourseLocator('Robot', 'fAKE', 'C--se--ID')
def _run_state_change_test(self, before_ideal, after_ideal, action):
@@ -372,7 +370,7 @@ class TestInstructorEnrollmentStudentModule(SharedModuleStoreTestCase):
""" Test student module manipulations. """
@classmethod
def setUpClass(cls):
- super(TestInstructorEnrollmentStudentModule, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory(
name='fake',
org='course',
@@ -403,7 +401,7 @@ class TestInstructorEnrollmentStudentModule(SharedModuleStoreTestCase):
)
def setUp(self):
- super(TestInstructorEnrollmentStudentModule, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.user = UserFactory()
@@ -482,8 +480,8 @@ class TestInstructorEnrollmentStudentModule(SharedModuleStoreTestCase):
# Create a submission and score for the student using the submissions API
student_item = {
'student_id': anonymous_id_for_user(user, self.course_key),
- 'course_id': text_type(self.course_key),
- 'item_id': text_type(problem_location),
+ 'course_id': str(self.course_key),
+ 'item_id': str(problem_location),
'item_type': 'openassessment'
}
submission = sub_api.create_submission(student_item, 'test answer')
@@ -708,7 +706,7 @@ class TestStudentModuleGrading(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(TestStudentModuleGrading, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
cls.chapter = ItemFactory.create(
parent=cls.course,
@@ -743,7 +741,7 @@ class TestStudentModuleGrading(SharedModuleStoreTestCase):
@classmethod
def tearDownClass(cls):
- super(TestStudentModuleGrading, cls).tearDownClass()
+ super().tearDownClass()
set_current_request(None)
def _get_subsection_grade_and_verify(self, all_earned, all_possible, graded_earned, graded_possible):
@@ -780,7 +778,7 @@ class TestStudentModuleGrading(SharedModuleStoreTestCase):
self._get_subsection_grade_and_verify(0, 1, 0, 1)
-class EnrollmentObjects(object):
+class EnrollmentObjects:
"""
Container for enrollment objects.
@@ -856,13 +854,13 @@ class TestSendBetaRoleEmail(CacheIsolationTestCase):
"""
def setUp(self):
- super(TestSendBetaRoleEmail, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.user = UserFactory.create()
self.email_params = {'course': 'Robot Super Course'}
def test_bad_action(self):
bad_action = 'beta_tester'
- error_msg = u"Unexpected action received '{}' - expected 'add' or 'remove'".format(bad_action)
+ error_msg = f"Unexpected action received '{bad_action}' - expected 'add' or 'remove'"
with self.assertRaisesRegex(ValueError, error_msg):
send_beta_role_email(bad_action, self.user, self.email_params)
@@ -876,12 +874,12 @@ class TestGetEmailParamsCCX(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(TestGetEmailParamsCCX, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
@patch.dict('django.conf.settings.FEATURES', {'CUSTOM_COURSES_EDX': True})
def setUp(self):
- super(TestGetEmailParamsCCX, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.coach = AdminFactory.create()
role = CourseCcxCoachRole(self.course.id)
role.add_users(self.coach)
@@ -890,12 +888,12 @@ class TestGetEmailParamsCCX(SharedModuleStoreTestCase):
# Explicitly construct what we expect the course URLs to be
site = settings.SITE_NAME
- self.course_url = u'https://{}/courses/{}/'.format(
+ self.course_url = 'https://{}/courses/{}/'.format(
site,
self.course_key
)
self.course_about_url = self.course_url + 'about'
- self.registration_url = u'https://{}/register'.format(site)
+ self.registration_url = f'https://{site}/register'
@patch.dict('django.conf.settings.FEATURES', {'CUSTOM_COURSES_EDX': True})
def test_ccx_enrollment_email_params(self):
@@ -922,17 +920,17 @@ class TestGetEmailParams(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(TestGetEmailParams, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
# Explicitly construct what we expect the course URLs to be
site = settings.SITE_NAME
- cls.course_url = u'https://{}/courses/{}/'.format(
+ cls.course_url = 'https://{}/courses/{}/'.format(
site,
- text_type(cls.course.id)
+ str(cls.course.id)
)
cls.course_about_url = cls.course_url + 'about'
- cls.registration_url = u'https://{}/register'.format(site)
+ cls.registration_url = f'https://{site}/register'
def test_normal_params(self):
# For a normal site, what do we expect to get for the URLs?
@@ -967,14 +965,14 @@ class TestRenderMessageToString(EmailTemplateTagMixin, SharedModuleStoreTestCase
@classmethod
def setUpClass(cls):
- super(TestRenderMessageToString, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
cls.subject_template = 'instructor/edx_ace/allowedenroll/email/subject.txt'
cls.message_template = 'instructor/edx_ace/allowedenroll/email/body.txt'
@patch.dict('django.conf.settings.FEATURES', {'CUSTOM_COURSES_EDX': True})
def setUp(self):
- super(TestRenderMessageToString, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
coach = AdminFactory.create()
role = CourseCcxCoachRole(self.course.id)
role.add_users(coach)
@@ -1034,7 +1032,7 @@ class TestRenderMessageToString(EmailTemplateTagMixin, SharedModuleStoreTestCase
subject, message = self.get_subject_and_message('eo')
language_after_rendering = get_language()
- you_have_been_invited_in_esperanto = u"Ýöü hävé ßéén"
+ you_have_been_invited_in_esperanto = "Ýöü hävé ßéén"
assert you_have_been_invited_in_esperanto in subject
assert you_have_been_invited_in_esperanto in message
assert settings.LANGUAGE_CODE == language_after_rendering
@@ -1062,7 +1060,7 @@ class TestRenderMessageToString(EmailTemplateTagMixin, SharedModuleStoreTestCase
assert self.ccx.display_name in subject
assert self.ccx.display_name in message
site = settings.SITE_NAME
- course_url = u'https://{}/courses/{}/'.format(
+ course_url = 'https://{}/courses/{}/'.format(
site,
self.course_key
)
@@ -1100,7 +1098,7 @@ class TestRenderMessageToString(EmailTemplateTagMixin, SharedModuleStoreTestCase
assert self.ccx.display_name in subject
assert self.ccx.display_name in message
site = settings.SITE_NAME
- registration_url = u'https://{}/register'.format(site)
+ registration_url = f'https://{site}/register'
assert registration_url in message
@patch.dict('django.conf.settings.FEATURES', {'CUSTOM_COURSES_EDX': True})
diff --git a/lms/djangoapps/instructor/tests/test_proctoring.py b/lms/djangoapps/instructor/tests/test_proctoring.py
index 79e1a756ed..95f25f72f6 100644
--- a/lms/djangoapps/instructor/tests/test_proctoring.py
+++ b/lms/djangoapps/instructor/tests/test_proctoring.py
@@ -2,16 +2,16 @@
Unit tests for Edx Proctoring feature flag in new instructor dashboard.
"""
+from unittest.mock import patch
+
import ddt
from django.apps import apps
from django.conf import settings
from django.urls import reverse
-from mock import patch
-from six import text_type
-
from edx_proctoring.api import create_exam
from edx_proctoring.backends.tests.test_backend import TestBackendProvider
from edx_toggles.toggles.testutils import override_waffle_flag
+
from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole
from common.djangoapps.student.tests.factories import AdminFactory
from lms.djangoapps.courseware.toggles import EXAM_RESUME_PROCTORING_IMPROVEMENTS
@@ -28,12 +28,12 @@ class TestProctoringDashboardViews(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(TestProctoringDashboardViews, cls).setUpClass()
+ super().setUpClass()
button = '' # lint-amnesty, pylint: disable=line-too-long
cls.proctoring_link = button
def setUp(self):
- super(TestProctoringDashboardViews, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
# Create instructor account
self.instructor = AdminFactory.create()
@@ -43,7 +43,7 @@ class TestProctoringDashboardViews(SharedModuleStoreTestCase):
"""
Create URL for instructor dashboard
"""
- self.url = reverse('instructor_dashboard', kwargs={'course_id': text_type(course.id)}) # lint-amnesty, pylint: disable=attribute-defined-outside-init
+ self.url = reverse('instructor_dashboard', kwargs={'course_id': str(course.id)}) # lint-amnesty, pylint: disable=attribute-defined-outside-init
def setup_course(self, enable_proctored_exams, enable_timed_exams):
"""
diff --git a/lms/djangoapps/instructor/tests/test_services.py b/lms/djangoapps/instructor/tests/test_services.py
index b7985d6ff1..e8ea894900 100644
--- a/lms/djangoapps/instructor/tests/test_services.py
+++ b/lms/djangoapps/instructor/tests/test_services.py
@@ -1,22 +1,21 @@
"""
Tests for the InstructorService
"""
-
-
import json
+from unittest import mock
+
import pytest
import mock
import six
+from django.core.exceptions import ObjectDoesNotExist
from opaque_keys import InvalidKeyError
-from django.core.exceptions import ObjectDoesNotExist
-
+from common.djangoapps.student.models import CourseEnrollment
+from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.courseware.models import StudentModule
from lms.djangoapps.instructor.access import allow_access
from lms.djangoapps.instructor.services import InstructorService
from lms.djangoapps.instructor.tests.test_tools import msk_from_problem_urlname
-from common.djangoapps.student.models import CourseEnrollment
-from common.djangoapps.student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -28,7 +27,7 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(InstructorServiceTests, cls).setUpClass()
+ super().setUpClass()
cls.email = 'escalation@test.com'
cls.course = CourseFactory.create(proctoring_escalation_email=cls.email)
cls.problem_location = msk_from_problem_urlname(
@@ -39,11 +38,11 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
cls.course.id,
'robot-some-other_problem-urlname'
)
- cls.problem_urlname = six.text_type(cls.problem_location)
- cls.other_problem_urlname = six.text_type(cls.other_problem_location)
+ cls.problem_urlname = str(cls.problem_location)
+ cls.other_problem_urlname = str(cls.other_problem_location)
def setUp(self):
- super(InstructorServiceTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.student = UserFactory()
CourseEnrollment.enroll(self.student, self.course.id)
@@ -68,7 +67,7 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
self.service.delete_student_attempt(
self.student.username,
- six.text_type(self.course.id),
+ str(self.course.id),
self.problem_urlname,
requesting_user=self.student,
)
@@ -84,7 +83,7 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
result = self.service.delete_student_attempt( # lint-amnesty, pylint: disable=assignment-from-none
self.student.username,
- six.text_type(self.course.id),
+ str(self.course.id),
'foo/bar/baz',
requesting_user=self.student,
)
@@ -97,7 +96,7 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
result = self.service.delete_student_attempt( # lint-amnesty, pylint: disable=assignment-from-none
'bad_student',
- six.text_type(self.course.id),
+ str(self.course.id),
'foo/bar/baz',
requesting_user=self.student,
)
@@ -110,7 +109,7 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
result = self.service.delete_student_attempt( # lint-amnesty, pylint: disable=assignment-from-none
self.student.username,
- six.text_type(self.course.id),
+ str(self.course.id),
self.other_problem_urlname,
requesting_user=self.student,
)
@@ -122,7 +121,7 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
"""
result = self.service.is_course_staff(
self.student,
- six.text_type(self.course.id)
+ str(self.course.id)
)
assert not result
@@ -130,7 +129,7 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
allow_access(self.course, self.student, 'staff')
result = self.service.is_course_staff(
self.student,
- six.text_type(self.course.id)
+ str(self.course.id)
)
assert result
@@ -140,11 +139,11 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
"""
requester_name = "edx-proctoring"
email = "edx-proctoring@edx.org"
- subject = u"Proctored Exam Review: {review_status}".format(review_status="Suspicious")
+ subject = "Proctored Exam Review: {review_status}".format(review_status="Suspicious")
- body = u"A proctored exam attempt for {exam_name} in {course_name} by username: {student_username} was " \
- u"reviewed as {review_status} by the proctored exam review provider.\n" \
- u"Review link: {url}"
+ body = "A proctored exam attempt for {exam_name} in {course_name} by username: {student_username} was " \
+ "reviewed as {review_status} by the proctored exam review provider.\n" \
+ "Review link: {url}"
args = {
'exam_name': 'test_exam',
'student_username': 'test_student',
@@ -157,7 +156,7 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
with mock.patch("lms.djangoapps.instructor.services.create_zendesk_ticket") as mock_create_zendesk_ticket:
self.service.send_support_notification(
- course_id=six.text_type(self.course.id),
+ course_id=str(self.course.id),
exam_name=args['exam_name'],
student_username=args["student_username"],
review_status="Suspicious",
@@ -169,7 +168,7 @@ class InstructorServiceTests(SharedModuleStoreTestCase):
args['url'] = 'http://review/url'
with mock.patch("lms.djangoapps.instructor.services.create_zendesk_ticket") as mock_create_zendesk_ticket:
self.service.send_support_notification(
- course_id=six.text_type(self.course.id),
+ course_id=str(self.course.id),
exam_name=args['exam_name'],
student_username=args["student_username"],
review_status="Suspicious",
diff --git a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py
index 36f5e3ac8f..42be8e9210 100644
--- a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py
+++ b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py
@@ -1,16 +1,12 @@
"""
Tests of the instructor dashboard spoc gradebook
"""
-
-
from django.urls import reverse
-from six import text_type
-from six.moves import range
from capa.tests.response_xml_factory import StringResponseXMLFactory
+from common.djangoapps.student.tests.factories import AdminFactory, CourseEnrollmentFactory, UserFactory
from lms.djangoapps.courseware.tests.factories import StudentModuleFactory
from lms.djangoapps.grades.api import task_compute_all_grades_for_course
-from common.djangoapps.student.tests.factories import AdminFactory, CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@@ -27,7 +23,7 @@ class TestGradebook(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(TestGradebook, cls).setUpClass()
+ super().setUpClass()
# Create a course with the desired grading policy (from our class attribute)
kwargs = {}
@@ -57,7 +53,7 @@ class TestGradebook(SharedModuleStoreTestCase):
]
def setUp(self):
- super(TestGradebook, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
instructor = AdminFactory.create()
self.client.login(username=instructor.username, password='test')
@@ -75,11 +71,11 @@ class TestGradebook(SharedModuleStoreTestCase):
course_id=self.course.id,
module_state_key=item.location
)
- task_compute_all_grades_for_course.apply_async(kwargs={'course_key': text_type(self.course.id)})
+ task_compute_all_grades_for_course.apply_async(kwargs={'course_key': str(self.course.id)})
self.response = self.client.get(reverse(
'spoc_gradebook',
- args=(text_type(self.course.id),)
+ args=(str(self.course.id),)
))
assert self.response.status_code == 200
@@ -92,7 +88,7 @@ class TestDefaultGradingPolicy(TestGradebook):
"""
def test_all_users_listed(self):
for user in self.users:
- assert user.username in text_type(self.response.content, 'utf-8')
+ assert user.username in str(self.response.content, 'utf-8')
def test_default_policy(self):
# Default >= 50% passes, so Users 5-10 should be passing for Homework 1 [6]
@@ -135,10 +131,10 @@ class TestLetterCutoffPolicy(TestGradebook):
def test_styles(self):
- self.assertContains(self.response, u"grade_A {color:green;}")
- self.assertContains(self.response, u"grade_B {color:Chocolate;}")
- self.assertContains(self.response, u"grade_C {color:DarkSlateGray;}")
- self.assertContains(self.response, u"grade_D {color:DarkSlateGray;}")
+ self.assertContains(self.response, "grade_A {color:green;}")
+ self.assertContains(self.response, "grade_B {color:Chocolate;}")
+ self.assertContains(self.response, "grade_C {color:DarkSlateGray;}")
+ self.assertContains(self.response, "grade_D {color:DarkSlateGray;}")
def test_assigned_grades(self):
# Users 9-10 have >= 90% on Homeworks [2]
diff --git a/lms/djangoapps/instructor/tests/test_tools.py b/lms/djangoapps/instructor/tests/test_tools.py
index c6a02a921e..0ad231bf21 100644
--- a/lms/djangoapps/instructor/tests/test_tools.py
+++ b/lms/djangoapps/instructor/tests/test_tools.py
@@ -6,20 +6,22 @@ Tests for views/tools.py.
import datetime
import json
import unittest
+from unittest import mock
+
import pytest
import mock
import six
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.exceptions import MultipleObjectsReturned
from django.test import TestCase
+from edx_when.api import set_dates_for_course
+from edx_when.field_data import DateLookupFieldData
from opaque_keys.edx.keys import CourseKey
from pytz import UTC
-from edx_when.api import set_dates_for_course
-from edx_when.field_data import DateLookupFieldData
+from common.djangoapps.student.tests.factories import UserFactory
from openedx.core.djangoapps.course_date_signals import handlers
from openedx.core.djangoapps.schedules.tests.factories import ScheduleFactory
-from common.djangoapps.student.tests.factories import UserFactory
from xmodule.fields import Date
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@@ -34,7 +36,7 @@ class TestDashboardError(unittest.TestCase):
Test DashboardError exceptions.
"""
def test_response(self):
- error = tools.DashboardError(u'Oh noes!')
+ error = tools.DashboardError('Oh noes!')
response = json.loads(error.response().content.decode('utf-8'))
assert response == {'error': 'Oh noes!'}
@@ -73,7 +75,7 @@ class TestRequireStudentIdentifier(TestCase):
"""
Fixtures
"""
- super(TestRequireStudentIdentifier, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.student = UserFactory.create()
def test_valid_student_id(self):
@@ -102,7 +104,7 @@ class TestFindUnit(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(TestFindUnit, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create()
with cls.store.bulk_operations(cls.course.id, emit_signals=False):
week1 = ItemFactory.create(parent=cls.course)
@@ -112,7 +114,7 @@ class TestFindUnit(SharedModuleStoreTestCase):
"""
Test finding a nested unit.
"""
- url = six.text_type(self.homework.location)
+ url = str(self.homework.location)
found_unit = tools.find_unit(self.course, url)
assert found_unit.location == self.homework.location
@@ -157,7 +159,7 @@ class TestGetUnitsWithDueDate(ModuleStoreTestCase):
"""
URLs for sequence of nodes.
"""
- return sorted(six.text_type(i.location) for i in seq)
+ return sorted(str(i.location) for i in seq)
assert urls(tools.get_units_with_due_date(self.course)) == urls((self.week1, self.week2))
@@ -176,14 +178,11 @@ class TestTitleOrUrl(unittest.TestCase):
"""
Mock implementation of __unicode__ or __str__ for the unit's location.
"""
- return u'test:hello'
+ return 'test:hello'
unit = mock.Mock(display_name=None)
- if six.PY2:
- unit.location.__unicode__ = mock_location_text
- else:
- unit.location.__str__ = mock_location_text
- assert tools.title_or_url(unit) == u'test:hello'
+ unit.location.__str__ = mock_location_text
+ assert tools.title_or_url(unit) == 'test:hello'
def inject_field_data(blocks, course, user):
@@ -201,7 +200,7 @@ class TestSetDueDateExtension(ModuleStoreTestCase):
"""
Fixtures.
"""
- super(TestSetDueDateExtension, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.due = due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=UTC)
course = CourseFactory.create()
@@ -290,7 +289,7 @@ class TestDataDumps(ModuleStoreTestCase):
"""
Fixtures.
"""
- super(TestDataDumps, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=UTC)
course = CourseFactory.create()
@@ -378,7 +377,7 @@ class TestStudentFromIdentifier(TestCase):
"""
@classmethod
def setUpClass(cls):
- super(TestStudentFromIdentifier, cls).setUpClass()
+ super().setUpClass()
cls.valid_student = UserFactory.create(username='baz@touchstone')
cls.student_conflicting_email = UserFactory.create(email='foo@touchstone.com')
cls.student_conflicting_username = UserFactory.create(username='foo@touchstone.com')
diff --git a/lms/djangoapps/instructor/tests/utils.py b/lms/djangoapps/instructor/tests/utils.py
index 084e619498..6b724365f1 100644
--- a/lms/djangoapps/instructor/tests/utils.py
+++ b/lms/djangoapps/instructor/tests/utils.py
@@ -7,19 +7,18 @@ import datetime
import json
import random
-import six
from pytz import UTC
from common.djangoapps.util.date_utils import get_default_time_display
-class FakeInfo(object):
+class FakeInfo:
"""Parent class for faking objects used in tests"""
FEATURES = []
def __init__(self):
for feature in self.FEATURES:
- setattr(self, feature, u'expected')
+ setattr(self, feature, 'expected')
def to_dict(self):
""" Returns a dict representation of the object """
@@ -35,7 +34,7 @@ class FakeContentTask(FakeInfo):
]
def __init__(self, email_id, num_sent, num_failed, sent_to): # lint-amnesty, pylint: disable=unused-argument
- super(FakeContentTask, self).__init__() # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__()
self.task_input = {'email_id': email_id}
self.task_input = json.dumps(self.task_input)
self.task_output = {'succeeded': num_sent, 'failed': num_failed}
@@ -57,8 +56,8 @@ class FakeEmail(FakeInfo):
]
def __init__(self, email_id):
- super(FakeEmail, self).__init__() # lint-amnesty, pylint: disable=super-with-arguments
- self.id = six.text_type(email_id) # pylint: disable=invalid-name
+ super().__init__()
+ self.id = str(email_id) # pylint: disable=invalid-name
# Select a random data for create field
year = random.randint(1950, 2000)
month = random.randint(1, 12)
@@ -69,7 +68,7 @@ class FakeEmail(FakeInfo):
self.targets = FakeTargetGroup()
-class FakeTarget(object):
+class FakeTarget:
""" Corresponding fake target for a fake email """
target_type = "expected"
@@ -78,7 +77,7 @@ class FakeTarget(object):
return self.target_type
-class FakeTargetGroup(object):
+class FakeTargetGroup:
""" Mocks out the M2M relationship between FakeEmail and FakeTarget """
def all(self):
""" Mocks out a django method """
@@ -88,21 +87,21 @@ class FakeTargetGroup(object):
class FakeEmailInfo(FakeInfo):
""" Fake email information object """
FEATURES = [
- u'created',
- u'sent_to',
- u'email',
- u'number_sent',
- u'requester',
+ 'created',
+ 'sent_to',
+ 'email',
+ 'number_sent',
+ 'requester',
]
EMAIL_FEATURES = [
- u'subject',
- u'html_message',
- u'id'
+ 'subject',
+ 'html_message',
+ 'id'
]
def __init__(self, fake_email, num_sent, num_failed):
- super(FakeEmailInfo, self).__init__() # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__()
self.created = get_default_time_display(fake_email.created)
number_sent = str(num_sent) + ' sent'
@@ -112,5 +111,5 @@ class FakeEmailInfo(FakeInfo):
self.number_sent = number_sent
fake_email_dict = fake_email.to_dict()
self.email = {feature: fake_email_dict[feature] for feature in self.EMAIL_FEATURES}
- self.requester = u'expected'
- self.sent_to = [u'expected']
+ self.requester = 'expected'
+ self.sent_to = ['expected']
diff --git a/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py b/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py
index c13b0acf8a..783f5da8f7 100644
--- a/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py
+++ b/lms/djangoapps/instructor/tests/views/test_instructor_dashboard.py
@@ -5,23 +5,23 @@ Unit tests for instructor_dashboard.py.
import datetime
import re
+from unittest.mock import patch
import ddt
-import six
from django.conf import settings
from django.contrib.sites.models import Site
from django.test.utils import override_settings
from django.urls import reverse
-from mock import patch
+from edx_toggles.toggles.testutils import override_waffle_flag
from pyquery import PyQuery as pq
from pytz import UTC
-from six import text_type
-from six.moves import range
-from common.test.utils import XssTestMixin
from common.djangoapps.course_modes.models import CourseMode
-from edx_toggles.toggles.testutils import override_waffle_flag # lint-amnesty, pylint: disable=wrong-import-order
from common.djangoapps.edxmako.shortcuts import render_to_response
+from common.djangoapps.student.models import CourseEnrollment
+from common.djangoapps.student.roles import CourseFinanceAdminRole # lint-amnesty, pylint: disable=unused-import
+from common.djangoapps.student.tests.factories import AdminFactory, CourseAccessRoleFactory, CourseEnrollmentFactory
+from common.test.utils import XssTestMixin
from lms.djangoapps.courseware.tabs import get_course_tab_list
from lms.djangoapps.courseware.tests.factories import StaffFactory, StudentModuleFactory, UserFactory
from lms.djangoapps.courseware.tests.helpers import LoginEnrollmentTestCase
@@ -29,9 +29,6 @@ from lms.djangoapps.grades.config.waffle import WRITABLE_GRADEBOOK, waffle_flags
from lms.djangoapps.instructor.toggles import DATA_DOWNLOAD_V2
from lms.djangoapps.instructor.views.gradebook_api import calculate_page_info
from openedx.core.djangoapps.site_configuration.models import SiteConfiguration
-from common.djangoapps.student.models import CourseEnrollment
-from common.djangoapps.student.roles import CourseFinanceAdminRole # lint-amnesty, pylint: disable=unused-import
-from common.djangoapps.student.tests.factories import AdminFactory, CourseAccessRoleFactory, CourseEnrollmentFactory
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls
@@ -61,7 +58,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
"""
Set up tests
"""
- super(TestInstructorDashboard, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.course = CourseFactory.create(
grading_policy={"GRADE_CUTOFFS": {"A": 0.75, "B": 0.63, "C": 0.57, "D": 0.5}},
display_name=''
@@ -85,21 +82,21 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
self.client.login(username=self.instructor.username, password="test")
# URL for instructor dash
- self.url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course.id)})
+ self.url = reverse('instructor_dashboard', kwargs={'course_id': str(self.course.id)})
def get_dashboard_enrollment_message(self):
"""
Returns expected dashboard enrollment message with link to Insights.
"""
- return u'Enrollment data is now available in Example.'.format(text_type(self.course.id))
+ return 'Enrollment data is now available in Example.'.format(str(self.course.id))
def get_dashboard_analytics_message(self):
"""
Returns expected dashboard demographic message with link to Insights.
"""
- return u'For analytics about your course, go to Example.'.format(text_type(self.course.id))
+ return 'For analytics about your course, go to Example.'.format(str(self.course.id))
def test_instructor_tab(self):
"""
@@ -203,7 +200,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
url = reverse(
'instructor_dashboard',
kwargs={
- 'course_id': six.text_type(self.course_info.id)
+ 'course_id': str(self.course_info.id)
}
)
@@ -237,7 +234,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
url = reverse(
'instructor_dashboard',
kwargs={
- 'course_id': six.text_type(self.course_info.id)
+ 'course_id': str(self.course_info.id)
}
)
response = self.client.get(url)
@@ -269,7 +266,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
url = reverse(
'instructor_dashboard',
kwargs={
- 'course_id': six.text_type(self.course_info.id)
+ 'course_id': str(self.course_info.id)
}
)
@@ -286,7 +283,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
url = reverse(
'instructor_dashboard',
kwargs={
- 'course_id': six.text_type(self.course_info.id)
+ 'course_id': str(self.course_info.id)
}
)
@@ -325,7 +322,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
with override_waffle_flag(waffle_flag, active=True):
response = self.client.get(self.url)
- expected_gradebook_url = 'http://gradebook.local.edx.org/{}'.format(self.course.id)
+ expected_gradebook_url = f'http://gradebook.local.edx.org/{self.course.id}'
self.assertContains(response, expected_gradebook_url)
self.assertContains(response, 'View Gradebook')
@@ -347,7 +344,7 @@ class TestInstructorDashboard(ModuleStoreTestCase, LoginEnrollmentTestCase, XssT
with override_waffle_flag(waffle_flag, active=True):
response = self.client.get(self.url)
- expected_gradebook_url = '{}/{}'.format(settings.WRITABLE_GRADEBOOK_URL, self.course.id)
+ expected_gradebook_url = f'{settings.WRITABLE_GRADEBOOK_URL}/{self.course.id}'
self.assertContains(response, expected_gradebook_url)
self.assertContains(response, 'View Gradebook')
@@ -581,7 +578,7 @@ class TestInstructorDashboardPerformance(ModuleStoreTestCase, LoginEnrollmentTes
"""
Set up tests
"""
- super(TestInstructorDashboardPerformance, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.course = CourseFactory.create(
grading_policy={"GRADE_CUTOFFS": {"A": 0.75, "B": 0.63, "C": 0.57, "D": 0.5}},
display_name='',
@@ -643,7 +640,7 @@ class TestInstructorDashboardPerformance(ModuleStoreTestCase, LoginEnrollmentTes
problem = ItemFactory.create(
category="problem",
parent=vertical,
- display_name=u"A Problem Block %d" % i,
+ display_name="A Problem Block %d" % i,
weight=1,
publish_item=False,
metadata={'rerandomize': 'always'},
diff --git a/lms/djangoapps/instructor/toggles.py b/lms/djangoapps/instructor/toggles.py
index 4fc8642e9a..042ba5424e 100644
--- a/lms/djangoapps/instructor/toggles.py
+++ b/lms/djangoapps/instructor/toggles.py
@@ -3,6 +3,7 @@ Waffle flags for instructor dashboard.
"""
from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace
+
from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag # lint-amnesty, pylint: disable=unused-import
WAFFLE_NAMESPACE = 'instructor'
diff --git a/lms/djangoapps/instructor/utils.py b/lms/djangoapps/instructor/utils.py
index 36535536f1..adc38bf1ac 100644
--- a/lms/djangoapps/instructor/utils.py
+++ b/lms/djangoapps/instructor/utils.py
@@ -8,7 +8,7 @@ from lms.djangoapps.courseware.module_render import get_module
from xmodule.modulestore.django import modulestore
-class DummyRequest(object):
+class DummyRequest:
"""Dummy request"""
META = {}
diff --git a/lms/djangoapps/instructor/views/api.py b/lms/djangoapps/instructor/views/api.py
index ffa0ce20c4..88cb6c9310 100644
--- a/lms/djangoapps/instructor/views/api.py
+++ b/lms/djangoapps/instructor/views/api.py
@@ -13,8 +13,6 @@ import random
import re
import string
-import six
-import unicodecsv
from django.conf import settings
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist, PermissionDenied, ValidationError
@@ -36,19 +34,43 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey, UsageKey
from ratelimit.decorators import ratelimit
from rest_framework import status
-from rest_framework.permissions import IsAuthenticated, IsAdminUser
+from rest_framework.permissions import IsAdminUser, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
-from six import text_type
-from six.moves import map, range
from submissions import api as sub_api # installed from the edx-submissions repository
-from lms.djangoapps.instructor_analytics import basic as instructor_analytics_basic
-from lms.djangoapps.instructor_analytics import csvs as instructor_analytics_csvs
-from lms.djangoapps.instructor_analytics import distributions as instructor_analytics_distributions # lint-amnesty, pylint: disable=unused-import
+from common.djangoapps.course_modes.models import CourseMode
+from common.djangoapps.student import auth
+from common.djangoapps.student.models import (
+ ALLOWEDTOENROLL_TO_ENROLLED,
+ ALLOWEDTOENROLL_TO_UNENROLLED,
+ DEFAULT_TRANSITION_STATE,
+ ENROLLED_TO_ENROLLED,
+ ENROLLED_TO_UNENROLLED,
+ UNENROLLED_TO_ALLOWEDTOENROLL,
+ UNENROLLED_TO_ENROLLED,
+ UNENROLLED_TO_UNENROLLED,
+ CourseEnrollment,
+ CourseEnrollmentAllowed,
+ EntranceExamConfiguration,
+ ManualEnrollmentAudit,
+ Registration,
+ UserProfile,
+ anonymous_id_for_user,
+ get_user_by_username_or_email,
+ is_email_retired,
+ unique_id_for_user
+)
+from common.djangoapps.student.roles import CourseFinanceAdminRole, CourseSalesAdminRole
+from common.djangoapps.util.file import (
+ FileValidationException,
+ course_and_time_based_filename_generator,
+ store_uploaded_file
+)
+from common.djangoapps.util.json_request import JsonResponse, JsonResponseBadRequest
+from common.djangoapps.util.views import require_global_staff
from lms.djangoapps.bulk_email.api import is_bulk_email_feature_enabled
from lms.djangoapps.bulk_email.models import CourseEmail
-from common.djangoapps.course_modes.models import CourseMode
from lms.djangoapps.certificates import api as certs_api
from lms.djangoapps.certificates.models import (
CertificateInvalidation,
@@ -77,6 +99,9 @@ from lms.djangoapps.instructor.enrollment import (
)
from lms.djangoapps.instructor.views import INVOICE_KEY
from lms.djangoapps.instructor.views.instructor_task_helpers import extract_email_features, extract_task_features
+from lms.djangoapps.instructor_analytics import basic as instructor_analytics_basic
+from lms.djangoapps.instructor_analytics import csvs as instructor_analytics_csvs
+from lms.djangoapps.instructor_analytics import distributions as instructor_analytics_distributions # lint-amnesty, pylint: disable=unused-import
from lms.djangoapps.instructor_task import api as task_api
from lms.djangoapps.instructor_task.api_helper import AlreadyRunningError, QueueConnectionError
from lms.djangoapps.instructor_task.models import ReportStore
@@ -94,40 +119,9 @@ from openedx.core.djangoapps.user_api.preferences.api import get_user_preference
from openedx.core.djangolib.markup import HTML, Text
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin
-from common.djangoapps.student import auth
-from common.djangoapps.student.models import (
- ALLOWEDTOENROLL_TO_ENROLLED,
- ALLOWEDTOENROLL_TO_UNENROLLED,
- DEFAULT_TRANSITION_STATE,
- ENROLLED_TO_ENROLLED,
- ENROLLED_TO_UNENROLLED,
- UNENROLLED_TO_ALLOWEDTOENROLL,
- UNENROLLED_TO_ENROLLED,
- UNENROLLED_TO_UNENROLLED,
- CourseEnrollment,
- CourseEnrollmentAllowed,
- EntranceExamConfiguration,
- ManualEnrollmentAudit,
- Registration,
- UserProfile,
- anonymous_id_for_user,
- get_user_by_username_or_email,
- is_email_retired,
- unique_id_for_user
-)
-from common.djangoapps.student.roles import CourseFinanceAdminRole, CourseSalesAdminRole
-from common.djangoapps.util.file import (
- FileValidationException,
- UniversalNewlineIterator,
- course_and_time_based_filename_generator,
- store_uploaded_file
-)
-from common.djangoapps.util.json_request import JsonResponse, JsonResponseBadRequest
-from common.djangoapps.util.views import require_global_staff
from xmodule.modulestore.django import modulestore
from .. import permissions
-
from .tools import (
dump_module_extensions,
dump_student_extensions,
@@ -144,7 +138,7 @@ log = logging.getLogger(__name__)
TASK_SUBMISSION_OK = 'created'
-SUCCESS_MESSAGE_TEMPLATE = _(u"The {report_type} report is being created. "
+SUCCESS_MESSAGE_TEMPLATE = _("The {report_type} report is being created. "
"To view the status of the report, see Pending Tasks below.")
@@ -164,7 +158,7 @@ def common_exceptions_400(func):
except MultipleObjectsReturned:
message = _('Found a conflict with given identifier. Please try an alternative identifier')
except (AlreadyRunningError, QueueConnectionError, AttributeError) as err:
- message = six.text_type(err)
+ message = str(err)
if use_json:
return JsonResponseBadRequest(message)
@@ -247,7 +241,7 @@ def require_sales_admin(func):
try:
course_key = CourseKey.from_string(course_id)
except InvalidKeyError:
- log.error(u"Unable to find course with course key %s", course_id)
+ log.error("Unable to find course with course key %s", course_id)
return HttpResponseNotFound()
access = auth.user_has_role(request.user, CourseSalesAdminRole(course_key))
@@ -272,7 +266,7 @@ def require_finance_admin(func):
try:
course_key = CourseKey.from_string(course_id)
except InvalidKeyError:
- log.error(u"Unable to find course with course key %s", course_id)
+ log.error("Unable to find course with course key %s", course_id)
return HttpResponseNotFound()
access = auth.user_has_role(request.user, CourseFinanceAdminRole(course_key))
@@ -362,7 +356,7 @@ def register_and_enroll_students(request, course_id): # pylint: disable=too-man
# verify that we have exactly four columns in every row but allow for blank lines
if len(student) != 4:
if student:
- error = _(u'Data in row #{row_num} must have exactly four columns: '
+ error = _('Data in row #{row_num} must have exactly four columns: '
'email, username, full name, and country').format(row_num=row_num)
general_errors.append({
'username': '',
@@ -384,7 +378,7 @@ def register_and_enroll_students(request, course_id): # pylint: disable=too-man
row_errors.append({
'username': username,
'email': email,
- 'response': _(u'Invalid email {email_address}.').format(email_address=email)
+ 'response': _('Invalid email {email_address}.').format(email_address=email)
})
else:
if User.objects.filter(email=email).exists():
@@ -396,17 +390,17 @@ def register_and_enroll_students(request, course_id): # pylint: disable=too-man
# if it's not an exact match then just display a warning message, but continue onwards
if not User.objects.filter(email=email, username=username).exists():
warning_message = _(
- u'An account with email {email} exists but the provided username {username} '
- u'is different. Enrolling anyway with {email}.'
+ 'An account with email {email} exists but the provided username {username} '
+ 'is different. Enrolling anyway with {email}.'
).format(email=email, username=username)
warnings.append({
'username': username, 'email': email, 'response': warning_message
})
- log.warning(u'email %s already exist', email)
+ log.warning('email %s already exist', email)
else:
log.info(
- u"user already exists with username '%s' and email '%s'",
+ "user already exists with username '%s' and email '%s'",
username,
email
)
@@ -433,10 +427,10 @@ def register_and_enroll_students(request, course_id): # pylint: disable=too-man
row_errors.append({
'username': username,
'email': email,
- 'response': _(u'Invalid email {email_address}.').format(email_address=email),
+ 'response': _('Invalid email {email_address}.').format(email_address=email),
})
- log.warning(u'Email address %s is associated with a retired user, so course enrollment was ' + # lint-amnesty, pylint: disable=logging-not-lazy
- u'blocked.', email)
+ log.warning('Email address %s is associated with a retired user, so course enrollment was ' + # lint-amnesty, pylint: disable=logging-not-lazy
+ 'blocked.', email)
else:
# This email does not yet exist, so we need to create a new account
# If username already exists in the database, then create_and_enroll_user
@@ -468,7 +462,7 @@ def generate_random_string(length):
char for char in string.ascii_uppercase + string.digits + string.ascii_lowercase
if char not in 'aAeEiIoOuU1l'
]
- return ''.join((random.choice(chars) for i in range(length)))
+ return ''.join(random.choice(chars) for i in range(length))
def generate_unique_password(generated_passwords, password_length=12):
@@ -527,7 +521,7 @@ def create_manual_course_enrollment(user, course_id, mode, enrolled_by, reason,
enrolled_by, user.email, state_transition, reason, enrollment_obj
)
- log.info(u'user %s enrolled in the course %s', user.username, course_id)
+ log.info('user %s enrolled in the course %s', user.username, course_id)
return enrollment_obj
@@ -571,7 +565,7 @@ def create_and_enroll_user(email, username, name, country, password, course_id,
errors.append({
'username': username,
'email': email,
- 'response': _(u'Username {user} already exists.').format(user=username)
+ 'response': _('Username {user} already exists.').format(user=username)
})
except Exception as ex: # pylint: disable=broad-except
log.exception(type(ex).__name__)
@@ -590,18 +584,18 @@ def create_and_enroll_user(email, username, name, country, password, course_id,
send_mail_to_student(email, email_params)
except Exception as ex: # pylint: disable=broad-except
log.exception(
- u"Exception '{exception}' raised while sending email to new user.".format(exception=type(ex).__name__)
+ "Exception '{exception}' raised while sending email to new user.".format(exception=type(ex).__name__)
)
errors.append({
'username': username,
'email': email,
'response':
- _(u"Error '{error}' while sending email to new user (user email={email}). "
- u"Without the email student would not be able to login. "
- u"Please contact support for further information.").format(error=type(ex).__name__, email=email),
+ _("Error '{error}' while sending email to new user (user email={email}). "
+ "Without the email student would not be able to login. "
+ "Please contact support for further information.").format(error=type(ex).__name__, email=email),
})
else:
- log.info(u'email sent to new created user at %s', email)
+ log.info('email sent to new created user at %s', email)
return errors
@@ -735,7 +729,7 @@ def students_update_enrollment(request, course_id): # lint-amnesty, pylint: dis
else:
return HttpResponseBadRequest(strip_tags(
- u"Unrecognized action '{}'".format(action)
+ f"Unrecognized action '{action}'"
))
except ValidationError:
@@ -749,7 +743,7 @@ def students_update_enrollment(request, course_id): # lint-amnesty, pylint: dis
except Exception as exc: # pylint: disable=broad-except
# catch and log any exceptions
# so that one error doesn't cause a 500.
- log.exception(u"Error while #{}ing student")
+ log.exception("Error while #{}ing student")
log.exception(exc)
results.append({
'identifier': identifier,
@@ -820,7 +814,7 @@ def bulk_beta_modify_access(request, course_id):
revoke_access(course, user, rolename)
else:
return HttpResponseBadRequest(strip_tags(
- u"Unrecognized action '{}'".format(action)
+ f"Unrecognized action '{action}'"
))
except User.DoesNotExist:
error = True
@@ -829,7 +823,7 @@ def bulk_beta_modify_access(request, course_id):
# catch and log any unexpected exceptions
# so that one error doesn't cause a 500.
except Exception as exc: # pylint: disable=broad-except
- log.exception(u"Error while #{}ing student")
+ log.exception("Error while #{}ing student")
log.exception(exc)
error = True
else:
@@ -907,7 +901,7 @@ def modify_access(request, course_id):
action = request.POST.get('action')
if rolename not in ROLES:
- error = strip_tags(u"unknown rolename '{}'".format(rolename))
+ error = strip_tags(f"unknown rolename '{rolename}'")
log.error(error)
return HttpResponseBadRequest(error)
@@ -927,7 +921,7 @@ def modify_access(request, course_id):
revoke_access(course, user, rolename)
else:
return HttpResponseBadRequest(strip_tags(
- u"unrecognized action u'{}'".format(action)
+ f"unrecognized action u'{action}'"
))
response_payload = {
@@ -984,7 +978,7 @@ def list_course_role_members(request, course_id):
}
response_payload = {
- 'course_id': text_type(course_id),
+ 'course_id': str(course_id),
rolename: list(map(extract_user_info, list_with_level(
course, rolename
))),
@@ -1082,7 +1076,7 @@ def get_grading_config(request, course_id):
grading_config_summary = instructor_analytics_basic.dump_grading_context(course)
response_payload = {
- 'course_id': text_type(course_id),
+ 'course_id': str(course_id),
'grading_config_summary': grading_config_summary,
}
return JsonResponse(response_payload)
@@ -1205,7 +1199,7 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=red
if not csv:
student_data = instructor_analytics_basic.enrolled_students_features(course_key, query_features)
response_payload = {
- 'course_id': six.text_type(course_key),
+ 'course_id': str(course_key),
'students': student_data,
'students_count': len(student_data),
'queried_features': query_features,
@@ -1254,10 +1248,7 @@ def _cohorts_csv_validator(file_storage, file_to_validate):
Verifies that the expected columns are present in the CSV used to add users to cohorts.
"""
with file_storage.open(file_to_validate) as f:
- if six.PY2:
- reader = unicodecsv.reader(UniversalNewlineIterator(f), encoding='utf-8')
- else:
- reader = csv.reader(f.read().decode('utf-8').splitlines())
+ reader = csv.reader(f.read().decode('utf-8').splitlines())
try:
fieldnames = next(reader)
@@ -1296,7 +1287,7 @@ def add_users_to_cohorts(request, course_id):
# The task will assume the default file storage.
task_api.submit_cohort_students(request, course_key, filename)
except (FileValidationException, PermissionDenied) as err:
- return JsonResponse({"error": six.text_type(err)}, status=400)
+ return JsonResponse({"error": str(err)}, status=400)
return JsonResponse()
@@ -1396,16 +1387,14 @@ def get_anon_ids(request, course_id):
def csv_response(filename, header, rows):
"""Returns a CSV http response for the given header and rows (excel/utf-8)."""
response = HttpResponse(content_type='text/csv')
- response['Content-Disposition'] = u'attachment; filename={0}'.format(
- text_type(filename).encode('utf-8') if six.PY2 else text_type(filename)
- )
+ response['Content-Disposition'] = 'attachment; filename={}'.format(str(filename))
writer = csv.writer(response, dialect='excel', quotechar='"', quoting=csv.QUOTE_ALL)
# In practice, there should not be non-ascii data in this query,
# but trying to do the right thing anyway.
- encoded = [text_type(s) for s in header]
+ encoded = [str(s) for s in header]
writer.writerow(encoded)
for row in rows:
- encoded = [text_type(s) for s in row]
+ encoded = [str(s) for s in row]
writer.writerow(encoded)
return response
@@ -1415,7 +1404,7 @@ def get_anon_ids(request, course_id):
header = ['User ID', 'Anonymized User ID', 'Course Specific Anonymized User ID']
rows = [[s.id, unique_id_for_user(s), anonymous_id_for_user(s, course_id)]
for s in students]
- return csv_response(text_type(course_id).replace('/', '-') + '-anon-ids.csv', header, rows)
+ return csv_response(str(course_id).replace('/', '-') + '-anon-ids.csv', header, rows)
@require_POST
@@ -1450,23 +1439,23 @@ def get_student_enrollment_status(request, course_id):
# records, so let the lack of a User slide.
pass
- enrollment_status = _(u'Enrollment status for {student}: unknown').format(student=unique_student_identifier)
+ enrollment_status = _('Enrollment status for {student}: unknown').format(student=unique_student_identifier)
if user and mode:
if is_active:
- enrollment_status = _(u'Enrollment status for {student}: active').format(student=user)
+ enrollment_status = _('Enrollment status for {student}: active').format(student=user)
else:
- enrollment_status = _(u'Enrollment status for {student}: inactive').format(student=user)
+ enrollment_status = _('Enrollment status for {student}: inactive').format(student=user)
else:
email = user.email if user else unique_student_identifier
allowed = CourseEnrollmentAllowed.may_enroll_and_unenrolled(course_id)
if allowed and email in [cea.email for cea in allowed]:
- enrollment_status = _(u'Enrollment status for {student}: pending').format(student=email)
+ enrollment_status = _('Enrollment status for {student}: pending').format(student=email)
else:
- enrollment_status = _(u'Enrollment status for {student}: never enrolled').format(student=email)
+ enrollment_status = _('Enrollment status for {student}: never enrolled').format(student=email)
response_payload = {
- 'course_id': text_type(course_id),
+ 'course_id': str(course_id),
'error': error,
'enrollment_status': enrollment_status
}
@@ -1496,10 +1485,10 @@ def get_student_progress_url(request, course_id):
course_id = CourseKey.from_string(course_id)
user = get_student_from_identifier(request.POST.get('unique_student_identifier'))
- progress_url = reverse('student_progress', kwargs={'course_id': text_type(course_id), 'student_id': user.id})
+ progress_url = reverse('student_progress', kwargs={'course_id': str(course_id), 'student_id': user.id})
response_payload = {
- 'course_id': text_type(course_id),
+ 'course_id': str(course_id),
'progress_url': progress_url,
}
return JsonResponse(response_payload)
@@ -1725,7 +1714,7 @@ def rescore_problem(request, course_id):
only_if_higher,
)
except NotImplementedError as exc:
- return HttpResponseBadRequest(text_type(exc))
+ return HttpResponseBadRequest(str(exc))
elif all_students:
try:
@@ -1735,7 +1724,7 @@ def rescore_problem(request, course_id):
only_if_higher,
)
except NotImplementedError as exc:
- return HttpResponseBadRequest(text_type(exc))
+ return HttpResponseBadRequest(str(exc))
else:
return HttpResponseBadRequest()
@@ -1765,16 +1754,16 @@ def override_problem_score(request, course_id): # lint-amnesty, pylint: disable
if student_identifier is not None:
student = get_student_from_identifier(student_identifier)
else:
- return _create_error_response(request, u"Invalid student ID {}.".format(student_identifier))
+ return _create_error_response(request, f"Invalid student ID {student_identifier}.")
try:
usage_key = UsageKey.from_string(problem_to_reset).map_into_course(course_key)
except InvalidKeyError:
- return _create_error_response(request, u"Unable to parse problem id {}.".format(problem_to_reset))
+ return _create_error_response(request, f"Unable to parse problem id {problem_to_reset}.")
# check the user's access to this specific problem
if not has_access(request.user, "staff", modulestore().get_item(usage_key)):
- _create_error_response(request, u"User {} does not have permission to override scores for problem {}.".format(
+ _create_error_response(request, "User {} does not have permission to override scores for problem {}.".format(
request.user.id,
problem_to_reset
))
@@ -1791,10 +1780,10 @@ def override_problem_score(request, course_id): # lint-amnesty, pylint: disable
score,
)
except NotImplementedError as exc: # if we try to override the score of a non-scorable block, catch it here
- return _create_error_response(request, text_type(exc))
+ return _create_error_response(request, str(exc))
except ValueError as exc:
- return _create_error_response(request, text_type(exc))
+ return _create_error_response(request, str(exc))
response_payload['task'] = TASK_SUBMISSION_OK
return JsonResponse(response_payload)
@@ -2004,7 +1993,7 @@ def list_report_downloads(request, course_id):
response_payload = {
'downloads': [
- dict(name=name, url=url, link=HTML(u'{}').format(HTML(url), Text(name)))
+ dict(name=name, url=url, link=HTML('{}').format(HTML(url), Text(name)))
for name, url in report_store.links_for(course_id) if report_name is None or name == report_name
]
}
@@ -2025,7 +2014,7 @@ def list_financial_report_downloads(_request, course_id):
response_payload = {
'downloads': [
- dict(name=name, url=url, link=HTML(u'{}').format(HTML(url), Text(name)))
+ dict(name=name, url=url, link=HTML('{}').format(HTML(url), Text(name)))
for name, url in report_store.links_for(course_id)
]
}
@@ -2151,7 +2140,7 @@ def list_forum_members(request, course_id):
if rolename not in [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_GROUP_MODERATOR,
FORUM_ROLE_COMMUNITY_TA]:
return HttpResponseBadRequest(strip_tags(
- u"Unrecognized rolename '{}'.".format(rolename)
+ f"Unrecognized rolename '{rolename}'."
))
try:
@@ -2176,7 +2165,7 @@ def list_forum_members(request, course_id):
}
response_payload = {
- 'course_id': text_type(course_id),
+ 'course_id': str(course_id),
rolename: list(map(extract_user_info, users)),
'division_scheme': course_discussion_settings.division_scheme,
}
@@ -2203,7 +2192,7 @@ def send_email(request, course_id):
course_id = CourseKey.from_string(course_id)
if not is_bulk_email_feature_enabled(course_id):
- log.warning(u'Email is not enabled for course %s', course_id)
+ log.warning('Email is not enabled for course %s', course_id)
return HttpResponseForbidden("Email is not enabled for this course.")
targets = json.loads(request.POST.get("send_to"))
@@ -2245,7 +2234,7 @@ def send_email(request, course_id):
from_addr=from_addr
)
except ValueError as err:
- log.exception(u'Cannot create course email for course %s requested by user %s for targets %s',
+ log.exception('Cannot create course email for course %s requested by user %s for targets %s',
course_id, request.user, targets)
return HttpResponseBadRequest(repr(err))
@@ -2253,7 +2242,7 @@ def send_email(request, course_id):
task_api.submit_bulk_course_email(request, course_id, email.id)
response_payload = {
- 'course_id': text_type(course_id),
+ 'course_id': str(course_id),
'success': True,
}
@@ -2309,7 +2298,7 @@ def update_forum_role_membership(request, course_id):
if rolename not in [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_GROUP_MODERATOR,
FORUM_ROLE_COMMUNITY_TA]:
return HttpResponseBadRequest(strip_tags(
- u"Unrecognized rolename '{}'.".format(rolename)
+ f"Unrecognized rolename '{rolename}'."
))
user = get_student_from_identifier(unique_student_identifier)
@@ -2320,7 +2309,7 @@ def update_forum_role_membership(request, course_id):
return HttpResponseBadRequest("Role does not exist.")
response_payload = {
- 'course_id': text_type(course_id),
+ 'course_id': str(course_id),
'action': action,
}
return JsonResponse(response_payload)
@@ -2347,9 +2336,9 @@ def _display_unit(unit):
"""
name = getattr(unit, 'display_name', None)
if name:
- return u'{0} ({1})'.format(name, text_type(unit.location))
+ return '{} ({})'.format(name, str(unit.location))
else:
- return text_type(unit.location)
+ return str(unit.location)
@handle_dashboard_error
@@ -2371,9 +2360,9 @@ def change_due_date(request, course_id):
set_due_date_extension(course, unit, student, due_date, request.user, reason=reason)
return JsonResponse(_(
- u'Successfully changed due date for student {0} for {1} '
- u'to {2}').format(student.profile.name, _display_unit(unit),
- due_date.strftime(u'%Y-%m-%d %H:%M')))
+ 'Successfully changed due date for student {0} for {1} '
+ 'to {2}').format(student.profile.name, _display_unit(unit),
+ due_date.strftime('%Y-%m-%d %H:%M')))
@handle_dashboard_error
@@ -2400,11 +2389,11 @@ def reset_due_date(request, course_id):
_("Successfully removed invalid due date extension (unit has no due date).")
)
- original_due_date_str = original_due_date.strftime(u'%Y-%m-%d %H:%M')
+ original_due_date_str = original_due_date.strftime('%Y-%m-%d %H:%M')
return JsonResponse(_(
- u'Successfully reset due date for student {0} for {1} '
- u'to {2}').format(student.profile.name, _display_unit(unit),
- original_due_date_str))
+ 'Successfully reset due date for student {0} for {1} '
+ 'to {2}').format(student.profile.name, _display_unit(unit),
+ original_due_date_str))
@handle_dashboard_error
@@ -2470,9 +2459,9 @@ def _instructor_dash_url(course_key, section=None):
unicode: The URL of a section in the instructor dashboard.
"""
- url = reverse('instructor_dashboard', kwargs={'course_id': six.text_type(course_key)})
+ url = reverse('instructor_dashboard', kwargs={'course_id': str(course_key)})
if section is not None:
- url += u'#view-{section}'.format(section=section)
+ url += f'#view-{section}'
return url
@@ -2526,9 +2515,9 @@ def mark_student_can_skip_entrance_exam(request, course_id):
__, created = EntranceExamConfiguration.objects.get_or_create(user=student, course_id=course_id)
if created:
- message = _(u'This student (%s) will skip the entrance exam.') % student_identifier
+ message = _('This student (%s) will skip the entrance exam.') % student_identifier
else:
- message = _(u'This student (%s) is already allowed to skip the entrance exam.') % student_identifier
+ message = _('This student (%s) is already allowed to skip the entrance exam.') % student_identifier
response_payload = {
'message': message,
}
@@ -2617,14 +2606,14 @@ def certificate_exception_view(request, course_id):
try:
certificate_exception, student = parse_request_data_and_get_user(request, course_key)
except ValueError as error:
- return JsonResponse({'success': False, 'message': text_type(error)}, status=400)
+ return JsonResponse({'success': False, 'message': str(error)}, status=400)
# Add new Certificate Exception for the student passed in request data
if request.method == 'POST':
try:
exception = add_certificate_exception(course_key, student, certificate_exception)
except ValueError as error:
- return JsonResponse({'success': False, 'message': text_type(error)}, status=400)
+ return JsonResponse({'success': False, 'message': str(error)}, status=400)
return JsonResponse(exception)
# Remove Certificate Exception for the student passed in request data
@@ -2632,7 +2621,7 @@ def certificate_exception_view(request, course_id):
try:
remove_certificate_exception(course_key, student)
except ValueError as error:
- return JsonResponse({'success': False, 'message': text_type(error)}, status=400)
+ return JsonResponse({'success': False, 'message': str(error)}, status=400)
return JsonResponse({}, status=204)
@@ -2649,7 +2638,7 @@ def add_certificate_exception(course_key, student, certificate_exception):
"""
if CertificateWhitelist.get_certificate_white_list(course_key, student):
raise ValueError(
- _(u"Student (username/email={user}) already in certificate exception list.").format(user=student.username)
+ _("Student (username/email={user}) already in certificate exception list.").format(user=student.username)
)
certificate_white_list, __ = CertificateWhitelist.objects.get_or_create(
@@ -2660,7 +2649,7 @@ def add_certificate_exception(course_key, student, certificate_exception):
'notes': certificate_exception.get('notes', '')
}
)
- log.info(u'%s has been added to the whitelist in course %s', student.username, course_key)
+ log.info('%s has been added to the whitelist in course %s', student.username, course_key)
generated_certificate = GeneratedCertificate.eligible_certificates.filter(
user=student,
@@ -2673,8 +2662,8 @@ def add_certificate_exception(course_key, student, certificate_exception):
'user_email': student.email,
'user_name': student.username,
'user_id': student.id,
- 'certificate_generated': generated_certificate and generated_certificate.created_date.strftime(u"%B %d, %Y"),
- 'created': certificate_white_list.created.strftime(u"%A, %B %d, %Y"),
+ 'certificate_generated': generated_certificate and generated_certificate.created_date.strftime("%B %d, %Y"),
+ 'created': certificate_white_list.created.strftime("%A, %B %d, %Y"),
})
return exception
@@ -2694,7 +2683,7 @@ def remove_certificate_exception(course_key, student):
certificate_exception = CertificateWhitelist.objects.get(user=student, course_id=course_key)
except ObjectDoesNotExist:
raise ValueError( # lint-amnesty, pylint: disable=raise-missing-from
- _(u'Certificate exception (user={user}) does not exist in certificate white list. '
+ _('Certificate exception (user={user}) does not exist in certificate white list. '
'Please refresh the page and try again.').format(user=student.username)
)
@@ -2705,14 +2694,14 @@ def remove_certificate_exception(course_key, student):
)
generated_certificate.invalidate()
log.info(
- u'Certificate invalidated for %s in course %s when removed from certificate exception list',
+ 'Certificate invalidated for %s in course %s when removed from certificate exception list',
student.username,
course_key
)
except ObjectDoesNotExist:
# Certificate has not been generated yet, so just remove the certificate exception from white list
pass
- log.info(u'%s has been removed from the whitelist in course %s', student.username, course_key)
+ log.info('%s has been removed from the whitelist in course %s', student.username, course_key)
certificate_exception.delete()
@@ -2744,7 +2733,7 @@ def parse_request_data(request):
:return: dict object containing parsed json data.
"""
try:
- data = json.loads(request.body.decode('utf8') or u'{}')
+ data = json.loads(request.body.decode('utf8') or '{}')
except ValueError:
raise ValueError(_('The record is not in the correct format. Please add a valid username or email address.')) # lint-amnesty, pylint: disable=raise-missing-from
@@ -2763,13 +2752,13 @@ def get_student(username_or_email, course_key):
try:
student = get_user_by_username_or_email(username_or_email)
except ObjectDoesNotExist:
- raise ValueError(_(u"{user} does not exist in the LMS. Please check your spelling and retry.").format( # lint-amnesty, pylint: disable=raise-missing-from
+ raise ValueError(_("{user} does not exist in the LMS. Please check your spelling and retry.").format( # lint-amnesty, pylint: disable=raise-missing-from
user=username_or_email
))
# Make Sure the given student is enrolled in the course
if not CourseEnrollment.is_enrolled(student, course_key):
- raise ValueError(_(u"{user} is not enrolled in this course. Please check your spelling and retry.")
+ raise ValueError(_("{user} is not enrolled in this course. Please check your spelling and retry.")
.format(user=username_or_email))
return student
@@ -2847,7 +2836,7 @@ def generate_bulk_certificate_exceptions(request, course_id):
"""
inner method to build dict of csv data as row errors.
"""
- row_errors[key].append(_(u'user "{user}" in row# {row}').format(user=_user, row=row_count))
+ row_errors[key].append(_('user "{user}" in row# {row}').format(user=_user, row=row_count))
if 'students_list' in request.FILES:
try:
@@ -2871,7 +2860,7 @@ def generate_bulk_certificate_exceptions(request, course_id):
if len(student) != 2:
if student:
build_row_errors('data_format_error', student[user_index], row_num)
- log.info(u'invalid data/format in csv row# %s', row_num)
+ log.info('invalid data/format in csv row# %s', row_num)
continue
user = student[user_index]
@@ -2879,16 +2868,16 @@ def generate_bulk_certificate_exceptions(request, course_id):
user = get_user_by_username_or_email(user)
except ObjectDoesNotExist:
build_row_errors('user_not_exist', user, row_num)
- log.info(u'student %s does not exist', user)
+ log.info('student %s does not exist', user)
else:
if CertificateWhitelist.get_certificate_white_list(course_key, user):
build_row_errors('user_already_white_listed', user, row_num)
- log.warning(u'student %s already exist.', user.username)
+ log.warning('student %s already exist.', user.username)
# make sure user is enrolled in course
elif not CourseEnrollment.is_enrolled(user, course_key):
build_row_errors('user_not_enrolled', user, row_num)
- log.warning(u'student %s is not enrolled in course.', user.username)
+ log.warning('student %s is not enrolled in course.', user.username)
else:
CertificateWhitelist.objects.create(
@@ -2897,7 +2886,7 @@ def generate_bulk_certificate_exceptions(request, course_id):
whitelist=True,
notes=student[notes_index]
)
- success.append(_(u'user "{username}" in row# {row}').format(username=user.username, row=row_num))
+ success.append(_('user "{username}" in row# {row}').format(username=user.username, row=row_num))
else:
general_errors.append(_('File is not attached.'))
@@ -2930,14 +2919,14 @@ def certificate_invalidation_view(request, course_id):
certificate_invalidation_data = parse_request_data(request)
certificate = validate_request_data_and_get_certificate(certificate_invalidation_data, course_key)
except ValueError as error:
- return JsonResponse({'message': text_type(error)}, status=400)
+ return JsonResponse({'message': str(error)}, status=400)
# Invalidate certificate of the given student for the course course
if request.method == 'POST':
try:
certificate_invalidation = invalidate_certificate(request, certificate, certificate_invalidation_data)
except ValueError as error:
- return JsonResponse({'message': text_type(error)}, status=400)
+ return JsonResponse({'message': str(error)}, status=400)
return JsonResponse(certificate_invalidation)
# Re-Validate student certificate for the course course
@@ -2945,7 +2934,7 @@ def certificate_invalidation_view(request, course_id):
try:
re_validate_certificate(request, course_key, certificate)
except ValueError as error:
- return JsonResponse({'message': text_type(error)}, status=400)
+ return JsonResponse({'message': str(error)}, status=400)
return JsonResponse({}, status=204)
@@ -2964,7 +2953,7 @@ def invalidate_certificate(request, generated_certificate, certificate_invalidat
generated_certificate.user,
):
raise ValueError(
- _(u"Certificate of {user} has already been invalidated. Please check your spelling and retry.").format(
+ _("Certificate of {user} has already been invalidated. Please check your spelling and retry.").format(
user=generated_certificate.user.username,
)
)
@@ -2972,7 +2961,7 @@ def invalidate_certificate(request, generated_certificate, certificate_invalidat
# Verify that certificate user wants to invalidate is a valid one.
if not generated_certificate.is_valid():
raise ValueError(
- _(u"Certificate for student {user} is already invalid, kindly verify that certificate was generated "
+ _("Certificate for student {user} is already invalid, kindly verify that certificate was generated "
"for this student and then proceed.").format(user=generated_certificate.user.username)
)
@@ -2992,7 +2981,7 @@ def invalidate_certificate(request, generated_certificate, certificate_invalidat
'id': certificate_invalidation.id,
'user': certificate_invalidation.generated_certificate.user.username,
'invalidated_by': certificate_invalidation.invalidated_by.username,
- 'created': certificate_invalidation.created.strftime(u"%B %d, %Y"),
+ 'created': certificate_invalidation.created.strftime("%B %d, %Y"),
'notes': certificate_invalidation.notes,
}
@@ -3048,7 +3037,7 @@ def validate_request_data_and_get_certificate(certificate_invalidation, course_k
certificate = GeneratedCertificate.certificate_for_student(student, course_key)
if not certificate:
raise ValueError(_(
- u"The student {student} does not have certificate for the course {course}. Kindly verify student "
+ "The student {student} does not have certificate for the course {course}. Kindly verify student "
"username/email and the selected course are correct and try again."
).format(student=student.username, course=course_key.course))
return certificate
diff --git a/lms/djangoapps/instructor/views/gradebook_api.py b/lms/djangoapps/instructor/views/gradebook_api.py
index fb61ecdf1b..dcdfb2e1a9 100644
--- a/lms/djangoapps/instructor/views/gradebook_api.py
+++ b/lms/djangoapps/instructor/views/gradebook_api.py
@@ -12,8 +12,8 @@ from django.urls import reverse
from django.views.decorators.cache import cache_control
from opaque_keys.edx.keys import CourseKey
-from lms.djangoapps.courseware.courses import get_course_with_access
from common.djangoapps.edxmako.shortcuts import render_to_response
+from lms.djangoapps.courseware.courses import get_course_with_access
from lms.djangoapps.grades.api import CourseGradeFactory
from lms.djangoapps.instructor.views.api import require_course_permission
from xmodule.modulestore.django import modulestore
diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py
index 9286e719e8..29d83fdb9e 100644
--- a/lms/djangoapps/instructor/views/instructor_dashboard.py
+++ b/lms/djangoapps/instructor/views/instructor_dashboard.py
@@ -7,9 +7,9 @@ import datetime
import logging
import uuid
from functools import reduce
+from unittest.mock import patch
import pytz
-import six
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import Http404, HttpResponseServerError
@@ -22,17 +22,23 @@ from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_POST
from edx_proctoring.api import does_backend_support_onboarding
from edx_when.api import is_enabled_for_course
-from mock import patch
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
-from six import text_type
from six.moves.urllib.parse import urljoin # lint-amnesty, pylint: disable=unused-import
from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds
-from lms.djangoapps.bulk_email.api import is_bulk_email_feature_enabled
from common.djangoapps.course_modes.models import CourseMode, CourseModesArchive
from common.djangoapps.edxmako.shortcuts import render_to_response
+from common.djangoapps.student.models import CourseEnrollment
+from common.djangoapps.student.roles import (
+ CourseFinanceAdminRole,
+ CourseInstructorRole,
+ CourseSalesAdminRole,
+ CourseStaffRole
+)
+from common.djangoapps.util.json_request import JsonResponse
+from lms.djangoapps.bulk_email.api import is_bulk_email_feature_enabled
from lms.djangoapps.certificates import api as certs_api
from lms.djangoapps.certificates.models import (
CertificateGenerationConfiguration,
@@ -55,19 +61,13 @@ from openedx.core.djangoapps.verified_track_content.models import VerifiedTrackC
from openedx.core.djangolib.markup import HTML, Text
from openedx.core.lib.url_utils import quote_slashes
from openedx.core.lib.xblock_utils import wrap_xblock
-from common.djangoapps.student.models import CourseEnrollment
-from common.djangoapps.student.roles import (
- CourseFinanceAdminRole, CourseInstructorRole,
- CourseSalesAdminRole, CourseStaffRole
-)
-from common.djangoapps.util.json_request import JsonResponse
from xmodule.html_module import HtmlBlock
from xmodule.modulestore.django import modulestore
from xmodule.tabs import CourseTab
-from .tools import get_units_with_due_date, title_or_url
from .. import permissions
from ..toggles import data_download_v2_is_enabled
+from .tools import get_units_with_due_date, title_or_url
log = logging.getLogger(__name__)
@@ -111,7 +111,7 @@ def instructor_dashboard_2(request, course_id): # lint-amnesty, pylint: disable
try:
course_key = CourseKey.from_string(course_id)
except InvalidKeyError:
- log.error(u"Unable to find course with course key %s while loading the Instructor Dashboard.", course_id)
+ log.error("Unable to find course with course key %s while loading the Instructor Dashboard.", course_id)
return HttpResponseServerError()
course = get_course_by_id(course_key, depth=0)
@@ -148,11 +148,11 @@ def instructor_dashboard_2(request, course_id): # lint-amnesty, pylint: disable
analytics_dashboard_message = None
if show_analytics_dashboard_message(course_key) and (access['staff'] or access['instructor']):
# Construct a URL to the external analytics dashboard
- analytics_dashboard_url = '{0}/courses/{1}'.format(settings.ANALYTICS_DASHBOARD_URL, six.text_type(course_key))
- link_start = HTML(u"").format(analytics_dashboard_url)
+ analytics_dashboard_url = '{}/courses/{}'.format(settings.ANALYTICS_DASHBOARD_URL, str(course_key))
+ link_start = HTML("").format(analytics_dashboard_url)
analytics_dashboard_message = _(
- u"To gain insights into student enrollment and participation {link_start}"
- u"visit {analytics_dashboard_name}, our new course analytics product{link_end}."
+ "To gain insights into student enrollment and participation {link_start}"
+ "visit {analytics_dashboard_name}, our new course analytics product{link_end}."
)
analytics_dashboard_message = Text(analytics_dashboard_message).format(
link_start=link_start, link_end=HTML(""), analytics_dashboard_name=settings.ANALYTICS_DASHBOARD_NAME)
@@ -167,9 +167,9 @@ def instructor_dashboard_2(request, course_id): # lint-amnesty, pylint: disable
course_mode_has_price = True
elif len(paid_modes) > 1:
log.error(
- u"Course %s has %s course modes with payment options. Course must only have "
- u"one paid course mode to enable eCommerce options.",
- six.text_type(course_key), len(paid_modes)
+ "Course %s has %s course modes with payment options. Course must only have "
+ "one paid course mode to enable eCommerce options.",
+ str(course_key), len(paid_modes)
)
if access['instructor'] and is_enabled_for_course(course_key):
@@ -216,20 +216,20 @@ def instructor_dashboard_2(request, course_id): # lint-amnesty, pylint: disable
certificate_white_list = CertificateWhitelist.get_certificate_white_list(course_key)
generate_certificate_exceptions_url = reverse(
'generate_certificate_exceptions',
- kwargs={'course_id': six.text_type(course_key), 'generate_for': ''}
+ kwargs={'course_id': str(course_key), 'generate_for': ''}
)
generate_bulk_certificate_exceptions_url = reverse(
'generate_bulk_certificate_exceptions',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
)
certificate_exception_view_url = reverse(
'certificate_exception_view',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
)
certificate_invalidation_view_url = reverse(
'certificate_invalidation_view',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
)
certificate_invalidations = CertificateInvalidation.get_certificate_invalidations(course_key)
@@ -264,7 +264,7 @@ def instructor_dashboard_2(request, course_id): # lint-amnesty, pylint: disable
def _section_special_exams(course, access):
""" Provide data for the corresponding dashboard section """
- course_key = six.text_type(course.id)
+ course_key = str(course.id)
proctoring_provider = course.proctoring_provider
escalation_email = None
if proctoring_provider == 'proctortrack':
@@ -383,7 +383,7 @@ def set_course_mode_price(request, course_id):
course_honor_mode = CourseMode.objects.filter(mode_slug='honor', course_id=course_key)
if not course_honor_mode:
return JsonResponse(
- {'message': _(u"CourseMode with the mode slug({mode_slug}) DoesNotExist").format(mode_slug='honor')},
+ {'message': _("CourseMode with the mode slug({mode_slug}) DoesNotExist").format(mode_slug='honor')},
status=400) # status code 400: Bad Request
CourseModesArchive.objects.create(
@@ -415,7 +415,7 @@ def _section_course_info(course, access):
'start_date': course.start,
'end_date': course.end,
'num_sections': len(course.children),
- 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': six.text_type(course_key)}),
+ 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': str(course_key)}),
}
if settings.FEATURES.get('DISPLAY_ANALYTICS_ENROLLMENTS'):
@@ -426,19 +426,19 @@ def _section_course_info(course, access):
dashboard_link = _get_dashboard_link(course_key)
# so we can use Text() here so it's not double-escaped and rendering HTML on the front-end
message = Text(
- _(u"Enrollment data is now available in {dashboard_link}.")
+ _("Enrollment data is now available in {dashboard_link}.")
).format(dashboard_link=dashboard_link)
section_data['enrollment_message'] = message
if settings.FEATURES.get('ENABLE_SYSADMIN_DASHBOARD'):
section_data['detailed_gitlogs_url'] = reverse(
'gitlogs_detail',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
)
try:
sorted_cutoffs = sorted(list(course.grade_cutoffs.items()), key=lambda i: i[1], reverse=True)
- advance = lambda memo, letter_score_tuple: u"{}: {}, ".format(letter_score_tuple[0], letter_score_tuple[1]) \
+ advance = lambda memo, letter_score_tuple: "{}: {}, ".format(letter_score_tuple[0], letter_score_tuple[1]) \
+ memo
section_data['grade_cutoffs'] = reduce(advance, sorted_cutoffs, "")[:-2]
except Exception: # pylint: disable=broad-except
@@ -464,25 +464,25 @@ def _section_membership(course, access):
'section_display_name': _('Membership'),
'access': access,
'ccx_is_enabled': ccx_enabled,
- 'enroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': six.text_type(course_key)}),
- 'unenroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': six.text_type(course_key)}),
+ 'enroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': str(course_key)}),
+ 'unenroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': str(course_key)}),
'upload_student_csv_button_url': reverse(
'register_and_enroll_students',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
),
'modify_beta_testers_button_url': reverse(
'bulk_beta_modify_access',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
),
'list_course_role_members_url': reverse(
'list_course_role_members',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
),
- 'modify_access_url': reverse('modify_access', kwargs={'course_id': six.text_type(course_key)}),
- 'list_forum_members_url': reverse('list_forum_members', kwargs={'course_id': six.text_type(course_key)}),
+ 'modify_access_url': reverse('modify_access', kwargs={'course_id': str(course_key)}),
+ 'list_forum_members_url': reverse('list_forum_members', kwargs={'course_id': str(course_key)}),
'update_forum_role_membership_url': reverse(
'update_forum_role_membership',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
),
'enrollment_role_choices': enrollment_role_choices,
'is_reason_field_enabled': configuration_helpers.get_value('ENABLE_MANUAL_ENROLLMENT_REASON_FIELD', False)
@@ -501,12 +501,12 @@ def _section_cohort_management(course, access):
'ccx_is_enabled': ccx_enabled,
'course_cohort_settings_url': reverse(
'course_cohort_settings',
- kwargs={'course_key_string': six.text_type(course_key)}
+ kwargs={'course_key_string': str(course_key)}
),
- 'cohorts_url': reverse('cohorts', kwargs={'course_key_string': six.text_type(course_key)}),
- 'upload_cohorts_csv_url': reverse('add_users_to_cohorts', kwargs={'course_id': six.text_type(course_key)}),
+ 'cohorts_url': reverse('cohorts', kwargs={'course_key_string': str(course_key)}),
+ 'upload_cohorts_csv_url': reverse('add_users_to_cohorts', kwargs={'course_id': str(course_key)}),
'verified_track_cohorting_url': reverse(
- 'verified_track_cohorting', kwargs={'course_key_string': six.text_type(course_key)}
+ 'verified_track_cohorting', kwargs={'course_key_string': str(course_key)}
),
}
return section_data
@@ -521,10 +521,10 @@ def _section_discussions_management(course, access): # lint-amnesty, pylint: di
'section_display_name': _('Discussions'),
'is_hidden': (not is_course_cohorted(course_key) and
CourseDiscussionSettings.ENROLLMENT_TRACK not in enrollment_track_schemes),
- 'discussion_topics_url': reverse('discussion_topics', kwargs={'course_key_string': six.text_type(course_key)}),
+ 'discussion_topics_url': reverse('discussion_topics', kwargs={'course_key_string': str(course_key)}),
'course_discussion_settings': reverse(
'course_discussions_settings',
- kwargs={'course_key_string': six.text_type(course_key)}
+ kwargs={'course_key_string': str(course_key)}
),
}
return section_data
@@ -542,40 +542,40 @@ def _section_student_admin(course, access):
'is_small_course': is_small_course,
'get_student_enrollment_status_url': reverse(
'get_student_enrollment_status',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
),
'get_student_progress_url_url': reverse(
'get_student_progress_url',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
),
- 'enrollment_url': reverse('students_update_enrollment', kwargs={'course_id': six.text_type(course_key)}),
+ 'enrollment_url': reverse('students_update_enrollment', kwargs={'course_id': str(course_key)}),
'reset_student_attempts_url': reverse(
'reset_student_attempts',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
),
'reset_student_attempts_for_entrance_exam_url': reverse(
'reset_student_attempts_for_entrance_exam',
- kwargs={'course_id': six.text_type(course_key)},
+ kwargs={'course_id': str(course_key)},
),
- 'rescore_problem_url': reverse('rescore_problem', kwargs={'course_id': six.text_type(course_key)}),
+ 'rescore_problem_url': reverse('rescore_problem', kwargs={'course_id': str(course_key)}),
'override_problem_score_url': reverse(
'override_problem_score',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
),
- 'rescore_entrance_exam_url': reverse('rescore_entrance_exam', kwargs={'course_id': six.text_type(course_key)}),
+ 'rescore_entrance_exam_url': reverse('rescore_entrance_exam', kwargs={'course_id': str(course_key)}),
'student_can_skip_entrance_exam_url': reverse(
'mark_student_can_skip_entrance_exam',
- kwargs={'course_id': six.text_type(course_key)},
+ kwargs={'course_id': str(course_key)},
),
- 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': six.text_type(course_key)}),
+ 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': str(course_key)}),
'list_entrace_exam_instructor_tasks_url': reverse(
'list_entrance_exam_instructor_tasks',
- kwargs={'course_id': six.text_type(course_key)}
+ kwargs={'course_id': str(course_key)}
),
- 'spoc_gradebook_url': reverse('spoc_gradebook', kwargs={'course_id': six.text_type(course_key)}),
+ 'spoc_gradebook_url': reverse('spoc_gradebook', kwargs={'course_id': str(course_key)}),
}
if is_writable_gradebook_enabled(course_key) and settings.WRITABLE_GRADEBOOK_URL:
- section_data['writable_gradebook_url'] = '{}/{}'.format(settings.WRITABLE_GRADEBOOK_URL, text_type(course_key))
+ section_data['writable_gradebook_url'] = '{}/{}'.format(settings.WRITABLE_GRADEBOOK_URL, str(course_key))
return section_data
@@ -584,14 +584,14 @@ def _section_extensions(course):
section_data = {
'section_key': 'extensions',
'section_display_name': _('Extensions'),
- 'units_with_due_dates': [(title_or_url(unit), six.text_type(unit.location))
+ 'units_with_due_dates': [(title_or_url(unit), str(unit.location))
for unit in get_units_with_due_date(course)],
- 'change_due_date_url': reverse('change_due_date', kwargs={'course_id': six.text_type(course.id)}),
- 'reset_due_date_url': reverse('reset_due_date', kwargs={'course_id': six.text_type(course.id)}),
- 'show_unit_extensions_url': reverse('show_unit_extensions', kwargs={'course_id': six.text_type(course.id)}),
+ 'change_due_date_url': reverse('change_due_date', kwargs={'course_id': str(course.id)}),
+ 'reset_due_date_url': reverse('reset_due_date', kwargs={'course_id': str(course.id)}),
+ 'show_unit_extensions_url': reverse('show_unit_extensions', kwargs={'course_id': str(course.id)}),
'show_student_extensions_url': reverse(
'show_student_extensions',
- kwargs={'course_id': six.text_type(course.id)}
+ kwargs={'course_id': str(course.id)}
),
}
return section_data
@@ -611,30 +611,30 @@ def _section_data_download(course, access):
'section_display_name': _('Data Download'),
'access': access,
'show_generate_proctored_exam_report_button': show_proctored_report_button,
- 'get_problem_responses_url': reverse('get_problem_responses', kwargs={'course_id': six.text_type(course_key)}),
- 'get_grading_config_url': reverse('get_grading_config', kwargs={'course_id': six.text_type(course_key)}),
- 'get_students_features_url': reverse('get_students_features', kwargs={'course_id': six.text_type(course_key)}),
+ 'get_problem_responses_url': reverse('get_problem_responses', kwargs={'course_id': str(course_key)}),
+ 'get_grading_config_url': reverse('get_grading_config', kwargs={'course_id': str(course_key)}),
+ 'get_students_features_url': reverse('get_students_features', kwargs={'course_id': str(course_key)}),
'get_issued_certificates_url': reverse(
- 'get_issued_certificates', kwargs={'course_id': six.text_type(course_key)}
+ 'get_issued_certificates', kwargs={'course_id': str(course_key)}
),
'get_students_who_may_enroll_url': reverse(
- 'get_students_who_may_enroll', kwargs={'course_id': six.text_type(course_key)}
+ 'get_students_who_may_enroll', kwargs={'course_id': str(course_key)}
),
- 'get_anon_ids_url': reverse('get_anon_ids', kwargs={'course_id': six.text_type(course_key)}),
+ 'get_anon_ids_url': reverse('get_anon_ids', kwargs={'course_id': str(course_key)}),
'list_proctored_results_url': reverse(
- 'get_proctored_exam_results', kwargs={'course_id': six.text_type(course_key)}
+ 'get_proctored_exam_results', kwargs={'course_id': str(course_key)}
),
- 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': six.text_type(course_key)}),
- 'list_report_downloads_url': reverse('list_report_downloads', kwargs={'course_id': six.text_type(course_key)}),
- 'calculate_grades_csv_url': reverse('calculate_grades_csv', kwargs={'course_id': six.text_type(course_key)}),
- 'problem_grade_report_url': reverse('problem_grade_report', kwargs={'course_id': six.text_type(course_key)}),
+ 'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': str(course_key)}),
+ 'list_report_downloads_url': reverse('list_report_downloads', kwargs={'course_id': str(course_key)}),
+ 'calculate_grades_csv_url': reverse('calculate_grades_csv', kwargs={'course_id': str(course_key)}),
+ 'problem_grade_report_url': reverse('problem_grade_report', kwargs={'course_id': str(course_key)}),
'course_has_survey': True if course.course_survey_name else False, # lint-amnesty, pylint: disable=simplifiable-if-expression
'course_survey_results_url': reverse(
- 'get_course_survey_results', kwargs={'course_id': six.text_type(course_key)}
+ 'get_course_survey_results', kwargs={'course_id': str(course_key)}
),
- 'export_ora2_data_url': reverse('export_ora2_data', kwargs={'course_id': six.text_type(course_key)}),
+ 'export_ora2_data_url': reverse('export_ora2_data', kwargs={'course_id': str(course_key)}),
'export_ora2_submission_files_url': reverse(
- 'export_ora2_submission_files', kwargs={'course_id': six.text_type(course_key)}
+ 'export_ora2_submission_files', kwargs={'course_id': str(course_key)}
),
}
if not access.get('data_researcher'):
@@ -666,8 +666,8 @@ def _section_send_email(course, access):
fragment = course.system.render(html_module, 'studio_view')
fragment = wrap_xblock(
'LmsRuntime', html_module, 'studio_view', fragment, None,
- extra_data={"course-id": six.text_type(course_key)},
- usage_id_serializer=lambda usage_id: quote_slashes(six.text_type(usage_id)),
+ extra_data={"course-id": str(course_key)},
+ usage_id_serializer=lambda usage_id: quote_slashes(str(usage_id)),
# Generate a new request_token here at random, because this module isn't connected to any other
# xblock rendering.
request_token=uuid.uuid1().hex
@@ -683,19 +683,19 @@ def _section_send_email(course, access):
'section_key': 'send_email',
'section_display_name': _('Email'),
'access': access,
- 'send_email': reverse('send_email', kwargs={'course_id': six.text_type(course_key)}),
+ 'send_email': reverse('send_email', kwargs={'course_id': str(course_key)}),
'editor': email_editor,
'cohorts': cohorts,
'course_modes': course_modes,
'default_cohort_name': DEFAULT_COHORT_NAME,
'list_instructor_tasks_url': reverse(
- 'list_instructor_tasks', kwargs={'course_id': six.text_type(course_key)}
+ 'list_instructor_tasks', kwargs={'course_id': str(course_key)}
),
'email_background_tasks_url': reverse(
- 'list_background_email_tasks', kwargs={'course_id': six.text_type(course_key)}
+ 'list_background_email_tasks', kwargs={'course_id': str(course_key)}
),
'email_content_history_url': reverse(
- 'list_email_content', kwargs={'course_id': six.text_type(course_key)}
+ 'list_email_content', kwargs={'course_id': str(course_key)}
),
}
return section_data
@@ -703,8 +703,8 @@ def _section_send_email(course, access):
def _get_dashboard_link(course_key):
""" Construct a URL to the external analytics dashboard """
- analytics_dashboard_url = u'{0}/courses/{1}'.format(settings.ANALYTICS_DASHBOARD_URL, six.text_type(course_key))
- link = HTML(u"{1}").format(
+ analytics_dashboard_url = '{}/courses/{}'.format(settings.ANALYTICS_DASHBOARD_URL, str(course_key))
+ link = HTML("{1}").format(
analytics_dashboard_url, settings.ANALYTICS_DASHBOARD_NAME
)
return link
@@ -716,7 +716,7 @@ def _section_analytics(course, access):
'section_key': 'instructor_analytics',
'section_display_name': _('Analytics'),
'access': access,
- 'course_id': six.text_type(course.id),
+ 'course_id': str(course.id),
}
return section_data
@@ -729,8 +729,8 @@ def _section_open_response_assessment(request, course, openassessment_blocks, ac
parents = {}
for block in openassessment_blocks:
- block_parent_id = six.text_type(block.parent)
- result_item_id = six.text_type(block.location)
+ block_parent_id = str(block.parent)
+ result_item_id = str(block.location)
if block_parent_id not in parents:
parents[block_parent_id] = modulestore().get_item(block.parent)
assessment_name = _("Team") + " : " + block.display_name if block.teams_enabled else block.display_name
@@ -747,7 +747,7 @@ def _section_open_response_assessment(request, course, openassessment_blocks, ac
openassessment_block = openassessment_blocks[0]
block, __ = get_module_by_usage_id(
- request, six.text_type(course_key), six.text_type(openassessment_block.location),
+ request, str(course_key), str(openassessment_block.location),
disable_staff_debug_info=True, course=course
)
section_data = {
@@ -758,7 +758,7 @@ def _section_open_response_assessment(request, course, openassessment_blocks, ac
'section_key': 'open_response_assessment',
'section_display_name': _('Open Responses'),
'access': access,
- 'course_id': six.text_type(course_key),
+ 'course_id': str(course_key),
}
return section_data
diff --git a/lms/djangoapps/instructor/views/instructor_task_helpers.py b/lms/djangoapps/instructor/views/instructor_task_helpers.py
index e7eb12d234..7ea28b10fd 100644
--- a/lms/djangoapps/instructor/views/instructor_task_helpers.py
+++ b/lms/djangoapps/instructor/views/instructor_task_helpers.py
@@ -7,13 +7,12 @@ tasks.
import json
import logging
-import six
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
+from common.djangoapps.util.date_utils import get_default_time_display
from lms.djangoapps.bulk_email.models import CourseEmail
from lms.djangoapps.instructor_task.views import get_task_completion_info
-from common.djangoapps.util.date_utils import get_default_time_display
log = logging.getLogger(__name__)
@@ -56,7 +55,7 @@ def extract_email_features(email_task):
try:
task_input_information = json.loads(email_task.task_input)
except ValueError:
- log.error(u"Could not parse task input as valid json; task input: %s", email_task.task_input)
+ log.error("Could not parse task input as valid json; task input: %s", email_task.task_input)
return email_error_information()
email = CourseEmail.objects.get(id=task_input_information['email_id'])
@@ -66,7 +65,7 @@ def extract_email_features(email_task):
'requester': str(email_task.requester),
}
features = ['subject', 'html_message', 'id']
- email_info = {feature: six.text_type(getattr(email, feature)) for feature in features}
+ email_info = {feature: str(getattr(email, feature)) for feature in features}
# Pass along email as an object with the information we desire
email_feature_dict['email'] = email_info
@@ -77,13 +76,13 @@ def extract_email_features(email_task):
try:
task_output = json.loads(email_task.task_output)
except ValueError:
- log.error(u"Could not parse task output as valid json; task output: %s", email_task.task_output)
+ log.error("Could not parse task output as valid json; task output: %s", email_task.task_output)
else:
if 'succeeded' in task_output and task_output['succeeded'] > 0:
num_emails = task_output['succeeded']
number_sent = ungettext(
- u"{num_emails} sent",
- u"{num_emails} sent",
+ "{num_emails} sent",
+ "{num_emails} sent",
num_emails
).format(num_emails=num_emails)
@@ -91,8 +90,8 @@ def extract_email_features(email_task):
num_emails = task_output['failed']
number_sent += ", "
number_sent += ungettext(
- u"{num_emails} failed",
- u"{num_emails} failed",
+ "{num_emails} failed",
+ "{num_emails} failed",
num_emails
).format(num_emails=num_emails)
@@ -124,7 +123,7 @@ def extract_task_features(task):
try:
task_output = json.loads(task.task_output)
except ValueError:
- log.error(u"Could not parse task output as valid json; task output: %s", task.task_output)
+ log.error("Could not parse task output as valid json; task output: %s", task.task_output)
else:
if 'duration_ms' in task_output:
duration_sec = int(task_output['duration_ms'] / 1000.0)
diff --git a/lms/djangoapps/instructor/views/tools.py b/lms/djangoapps/instructor/views/tools.py
index cca5b91778..ea40d4d536 100644
--- a/lms/djangoapps/instructor/views/tools.py
+++ b/lms/djangoapps/instructor/views/tools.py
@@ -7,18 +7,15 @@ import json
import operator
import dateutil
-import six
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.http import HttpResponseBadRequest
from django.utils.translation import ugettext as _
from edx_when import api
from opaque_keys.edx.keys import UsageKey
from pytz import UTC
-from six import string_types, text_type
-from six.moves import zip
+from common.djangoapps.student.models import CourseEnrollment, get_user_by_username_or_email
from openedx.core.djangoapps.schedules.models import Schedule
-from common.djangoapps.student.models import get_user_by_username_or_email, CourseEnrollment
class DashboardError(Exception):
@@ -29,7 +26,7 @@ class DashboardError(Exception):
"""
Generate an instance of HttpResponseBadRequest for this error.
"""
- error = six.text_type(self)
+ error = str(self)
return HttpResponseBadRequest(json.dumps({'error': error}))
@@ -52,7 +49,7 @@ def handle_dashboard_error(view):
def strip_if_string(value):
- if isinstance(value, string_types):
+ if isinstance(value, str):
return value.strip()
return value
@@ -80,7 +77,7 @@ def require_student_from_identifier(unique_student_identifier):
return get_student_from_identifier(unique_student_identifier)
except User.DoesNotExist:
raise DashboardError( # lint-amnesty, pylint: disable=raise-missing-from
- _(u"Could not find student matching identifier: {student_identifier}").format(
+ _("Could not find student matching identifier: {student_identifier}").format(
student_identifier=unique_student_identifier
)
)
@@ -107,7 +104,7 @@ def find_unit(course, url):
"""
Find node in course tree for url.
"""
- if text_type(node.location) == url:
+ if str(node.location) == url:
return node
for child in node.get_children():
found = find(child, url)
@@ -117,7 +114,7 @@ def find_unit(course, url):
unit = find(course, url)
if unit is None:
- raise DashboardError(_(u"Couldn't find module for url: {0}").format(url))
+ raise DashboardError(_("Couldn't find module for url: {0}").format(url))
return unit
@@ -157,7 +154,7 @@ def title_or_url(node):
"""
title = getattr(node, 'display_name', None)
if not title:
- title = text_type(node.location)
+ title = str(node.location)
return title
@@ -169,7 +166,7 @@ def set_due_date_extension(course, unit, student, due_date, actor=None, reason='
DashboardError if the unit or extended, due date is invalid or user is
not enrolled in the course.
"""
- mode, __ = CourseEnrollment.enrollment_mode_for_user(user=student, course_id=six.text_type(course.id))
+ mode, __ = CourseEnrollment.enrollment_mode_for_user(user=student, course_id=str(course.id))
if not mode:
raise DashboardError(_("Could not find student enrollment in the course."))
@@ -196,10 +193,10 @@ def set_due_date_extension(course, unit, student, due_date, actor=None, reason='
try:
api.set_date_for_block(course.id, block.location, 'due', due_date, user=student, reason=reason,
actor=actor)
- except api.MissingDateError:
- raise DashboardError(_(u"Unit {0} has no due date to extend.").format(unit.location))
- except api.InvalidDateError:
- raise DashboardError(_("An extended due date must be later than the original due date."))
+ except api.MissingDateError as ex:
+ raise DashboardError(_("Unit {0} has no due date to extend.").format(unit.location)) from ex
+ except api.InvalidDateError as ex:
+ raise DashboardError(_("An extended due date must be later than the original due date.")) from ex
else:
api.set_date_for_block(course.id, block.location, 'due', None, user=student, reason=reason, actor=actor)
@@ -212,12 +209,12 @@ def dump_module_extensions(course, unit):
header = [_("Username"), _("Full Name"), _("Extended Due Date")]
data = []
for username, fullname, due_date in api.get_overrides_for_block(course.id, unit.location):
- due_date = due_date.strftime(u'%Y-%m-%d %H:%M')
+ due_date = due_date.strftime('%Y-%m-%d %H:%M')
data.append(dict(list(zip(header, (username, fullname, due_date)))))
data.sort(key=operator.itemgetter(_("Username")))
return {
"header": header,
- "title": _(u"Users with due date extensions for {0}").format(
+ "title": _("Users with due date extensions for {0}").format(
title_or_url(unit)),
"data": data
}
@@ -238,13 +235,13 @@ def dump_student_extensions(course, student):
if location not in units:
continue
due = override['actual_date']
- due = due.strftime(u"%Y-%m-%d %H:%M")
+ due = due.strftime("%Y-%m-%d %H:%M")
title = title_or_url(units[location])
data.append(dict(list(zip(header, (title, due)))))
data.sort(key=operator.itemgetter(_("Unit")))
return {
"header": header,
- "title": _(u"Due date extensions for {0} {1} ({2})").format(
+ "title": _("Due date extensions for {0} {1} ({2})").format(
student.first_name, student.last_name, student.username),
"data": data}