BOM-2375-student-part2

pyupgrade in student app.
This commit is contained in:
Awais Qureshi
2021-03-08 18:31:36 +05:00
parent ba4708edd0
commit 094573e901
38 changed files with 499 additions and 510 deletions

View File

@@ -61,7 +61,7 @@ User = get_user_model() # pylint:disable=invalid-name
COURSE_ENROLLMENT_ADMIN_SWITCH = WaffleSwitch('student.courseenrollment_admin', __name__)
class _Check(object):
class _Check:
"""
A method decorator that pre-emptively returns false if a feature is disabled.
Otherwise, it returns the return value of the decorated method.
@@ -128,7 +128,7 @@ class DisableEnrollmentAdminMixin:
class CourseAccessRoleForm(forms.ModelForm):
"""Form for adding new Course Access Roles view the Django Admin Panel."""
class Meta(object):
class Meta:
model = CourseAccessRole
fields = '__all__'
@@ -152,7 +152,7 @@ class CourseAccessRoleForm(forms.ModelForm):
org_name = self.cleaned_data.get('course_id').org
if org.lower() != org_name.lower():
raise forms.ValidationError(
u"Org name {} is not valid. Valid name is {}.".format(
"Org name {} is not valid. Valid name is {}.".format(
org, org_name
)
)
@@ -168,7 +168,7 @@ class CourseAccessRoleForm(forms.ModelForm):
user = User.objects.get(email=email)
except Exception:
raise forms.ValidationError( # lint-amnesty, pylint: disable=raise-missing-from
u"Email does not exist. Could not find {email}. Please re-enter email address".format(
"Email does not exist. Could not find {email}. Please re-enter email address".format(
email=email
)
)
@@ -179,7 +179,7 @@ class CourseAccessRoleForm(forms.ModelForm):
"""
Checking the course already exists in db.
"""
cleaned_data = super(CourseAccessRoleForm, self).clean() # lint-amnesty, pylint: disable=super-with-arguments
cleaned_data = super().clean()
if not self.errors:
if CourseAccessRole.objects.filter(
user=cleaned_data.get("email"),
@@ -192,7 +192,7 @@ class CourseAccessRoleForm(forms.ModelForm):
return cleaned_data
def __init__(self, *args, **kwargs):
super(CourseAccessRoleForm, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
if self.instance.user_id:
self.fields['email'].initial = self.instance.user.email
@@ -219,14 +219,14 @@ class CourseAccessRoleAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = form.cleaned_data['email']
super(CourseAccessRoleAdmin, self).save_model(request, obj, form, change) # lint-amnesty, pylint: disable=super-with-arguments
super().save_model(request, obj, form, change)
@admin.register(LinkedInAddToProfileConfiguration)
class LinkedInAddToProfileConfigurationAdmin(admin.ModelAdmin):
"""Admin interface for the LinkedIn Add to Profile configuration. """
class Meta(object):
class Meta:
model = LinkedInAddToProfileConfiguration
@@ -243,7 +243,7 @@ class CourseEnrollmentForm(forms.ModelForm):
raise forms.ValidationError("Cannot make a valid CourseKey from id {}!".format(args_copy['course'])) # lint-amnesty, pylint: disable=raise-missing-from
args = [args_copy]
super(CourseEnrollmentForm, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
if self.data.get('course'):
try:
@@ -259,15 +259,15 @@ class CourseEnrollmentForm(forms.ModelForm):
try:
course_key = CourseKey.from_string(course_id)
except InvalidKeyError:
raise forms.ValidationError("Cannot make a valid CourseKey from id {}!".format(course_id)) # lint-amnesty, pylint: disable=raise-missing-from
raise forms.ValidationError(f"Cannot make a valid CourseKey from id {course_id}!") # lint-amnesty, pylint: disable=raise-missing-from
if not modulestore().has_course(course_key):
raise forms.ValidationError("Cannot find course with id {} in the modulestore".format(course_id))
raise forms.ValidationError(f"Cannot find course with id {course_id} in the modulestore")
return course_key
def save(self, *args, **kwargs): # lint-amnesty, pylint: disable=signature-differs, unused-argument
course_enrollment = super(CourseEnrollmentForm, self).save(commit=False) # lint-amnesty, pylint: disable=super-with-arguments
course_enrollment = super().save(commit=False)
user = self.cleaned_data['user']
course_overview = self.cleaned_data['course']
enrollment = CourseEnrollment.get_or_create_enrollment(user, course_overview.id)
@@ -290,7 +290,7 @@ class CourseEnrollmentAdmin(DisableEnrollmentAdminMixin, admin.ModelAdmin):
form = CourseEnrollmentForm
def get_search_results(self, request, queryset, search_term):
qs, use_distinct = super(CourseEnrollmentAdmin, self).get_search_results(request, queryset, search_term) # lint-amnesty, pylint: disable=super-with-arguments
qs, use_distinct = super().get_search_results(request, queryset, search_term)
# annotate each enrollment with whether the username was an
# exact match for the search term
@@ -305,7 +305,7 @@ class CourseEnrollmentAdmin(DisableEnrollmentAdminMixin, admin.ModelAdmin):
return qs, use_distinct
def queryset(self, request):
return super(CourseEnrollmentAdmin, self).queryset(request).select_related('user') # lint-amnesty, pylint: disable=no-member, super-with-arguments
return super().queryset(request).select_related('user') # lint-amnesty, pylint: disable=no-member, super-with-arguments
class UserProfileInline(admin.StackedInline):
@@ -331,7 +331,7 @@ class UserChangeForm(BaseUserChangeForm):
last_name = forms.CharField(max_length=30, required=False)
def __init__(self, *args, **kwargs):
super(UserChangeForm, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
if not settings.FEATURES.get('ENABLE_CHANGE_USER_PASSWORD_ADMIN'):
self.fields["password"] = ReadOnlyPasswordHashField(
@@ -353,7 +353,7 @@ class UserAdmin(BaseUserAdmin):
Allows editing the users while skipping the username check, so we can have Unicode username with no problems.
The username is marked read-only when editing existing users regardless of `ENABLE_UNICODE_USERNAME`, to simplify the bokchoy tests. # lint-amnesty, pylint: disable=line-too-long
"""
django_readonly = super(UserAdmin, self).get_readonly_fields(request, obj) # lint-amnesty, pylint: disable=super-with-arguments
django_readonly = super().get_readonly_fields(request, obj)
if obj:
return django_readonly + ('username',)
return django_readonly
@@ -367,7 +367,7 @@ class UserAttributeAdmin(admin.ModelAdmin):
raw_id_fields = ('user',)
search_fields = ('name', 'value', 'user__username',)
class Meta(object):
class Meta:
model = UserAttribute
@@ -377,7 +377,7 @@ class CourseEnrollmentAllowedAdmin(admin.ModelAdmin):
list_display = ('email', 'course_id', 'auto_enroll',)
search_fields = ('email', 'course_id',)
class Meta(object):
class Meta:
model = CourseEnrollmentAllowed
@@ -395,35 +395,35 @@ class LoginFailuresAdmin(admin.ModelAdmin):
"""
Only enabled if feature is enabled.
"""
return super(LoginFailuresAdmin, self).has_module_permission(request) # lint-amnesty, pylint: disable=super-with-arguments
return super().has_module_permission(request)
@_Check.is_enabled(LoginFailures.is_feature_enabled)
def has_view_permission(self, request, obj=None):
"""
Only enabled if feature is enabled.
"""
return super(LoginFailuresAdmin, self).has_view_permission(request, obj) # lint-amnesty, pylint: disable=super-with-arguments
return super().has_view_permission(request, obj)
@_Check.is_enabled(LoginFailures.is_feature_enabled)
def has_delete_permission(self, request, obj=None):
"""
Only enabled if feature is enabled.
"""
return super(LoginFailuresAdmin, self).has_delete_permission(request, obj) # lint-amnesty, pylint: disable=super-with-arguments
return super().has_delete_permission(request, obj)
@_Check.is_enabled(LoginFailures.is_feature_enabled)
def has_change_permission(self, request, obj=None):
"""
Only enabled if feature is enabled.
"""
return super(LoginFailuresAdmin, self).has_change_permission(request, obj) # lint-amnesty, pylint: disable=super-with-arguments
return super().has_change_permission(request, obj)
@_Check.is_enabled(LoginFailures.is_feature_enabled)
def has_add_permission(self, request):
"""
Only enabled if feature is enabled.
"""
return super(LoginFailuresAdmin, self).has_add_permission(request) # lint-amnesty, pylint: disable=super-with-arguments
return super().has_add_permission(request)
def unlock_student_accounts(self, request, queryset):
"""
@@ -456,13 +456,13 @@ class LoginFailuresAdmin(admin.ModelAdmin):
self.unlock_student(request, object_id=object_id)
url = reverse('admin:student_loginfailures_changelist', current_app=self.admin_site.name)
return HttpResponseRedirect(url)
return super(LoginFailuresAdmin, self).change_view(request, object_id, form_url, extra_context) # lint-amnesty, pylint: disable=super-with-arguments
return super().change_view(request, object_id, form_url, extra_context)
def get_actions(self, request):
"""
Get actions for model admin and remove delete action.
"""
actions = super(LoginFailuresAdmin, self).get_actions(request) # lint-amnesty, pylint: disable=super-with-arguments
actions = super().get_actions(request)
if 'delete_selected' in actions:
del actions['delete_selected']
return actions
@@ -480,7 +480,7 @@ class LoginFailuresAdmin(admin.ModelAdmin):
class AllowedAuthUserForm(forms.ModelForm):
"""Model Form for AllowedAuthUser model's admin interface."""
class Meta(object):
class Meta:
model = AllowedAuthUser
fields = ('site', 'email', )
@@ -499,7 +499,7 @@ class AllowedAuthUserForm(forms.ModelForm):
)
elif email_domain != allowed_site_email_domain:
raise forms.ValidationError(
_("Email doesn't have {domain_name} domain name.".format(domain_name=allowed_site_email_domain)) # lint-amnesty, pylint: disable=translation-of-non-string
_(f"Email doesn't have {allowed_site_email_domain} domain name.") # lint-amnesty, pylint: disable=translation-of-non-string
)
elif not User.objects.filter(email=email).exists():
raise forms.ValidationError(_("User with this email doesn't exist in system."))
@@ -515,7 +515,7 @@ class AllowedAuthUserAdmin(admin.ModelAdmin):
search_fields = ('email',)
ordering = ('-created',)
class Meta(object):
class Meta:
model = AllowedAuthUser
@@ -526,7 +526,7 @@ class CourseEnrollmentCelebrationAdmin(DisableEnrollmentAdminMixin, admin.ModelA
list_display = ('id', 'course', 'user', 'celebrate_first_section')
search_fields = ('enrollment__course__id', 'enrollment__user__username')
class Meta(object):
class Meta:
model = CourseEnrollmentCelebration
def course(self, obj):

View File

@@ -69,7 +69,7 @@ def create_manual_enrollment_audit(
know about model level code.
"""
if transition_state not in TRANSITION_STATES:
raise ValueError("State `{}` not in allow states: `{}`".format(transition_state, TRANSITION_STATES))
raise ValueError(f"State `{transition_state}` not in allow states: `{TRANSITION_STATES}`")
User = get_user_model()
try:

View File

@@ -22,6 +22,6 @@ class StudentConfig(AppConfig):
# problems in testing, we mock it here so that the mock impacts all tests.
if os.environ.get('DISABLE_COURSEENROLLMENT_HISTORY', False):
import common.djangoapps.student.models as student_models
from mock import MagicMock
from unittest.mock import MagicMock
student_models.CourseEnrollment.history = MagicMock()

View File

@@ -214,7 +214,7 @@ def check_verify_status_by_course(user, course_enrollments):
}
if recent_verification_datetime:
for key, value in iteritems(status_by_course): # pylint: disable=unused-variable
for key, value in status_by_course.items(): # pylint: disable=unused-variable
status_by_course[key]['verification_good_until'] = recent_verification_datetime.strftime("%m/%d/%Y")
return status_by_course
@@ -270,8 +270,8 @@ def get_next_url_for_login_page(request, include_host=False):
redirect_to = reverse(login_redirect_url)
except NoReverseMatch:
log.warning(
u'Default redirect after login doesn\'t exist: %(login_redirect_url)r. '
u'Check the value set on DEFAULT_REDIRECT_AFTER_LOGIN configuration variable.',
'Default redirect after login doesn\'t exist: %(login_redirect_url)r. '
'Check the value set on DEFAULT_REDIRECT_AFTER_LOGIN configuration variable.',
{"login_redirect_url": login_redirect_url}
)
@@ -283,7 +283,7 @@ def get_next_url_for_login_page(request, include_host=False):
elif settings.ROOT_URLCONF == 'cms.urls':
redirect_to = reverse('home')
scheme = "https" if settings.HTTPS == "on" else "http"
root_url = '{}://{}'.format(scheme, settings.CMS_BASE)
root_url = f'{scheme}://{settings.CMS_BASE}'
if any(param in request_params for param in POST_AUTH_PARAMS):
# Before we redirect to next/dashboard, we need to handle auto-enrollment:
@@ -351,14 +351,14 @@ def _get_redirect_to(request_host, request_headers, request_params, request_is_h
)
if not safe_redirect:
log.warning(
u"Unsafe redirect parameter detected after login page: '%(redirect_to)s'",
"Unsafe redirect parameter detected after login page: '%(redirect_to)s'",
{"redirect_to": redirect_to}
)
redirect_to = None
elif not accepts_text_html:
log.info(
u"Redirect to non html content '%(content_type)s' detected from '%(user_agent)s'"
u" after login page: '%(redirect_to)s'",
"Redirect to non html content '%(content_type)s' detected from '%(user_agent)s'"
" after login page: '%(redirect_to)s'",
{
"redirect_to": redirect_to, "content_type": header_accept,
"user_agent": request_headers.get('HTTP_USER_AGENT', '')
@@ -367,13 +367,13 @@ def _get_redirect_to(request_host, request_headers, request_params, request_is_h
redirect_to = None
elif mime_type:
log.warning(
u"Redirect to url path with specified filed type '%(mime_type)s' not allowed: '%(redirect_to)s'",
"Redirect to url path with specified filed type '%(mime_type)s' not allowed: '%(redirect_to)s'",
{"redirect_to": redirect_to, "mime_type": mime_type}
)
redirect_to = None
elif settings.STATIC_URL in redirect_to:
log.warning(
u"Redirect to static content detected after login page: '%(redirect_to)s'",
"Redirect to static content detected after login page: '%(redirect_to)s'",
{"redirect_to": redirect_to}
)
redirect_to = None
@@ -383,7 +383,7 @@ def _get_redirect_to(request_host, request_headers, request_params, request_is_h
for theme in themes:
if theme.theme_dir_name in next_path:
log.warning(
u"Redirect to theme content detected after login page: '%(redirect_to)s'",
"Redirect to theme content detected after login page: '%(redirect_to)s'",
{"redirect_to": redirect_to}
)
redirect_to = None
@@ -421,7 +421,7 @@ def authenticate_new_user(request, username, password):
backend = load_backend(NEW_USER_AUTH_BACKEND)
user = backend.authenticate(request=request, username=username, password=password)
if not user:
log.warning("Unable to authenticate user: {username}".format(username=username))
log.warning(f"Unable to authenticate user: {username}")
user.backend = NEW_USER_AUTH_BACKEND
return user
@@ -431,7 +431,7 @@ class AccountValidationError(Exception):
Used in account creation views to raise exceptions with details about specific invalid fields
"""
def __init__(self, message, field, error_code=None):
super(AccountValidationError, self).__init__(message) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(message)
self.field = field
self.error_code = error_code
@@ -549,7 +549,7 @@ def _cert_info(user, course_overview, cert_status):
status_dict['status'] = 'unavailable'
elif 'download_url' not in cert_status:
log.warning(
u"User %s has a downloadable cert for %s, but no download url",
"User %s has a downloadable cert for %s, but no download url",
user.username,
course_overview.id
)
@@ -587,7 +587,7 @@ def _cert_info(user, course_overview, cert_status):
if all(grade is None for grade in grades_input)
else max(filter(lambda x: x is not None, grades_input))
)
status_dict['grade'] = text_type(max_grade)
status_dict['grade'] = str(max_grade)
return status_dict
@@ -681,7 +681,7 @@ def do_create_account(form, custom_form=None):
try:
profile.save()
except Exception:
log.exception("UserProfile creation failed for user {id}.".format(id=user.id))
log.exception(f"UserProfile creation failed for user {user.id}.")
raise
return user, profile, registration

View File

@@ -33,7 +33,7 @@ class UserStandingMiddleware(MiddlewareMixin):
'this was done in error, please contact us at '
'{support_email}'
)).format(
support_email=HTML(u'<a href="mailto:{address}?subject={subject_line}">{address}</a>').format(
support_email=HTML('<a href="mailto:{address}?subject={subject_line}">{address}</a>').format(
address=settings.DEFAULT_FEEDBACK_EMAIL,
subject_line=_('Disabled Account'),
),

View File

@@ -54,7 +54,6 @@ from opaque_keys.edx.keys import CourseKey
from pytz import UTC, timezone
from simple_history.models import HistoricalRecords
from six import text_type
from six.moves import range
from slumber.exceptions import HttpClientError, HttpServerError
from user_util import user_util
@@ -100,7 +99,7 @@ SessionStore = import_module(settings.SESSION_ENGINE).SessionStore # pylint: di
# ENROLL signal used for free enrollment only
class EnrollStatusChange(object):
class EnrollStatusChange:
"""
Possible event types for ENROLL_STATUS_CHANGE signal
"""
@@ -117,14 +116,14 @@ class EnrollStatusChange(object):
# complete a paid course purchase
paid_complete = 'paid_complete'
UNENROLLED_TO_ALLOWEDTOENROLL = u'from unenrolled to allowed to enroll'
ALLOWEDTOENROLL_TO_ENROLLED = u'from allowed to enroll to enrolled'
ENROLLED_TO_ENROLLED = u'from enrolled to enrolled'
ENROLLED_TO_UNENROLLED = u'from enrolled to unenrolled'
UNENROLLED_TO_ENROLLED = u'from unenrolled to enrolled'
ALLOWEDTOENROLL_TO_UNENROLLED = u'from allowed to enroll to enrolled'
UNENROLLED_TO_UNENROLLED = u'from unenrolled to unenrolled'
DEFAULT_TRANSITION_STATE = u'N/A'
UNENROLLED_TO_ALLOWEDTOENROLL = 'from unenrolled to allowed to enroll'
ALLOWEDTOENROLL_TO_ENROLLED = 'from allowed to enroll to enrolled'
ENROLLED_TO_ENROLLED = 'from enrolled to enrolled'
ENROLLED_TO_UNENROLLED = 'from enrolled to unenrolled'
UNENROLLED_TO_ENROLLED = 'from unenrolled to enrolled'
ALLOWEDTOENROLL_TO_UNENROLLED = 'from allowed to enroll to enrolled'
UNENROLLED_TO_UNENROLLED = 'from unenrolled to unenrolled'
DEFAULT_TRANSITION_STATE = 'N/A'
SCORE_RECALCULATION_DELAY_ON_ENROLLMENT_UPDATE = 30
TRANSITION_STATES = (
@@ -229,9 +228,9 @@ def anonymous_id_for_user(user, course_id, save='DEPRECATED'):
# include the secret key as a salt, and to make the ids unique across different LMS installs.
hasher = hashlib.shake_128()
hasher.update(settings.SECRET_KEY.encode('utf8'))
hasher.update(text_type(user.id).encode('utf8'))
hasher.update(str(user.id).encode('utf8'))
if course_id:
hasher.update(text_type(course_id).encode('utf-8'))
hasher.update(str(course_id).encode('utf-8'))
anonymous_user_id = hasher.hexdigest(16) # pylint: disable=too-many-function-args
try:
@@ -305,7 +304,7 @@ def is_username_retired(username):
UserRetirementStatus.objects.filter(original_username=username).exists()
except ProgrammingError as exc:
# Check the error message to make sure it's what we expect
if "user_api_userretirementstatus" in text_type(exc):
if "user_api_userretirementstatus" in str(exc):
return User.objects.filter(username__in=list(locally_hashed_usernames)).exists()
raise
@@ -426,7 +425,7 @@ def get_potentially_retired_user_by_username(username):
# We should have, at most, a retired username and an active one with a username
# differing only by case. If there are more we need to disambiguate them by hand.
raise Exception('Expected 1 or 2 Users, received {}'.format(text_type(potential_users)))
raise Exception('Expected 1 or 2 Users, received {}'.format(str(potential_users)))
def get_potentially_retired_user_by_username_and_hash(username, hashed_username):
@@ -456,11 +455,11 @@ class UserStanding(models.Model):
.. no_pii:
"""
ACCOUNT_DISABLED = u"disabled"
ACCOUNT_ENABLED = u"enabled"
ACCOUNT_DISABLED = "disabled"
ACCOUNT_ENABLED = "enabled"
USER_STANDING_CHOICES = (
(ACCOUNT_DISABLED, u"Account Disabled"),
(ACCOUNT_ENABLED, u"Account Enabled"),
(ACCOUNT_DISABLED, "Account Disabled"),
(ACCOUNT_ENABLED, "Account Enabled"),
)
user = models.OneToOneField(User, db_index=True, related_name='standing', on_delete=models.CASCADE)
@@ -494,9 +493,9 @@ class UserProfile(models.Model):
.. pii_retirement: local_api
"""
# cache key format e.g user.<user_id>.profile.country = 'SG'
PROFILE_COUNTRY_CACHE_KEY = u"user.{user_id}.profile.country"
PROFILE_COUNTRY_CACHE_KEY = "user.{user_id}.profile.country"
class Meta(object):
class Meta:
db_table = "auth_userprofile"
permissions = (("can_deactivate_users", "Can deactivate, but NOT delete users"),)
@@ -507,7 +506,7 @@ class UserProfile(models.Model):
name = models.CharField(blank=True, max_length=255, db_index=True)
meta = models.TextField(blank=True) # JSON dictionary for future expansion
courseware = models.CharField(blank=True, max_length=255, default=u'course.xml')
courseware = models.CharField(blank=True, max_length=255, default='course.xml')
# Language is deprecated and no longer used. Old rows exist that have
# user-entered free form text values (ex. "English"), some of which have
@@ -525,10 +524,10 @@ class UserProfile(models.Model):
VALID_YEARS = list(range(this_year, this_year - 120, -1))
year_of_birth = models.IntegerField(blank=True, null=True, db_index=True)
GENDER_CHOICES = (
(u'm', ugettext_noop(u'Male')),
(u'f', ugettext_noop(u'Female')),
('m', ugettext_noop('Male')),
('f', ugettext_noop('Female')),
# Translators: 'Other' refers to the student's gender
(u'o', ugettext_noop(u'Other/Prefer Not to Say'))
('o', ugettext_noop('Other/Prefer Not to Say'))
)
gender = models.CharField(
blank=True, null=True, max_length=6, db_index=True, choices=GENDER_CHOICES
@@ -539,17 +538,17 @@ class UserProfile(models.Model):
# ('p_se', 'Doctorate in science or engineering'),
# ('p_oth', 'Doctorate in another field'),
LEVEL_OF_EDUCATION_CHOICES = (
(u'p', ugettext_noop(u'Doctorate')),
(u'm', ugettext_noop(u"Master's or professional degree")),
(u'b', ugettext_noop(u"Bachelor's degree")),
(u'a', ugettext_noop(u"Associate degree")),
(u'hs', ugettext_noop(u"Secondary/high school")),
(u'jhs', ugettext_noop(u"Junior secondary/junior high/middle school")),
(u'el', ugettext_noop(u"Elementary/primary school")),
('p', ugettext_noop('Doctorate')),
('m', ugettext_noop("Master's or professional degree")),
('b', ugettext_noop("Bachelor's degree")),
('a', ugettext_noop("Associate degree")),
('hs', ugettext_noop("Secondary/high school")),
('jhs', ugettext_noop("Junior secondary/junior high/middle school")),
('el', ugettext_noop("Elementary/primary school")),
# Translators: 'None' refers to the student's level of education
(u'none', ugettext_noop(u"No formal education")),
('none', ugettext_noop("No formal education")),
# Translators: 'Other' refers to the student's level of education
(u'other', ugettext_noop(u"Other education"))
('other', ugettext_noop("Other education"))
)
level_of_education = models.CharField(
blank=True, null=True, max_length=6, db_index=True,
@@ -558,7 +557,7 @@ class UserProfile(models.Model):
mailing_address = models.TextField(blank=True, null=True)
city = models.TextField(blank=True, null=True)
country = CountryField(blank=True, null=True)
COUNTRY_WITH_STATES = u'US'
COUNTRY_WITH_STATES = 'US'
STATE_CHOICES = (
('AL', 'Alabama'),
('AK', 'Alaska'),
@@ -900,7 +899,7 @@ class Registration(models.Model):
.. no_pii:
"""
class Meta(object):
class Meta:
db_table = "auth_registration"
user = models.OneToOneField(User, on_delete=models.CASCADE)
@@ -945,7 +944,7 @@ class PendingEmailChange(DeletableByUserValue, models.Model):
"""
user = models.OneToOneField(User, unique=True, db_index=True, on_delete=models.CASCADE)
new_email = models.CharField(blank=True, max_length=255, db_index=True)
activation_key = models.CharField((u'activation key'), max_length=32, unique=True, db_index=True)
activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True)
def request_change(self, email):
"""Request a change to a user's email.
@@ -975,7 +974,7 @@ class PendingSecondaryEmailChange(DeletableByUserValue, models.Model):
"""
user = models.OneToOneField(User, unique=True, db_index=True, on_delete=models.CASCADE)
new_secondary_email = models.CharField(blank=True, max_length=255, db_index=True)
activation_key = models.CharField((u'activation key'), max_length=32, unique=True, db_index=True)
activation_key = models.CharField(('activation key'), max_length=32, unique=True, db_index=True)
EVENT_NAME_ENROLLMENT_ACTIVATED = 'edx.course.enrollment.activated'
@@ -1072,7 +1071,7 @@ class LoginFailures(models.Model):
def __str__(self):
"""Str -> Username: count - date."""
return u'{username}: {count} - {date}'.format(
return '{username}: {count} - {date}'.format(
username=self.user.username,
count=self.failure_count,
date=self.lockout_until.isoformat() if self.lockout_until else '-'
@@ -1116,7 +1115,7 @@ class CourseEnrollmentManager(models.Manager):
"""
max_enrollments = settings.FEATURES.get("MAX_ENROLLMENT_INSTR_BUTTONS")
enrollment_number = super(CourseEnrollmentManager, self).get_queryset().filter( # lint-amnesty, pylint: disable=super-with-arguments
enrollment_number = super().get_queryset().filter(
course_id=course_id,
is_active=1
)[:max_enrollments + 1].count()
@@ -1145,7 +1144,7 @@ class CourseEnrollmentManager(models.Manager):
admins = CourseInstructorRole(course_locator).users_with_role()
coaches = CourseCcxCoachRole(course_locator).users_with_role()
return super(CourseEnrollmentManager, self).get_queryset().filter( # lint-amnesty, pylint: disable=super-with-arguments
return super().get_queryset().filter(
course_id=course_id,
is_active=1,
).exclude(user__in=staff).exclude(user__in=admins).exclude(user__in=coaches).count()
@@ -1189,7 +1188,7 @@ class CourseEnrollmentManager(models.Manager):
"""
# Unfortunately, Django's "group by"-style queries look super-awkward
query = use_read_replica_if_available(
super(CourseEnrollmentManager, self).get_queryset().filter(course_id=course_id, is_active=True).values( # lint-amnesty, pylint: disable=super-with-arguments
super().get_queryset().filter(course_id=course_id, is_active=True).values(
'mode').order_by().annotate(Count('mode')))
total = 0
enroll_dict = defaultdict(int)
@@ -1262,17 +1261,17 @@ class CourseEnrollment(models.Model):
objects = CourseEnrollmentManager()
# cache key format e.g enrollment.<username>.<course_key>.mode = 'honor'
COURSE_ENROLLMENT_CACHE_KEY = u"enrollment.{}.{}.mode" # TODO Can this be removed? It doesn't seem to be used.
COURSE_ENROLLMENT_CACHE_KEY = "enrollment.{}.{}.mode" # TODO Can this be removed? It doesn't seem to be used.
MODE_CACHE_NAMESPACE = u'CourseEnrollment.mode_and_active'
MODE_CACHE_NAMESPACE = 'CourseEnrollment.mode_and_active'
class Meta(object):
class Meta:
unique_together = (('user', 'course'), )
indexes = [Index(fields=['user', '-created'])]
ordering = ('user', 'course')
def __init__(self, *args, **kwargs):
super(CourseEnrollment, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(*args, **kwargs)
# Private variable for storing course_overview to minimize calls to the database.
# When the property .course_overview is accessed for the first time, this variable will be set.
@@ -1284,8 +1283,9 @@ class CourseEnrollment(models.Model):
).format(self.user, self.course_id, self.created, self.is_active)
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
super(CourseEnrollment, self).save(force_insert=force_insert, force_update=force_update, using=using, # lint-amnesty, pylint: disable=super-with-arguments
update_fields=update_fields)
super().save(
force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields
)
# Delete the cached status hash, forcing the value to be recalculated the next time it is needed.
cache.delete(self.enrollment_status_hash_cache_key(self.user))
@@ -1477,12 +1477,12 @@ class CourseEnrollment(models.Model):
assert isinstance(self.course_id, CourseKey)
data = {
'user_id': self.user.id,
'course_id': text_type(self.course_id),
'course_id': str(self.course_id),
'mode': self.mode,
}
segment_properties = {
'category': 'conversion',
'label': text_type(self.course_id),
'label': str(self.course_id),
'org': self.course_id.org,
'course': self.course_id.course,
'run': self.course_id.run,
@@ -1500,7 +1500,7 @@ class CourseEnrollment(models.Model):
except Exception: # pylint: disable=broad-except
if event_name and self.course_id:
log.exception(
u'Unable to emit event %s for user %s and course %s',
'Unable to emit event %s for user %s and course %s',
event_name,
self.user.username,
self.course_id,
@@ -1547,7 +1547,7 @@ class CourseEnrollment(models.Model):
Also emits relevant events for analytics purposes.
"""
if mode is None:
mode = _default_course_mode(text_type(course_key))
mode = _default_course_mode(str(course_key))
# All the server-side checks for whether a user is allowed to enroll.
try:
course = CourseOverview.get_from_id(course_key)
@@ -1555,31 +1555,31 @@ class CourseEnrollment(models.Model):
# This is here to preserve legacy behavior which allowed enrollment in courses
# announced before the start of content creation.
if check_access:
log.warning(u"User %s failed to enroll in non-existent course %s", user.username, text_type(course_key))
log.warning("User %s failed to enroll in non-existent course %s", user.username, str(course_key))
raise NonExistentCourseError # lint-amnesty, pylint: disable=raise-missing-from
if check_access:
if cls.is_enrollment_closed(user, course) and not can_upgrade:
log.warning(
u"User %s failed to enroll in course %s because enrollment is closed",
"User %s failed to enroll in course %s because enrollment is closed",
user.username,
text_type(course_key)
str(course_key)
)
raise EnrollmentClosedError
if cls.objects.is_course_full(course):
log.warning(
u"Course %s has reached its maximum enrollment of %d learners. User %s failed to enroll.",
text_type(course_key),
"Course %s has reached its maximum enrollment of %d learners. User %s failed to enroll.",
str(course_key),
course.max_student_enrollments_allowed,
user.username,
)
raise CourseFullError
if cls.is_enrolled(user, course_key):
log.warning(
u"User %s attempted to enroll in %s, but they were already enrolled",
"User %s attempted to enroll in %s, but they were already enrolled",
user.username,
text_type(course_key)
str(course_key)
)
if check_access:
raise AlreadyEnrolledError
@@ -1624,7 +1624,7 @@ class CourseEnrollment(models.Model):
user = User.objects.get(email=email)
return cls.enroll(user, course_id, mode)
except User.DoesNotExist:
err_msg = u"Tried to enroll email {} into course {}, but user not found"
err_msg = "Tried to enroll email {} into course {}, but user not found"
log.error(err_msg.format(email, course_id))
if ignore_errors:
return None
@@ -1652,7 +1652,7 @@ class CourseEnrollment(models.Model):
except cls.DoesNotExist:
log.error(
u"Tried to unenroll student %s from %s but they were not enrolled",
"Tried to unenroll student %s from %s but they were not enrolled",
user,
course_id
)
@@ -1674,7 +1674,7 @@ class CourseEnrollment(models.Model):
return cls.unenroll(user, course_id)
except User.DoesNotExist:
log.error(
u"Tried to unenroll email %s from course %s, but user not found",
"Tried to unenroll email %s from course %s, but user not found",
email,
course_id
)
@@ -1712,7 +1712,7 @@ class CourseEnrollment(models.Model):
assert isinstance(course_id_partial, CourseKey)
assert not course_id_partial.run # None or empty string
course_key = CourseKey.from_string('/'.join([course_id_partial.org, course_id_partial.course, '']))
querystring = text_type(course_key)
querystring = str(course_key)
try:
return cls.objects.filter(
user=user,
@@ -1796,7 +1796,7 @@ class CourseEnrollment(models.Model):
if not status_hash:
enrollments = cls.enrollments_for_user(user).values_list('course_id', 'mode')
enrollments = [(six.text_type(e[0]).lower(), e[1].lower()) for e in enrollments]
enrollments = [(str(e[0]).lower(), e[1].lower()) for e in enrollments]
enrollments = sorted(enrollments, key=lambda e: e[0])
hash_elements = [user.username]
hash_elements += ['{course_id}={mode}'.format(course_id=e[0], mode=e[1]) for e in enrollments]
@@ -1900,7 +1900,7 @@ class CourseEnrollment(models.Model):
date_placed = order['date_placed']
# also save the attribute so that we don't need to call ecommerce again.
username = self.user.username
enrollment_attributes = get_enrollment_attributes(username, six.text_type(self.course_id))
enrollment_attributes = get_enrollment_attributes(username, str(self.course_id))
enrollment_attributes.append(
{
"namespace": "order",
@@ -1908,23 +1908,23 @@ class CourseEnrollment(models.Model):
"value": date_placed,
}
)
set_enrollment_attributes(username, six.text_type(self.course_id), enrollment_attributes)
set_enrollment_attributes(username, str(self.course_id), enrollment_attributes)
except HttpClientError:
log.warning(
u"Encountered HttpClientError while getting order details from ecommerce. "
u"Order={number} and user {user}".format(number=order_number, user=self.user.id))
"Encountered HttpClientError while getting order details from ecommerce. "
"Order={number} and user {user}".format(number=order_number, user=self.user.id))
return None
except HttpServerError:
log.warning(
u"Encountered HttpServerError while getting order details from ecommerce. "
u"Order={number} and user {user}".format(number=order_number, user=self.user.id))
"Encountered HttpServerError while getting order details from ecommerce. "
"Order={number} and user {user}".format(number=order_number, user=self.user.id))
return None
except SlumberBaseException:
log.warning(
u"Encountered an error while getting order details from ecommerce. "
u"Order={number} and user {user}".format(number=order_number, user=self.user.id))
"Encountered an error while getting order details from ecommerce. "
"Order={number} and user {user}".format(number=order_number, user=self.user.id))
return None
refund_window_start_date = max(
@@ -1944,7 +1944,7 @@ class CourseEnrollment(models.Model):
# If there are multiple attributes then return the last one.
enrollment_id = self.get_enrollment(self.user, self.course_id).id
log.warning(
u"Multiple CourseEnrollmentAttributes found for user %s with enrollment-ID %s",
"Multiple CourseEnrollmentAttributes found for user %s with enrollment-ID %s",
self.user.id,
enrollment_id
)
@@ -1974,7 +1974,7 @@ class CourseEnrollment(models.Model):
log.info('Course Overviews: unable to find course overview for enrollment, loading from modulestore.')
try:
self._course_overview = CourseOverview.get_from_id(self.course_id)
except (CourseOverview.DoesNotExist, IOError):
except (CourseOverview.DoesNotExist, OSError):
self._course_overview = None
return self._course_overview
@@ -2120,7 +2120,7 @@ class CourseEnrollment(models.Model):
Returns:
Unicode cache key
"""
return cls.COURSE_ENROLLMENT_CACHE_KEY.format(user_id, text_type(course_key))
return cls.COURSE_ENROLLMENT_CACHE_KEY.format(user_id, str(course_key))
@classmethod
def _get_enrollment_state(cls, user, course_key):
@@ -2203,7 +2203,7 @@ class FBEEnrollmentExclusion(models.Model):
)
def __str__(self):
return "[FBEEnrollmentExclusion] %s" % (self.enrollment,)
return f"[FBEEnrollmentExclusion] {self.enrollment}"
@receiver(models.signals.post_save, sender=CourseEnrollment)
@@ -2215,7 +2215,7 @@ def invalidate_enrollment_mode_cache(sender, instance, **kwargs): # pylint: dis
cache_key = CourseEnrollment.cache_key_name(
instance.user.id,
text_type(instance.course_id)
str(instance.course_id)
)
cache.delete(cache_key)
@@ -2332,11 +2332,11 @@ class CourseEnrollmentAllowed(DeletableByUserValue, models.Model):
created = models.DateTimeField(auto_now_add=True, null=True, db_index=True)
class Meta(object):
class Meta:
unique_together = (('email', 'course_id'),)
def __str__(self):
return "[CourseEnrollmentAllowed] %s: %s (%s)" % (self.email, self.course_id, self.created)
return f"[CourseEnrollmentAllowed] {self.email}: {self.course_id} ({self.created})"
@classmethod
def for_user(cls, user):
@@ -2387,7 +2387,7 @@ class CourseAccessRole(models.Model):
course_id = CourseKeyField(max_length=255, db_index=True, blank=True)
role = models.CharField(max_length=64, db_index=True)
class Meta(object):
class Meta:
unique_together = ('user', 'org', 'course_id', 'role')
@property
@@ -2415,14 +2415,14 @@ class CourseAccessRole(models.Model):
return self._key < other._key
def __str__(self):
return "[CourseAccessRole] user: {} role: {} org: {} course: {}".format(self.user.username, self.role, self.org, self.course_id) # lint-amnesty, pylint: disable=line-too-long
return f"[CourseAccessRole] user: {self.user.username} role: {self.role} org: {self.org} course: {self.course_id}" # lint-amnesty, pylint: disable=line-too-long
#### Helper methods for use from python manage.py shell and other classes.
def strip_if_string(value):
if isinstance(value, six.string_types):
if isinstance(value, str):
return value.strip()
return value
@@ -2538,7 +2538,7 @@ def create_comments_service_user(user): # lint-amnesty, pylint: disable=missing
except Exception: # pylint: disable=broad-except
log = logging.getLogger("edx.discussion") # pylint: disable=redefined-outer-name
log.error(
"Could not create comments service user with id {}".format(user.id),
f"Could not create comments service user with id {user.id}",
exc_info=True
)
@@ -2552,9 +2552,9 @@ def create_comments_service_user(user): # lint-amnesty, pylint: disable=missing
def log_successful_login(sender, request, user, **kwargs): # lint-amnesty, pylint: disable=unused-argument
"""Handler to log when logins have occurred successfully."""
if settings.FEATURES['SQUELCH_PII_IN_LOGS']:
AUDIT_LOG.info(u"Login success - user.id: {0}".format(user.id))
AUDIT_LOG.info(f"Login success - user.id: {user.id}")
else:
AUDIT_LOG.info(u"Login success - {0} ({1})".format(user.username, user.email))
AUDIT_LOG.info(f"Login success - {user.username} ({user.email})")
@receiver(user_logged_out)
@@ -2562,9 +2562,9 @@ def log_successful_logout(sender, request, user, **kwargs): # lint-amnesty, pyl
"""Handler to log when logouts have occurred successfully."""
if hasattr(request, 'user'):
if settings.FEATURES['SQUELCH_PII_IN_LOGS']:
AUDIT_LOG.info('Logout - user.id: {0}'.format(request.user.id)) # pylint: disable=logging-format-interpolation
AUDIT_LOG.info(f'Logout - user.id: {request.user.id}') # pylint: disable=logging-format-interpolation
else:
AUDIT_LOG.info('Logout - {0}'.format(request.user)) # pylint: disable=logging-format-interpolation
AUDIT_LOG.info(f'Logout - {request.user}') # pylint: disable=logging-format-interpolation
if request.user.id:
segment.track(request.user.id, 'edx.bi.user.account.logout')
@@ -2604,7 +2604,7 @@ class DashboardConfiguration(ConfigurationModel):
"""
recent_enrollment_time_delta = models.PositiveIntegerField(
default=0,
help_text=u"The number of seconds in which a new enrollment is considered 'recent'. "
help_text="The number of seconds in which a new enrollment is considered 'recent'. "
"Used to display notifications."
)
@@ -2735,11 +2735,11 @@ class EntranceExamConfiguration(models.Model):
# for the course
skip_entrance_exam = models.BooleanField(default=True)
class Meta(object):
class Meta:
unique_together = (('user', 'course_id'), )
def __str__(self):
return "[EntranceExamConfiguration] %s: %s (%s) = %s" % (
return "[EntranceExamConfiguration] {}: {} ({}) = {}".format(
self.user, self.course_id, self.created, self.skip_entrance_exam
)
@@ -2773,7 +2773,7 @@ class LanguageField(models.CharField):
'help_text',
_("The ISO 639-1 language code for this language."),
)
super(LanguageField, self).__init__( # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(
max_length=16,
choices=settings.ALL_LANGUAGES,
help_text=help_text,
@@ -2794,7 +2794,7 @@ class LanguageProficiency(models.Model):
.. no_pii: Language is not PII value according to OEP-30.
"""
class Meta(object):
class Meta:
unique_together = (('code', 'user_profile'),)
user_profile = models.ForeignKey(UserProfile, db_index=True, related_name='language_proficiencies',
@@ -2849,7 +2849,7 @@ class CourseEnrollmentAttribute(models.Model):
def __str__(self):
"""Unicode representation of the attribute. """
return u"{namespace}:{name}, {value}".format(
return "{namespace}:{name}, {value}".format(
namespace=self.namespace,
name=self.name,
value=self.value,
@@ -2953,7 +2953,7 @@ class RegistrationCookieConfiguration(ConfigurationModel):
def __str__(self):
"""Unicode representation of this config. """
return u"UTM: {utm_name}; AFFILIATE: {affiliate_name}".format(
return "UTM: {utm_name}; AFFILIATE: {affiliate_name}".format(
utm_name=self.utm_cookie_name,
affiliate_name=self.affiliate_cookie_name
)
@@ -2964,8 +2964,8 @@ class BulkUnenrollConfiguration(ConfigurationModel): # lint-amnesty, pylint: di
"""
csv_file = models.FileField(
validators=[FileExtensionValidator(allowed_extensions=[u'csv'])],
help_text=_(u"It expect that the data will be provided in a csv file format with \
validators=[FileExtensionValidator(allowed_extensions=['csv'])],
help_text=_("It expect that the data will be provided in a csv file format with \
first row being the header and columns will be as follows: \
user_id, username, email, course_id, is_verified, verification_date")
)
@@ -2976,8 +2976,8 @@ class BulkChangeEnrollmentConfiguration(ConfigurationModel):
config model for the bulk_change_enrollment_csv command
"""
csv_file = models.FileField(
validators=[FileExtensionValidator(allowed_extensions=[u'csv'])],
help_text=_(u"It expect that the data will be provided in a csv file format with \
validators=[FileExtensionValidator(allowed_extensions=['csv'])],
help_text=_("It expect that the data will be provided in a csv file format with \
first row being the header and columns will be as follows: \
course_id, username, mode")
)
@@ -2991,7 +2991,7 @@ class UserAttribute(TimeStampedModel):
.. no_pii:
"""
class Meta(object):
class Meta:
# Ensure that at most one value exists for a given user/name.
unique_together = (('user', 'name',), )
@@ -3043,13 +3043,13 @@ class AccountRecoveryManager(models.Manager):
AccountRecovery: AccountRecovery object with is_active=true
"""
filters['is_active'] = True
return super(AccountRecoveryManager, self).get_queryset().get(**filters) # lint-amnesty, pylint: disable=super-with-arguments
return super().get_queryset().get(**filters)
def activate(self):
"""
Set is_active flag to True.
"""
super(AccountRecoveryManager, self).get_queryset().update(is_active=True) # lint-amnesty, pylint: disable=super-with-arguments
super().get_queryset().update(is_active=True)
class AccountRecovery(models.Model):
@@ -3070,7 +3070,7 @@ class AccountRecovery(models.Model):
)
is_active = models.BooleanField(default=False)
class Meta(object):
class Meta:
db_table = "auth_accountrecovery"
objects = AccountRecoveryManager()
@@ -3122,8 +3122,8 @@ class AccountRecoveryConfiguration(ConfigurationModel):
configuration model for recover account management command
"""
csv_file = models.FileField(
validators=[FileExtensionValidator(allowed_extensions=[u'csv'])],
help_text=_(u"It expect that the data will be provided in a csv file format with \
validators=[FileExtensionValidator(allowed_extensions=['csv'])],
help_text=_("It expect that the data will be provided in a csv file format with \
first row being the header and columns will be as follows: \
username, current_email, desired_email")
)

View File

@@ -33,13 +33,13 @@ def register_access_role(cls):
role_name = cls.ROLE
REGISTERED_ACCESS_ROLES[role_name] = cls
except AttributeError:
log.exception(u"Unable to register Access Role with attribute 'ROLE'.")
log.exception("Unable to register Access Role with attribute 'ROLE'.")
return cls
class BulkRoleCache(object): # lint-amnesty, pylint: disable=missing-class-docstring
CACHE_NAMESPACE = u"student.roles.BulkRoleCache"
CACHE_KEY = u'roles_by_user'
class BulkRoleCache: # lint-amnesty, pylint: disable=missing-class-docstring
CACHE_NAMESPACE = "student.roles.BulkRoleCache"
CACHE_KEY = 'roles_by_user'
@classmethod
def prefetch(cls, users): # lint-amnesty, pylint: disable=missing-function-docstring
@@ -58,7 +58,7 @@ class BulkRoleCache(object): # lint-amnesty, pylint: disable=missing-class-docs
return get_cache(cls.CACHE_NAMESPACE)[cls.CACHE_KEY][user.id]
class RoleCache(object):
class RoleCache:
"""
A cache of the CourseAccessRoles held by a particular user
"""
@@ -82,7 +82,7 @@ class RoleCache(object):
)
class AccessRole(six.with_metaclass(ABCMeta, object)):
class AccessRole(metaclass=ABCMeta):
"""
Object representing a role with particular access to a resource
"""
@@ -150,7 +150,7 @@ class RoleBase(AccessRole):
an org. Provide org and course if constrained to a course. Although, you should use the subclasses
for all of these.
"""
super(RoleBase, self).__init__() # lint-amnesty, pylint: disable=super-with-arguments
super().__init__()
self.org = org
self.course_key = course_key
@@ -229,14 +229,14 @@ class CourseRole(RoleBase):
Args:
course_key (CourseKey)
"""
super(CourseRole, self).__init__(role, course_key.org, course_key) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(role, course_key.org, course_key)
@classmethod
def course_group_already_exists(self, course_key): # lint-amnesty, pylint: disable=bad-classmethod-argument
return CourseAccessRole.objects.filter(org=course_key.org, course_id=course_key).exists()
def __repr__(self):
return '<{}: course_key={}>'.format(self.__class__.__name__, self.course_key)
return f'<{self.__class__.__name__}: course_key={self.course_key}>'
class OrgRole(RoleBase):
@@ -244,7 +244,7 @@ class OrgRole(RoleBase):
A named role in a particular org independent of course
"""
def __repr__(self):
return '<{}>'.format(self.__class__.__name__)
return f'<{self.__class__.__name__}>'
@register_access_role
@@ -253,7 +253,7 @@ class CourseStaffRole(CourseRole):
ROLE = 'staff'
def __init__(self, *args, **kwargs):
super(CourseStaffRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
@register_access_role
@@ -262,7 +262,7 @@ class CourseInstructorRole(CourseRole):
ROLE = 'instructor'
def __init__(self, *args, **kwargs):
super(CourseInstructorRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
@register_access_role
@@ -271,7 +271,7 @@ class CourseFinanceAdminRole(CourseRole):
ROLE = 'finance_admin'
def __init__(self, *args, **kwargs):
super(CourseFinanceAdminRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
@register_access_role
@@ -280,7 +280,7 @@ class CourseSalesAdminRole(CourseRole):
ROLE = 'sales_admin'
def __init__(self, *args, **kwargs):
super(CourseSalesAdminRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
@register_access_role
@@ -289,7 +289,7 @@ class CourseBetaTesterRole(CourseRole):
ROLE = 'beta_testers'
def __init__(self, *args, **kwargs):
super(CourseBetaTesterRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
@register_access_role
@@ -301,7 +301,7 @@ class LibraryUserRole(CourseRole):
ROLE = 'library_user'
def __init__(self, *args, **kwargs):
super(LibraryUserRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
class CourseCcxCoachRole(CourseRole):
@@ -309,7 +309,7 @@ class CourseCcxCoachRole(CourseRole):
ROLE = 'ccx_coach'
def __init__(self, *args, **kwargs):
super(CourseCcxCoachRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
@register_access_role
@@ -318,19 +318,19 @@ class CourseDataResearcherRole(CourseRole):
ROLE = 'data_researcher'
def __init__(self, *args, **kwargs):
super(CourseDataResearcherRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
class OrgStaffRole(OrgRole):
"""An organization staff member"""
def __init__(self, *args, **kwargs):
super(OrgStaffRole, self).__init__('staff', *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__('staff', *args, **kwargs)
class OrgInstructorRole(OrgRole):
"""An organization instructor"""
def __init__(self, *args, **kwargs):
super(OrgInstructorRole, self).__init__('instructor', *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__('instructor', *args, **kwargs)
class OrgLibraryUserRole(OrgRole):
@@ -341,7 +341,7 @@ class OrgLibraryUserRole(OrgRole):
ROLE = LibraryUserRole.ROLE
def __init__(self, *args, **kwargs):
super(OrgLibraryUserRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
class OrgDataResearcherRole(OrgRole):
@@ -349,7 +349,7 @@ class OrgDataResearcherRole(OrgRole):
ROLE = 'data_researcher'
def __init__(self, *args, **kwargs):
super(OrgDataResearcherRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
@register_access_role
@@ -361,7 +361,7 @@ class CourseCreatorRole(RoleBase):
ROLE = "course_creator_group"
def __init__(self, *args, **kwargs):
super(CourseCreatorRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
@register_access_role
@@ -372,10 +372,10 @@ class SupportStaffRole(RoleBase):
ROLE = "support"
def __init__(self, *args, **kwargs):
super(SupportStaffRole, self).__init__(self.ROLE, *args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
super().__init__(self.ROLE, *args, **kwargs)
class UserBasedRole(object):
class UserBasedRole:
"""
Backward mapping: given a user, manipulate the courses and roles
"""

View File

@@ -33,15 +33,15 @@ TEST_PASSWORD = 'test'
class GroupFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = Group
django_get_or_create = ('name', )
name = factory.Sequence(u'group{0}'.format)
name = factory.Sequence('group{}'.format)
class UserStandingFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = UserStanding
user = None
@@ -50,38 +50,38 @@ class UserStandingFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=
class UserProfileFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = UserProfile
django_get_or_create = ('user', )
user = None
name = factory.LazyAttribute(u'{0.user.first_name} {0.user.last_name}'.format)
name = factory.LazyAttribute('{0.user.first_name} {0.user.last_name}'.format)
level_of_education = None
gender = u'm'
gender = 'm'
mailing_address = None
goals = u'Learn a lot'
goals = 'Learn a lot'
allow_certificate = True
class RegistrationFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = Registration
user = None
activation_key = six.text_type(uuid4().hex)
activation_key = str(uuid4().hex)
class UserFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = User
django_get_or_create = ('email', 'username')
_DEFAULT_PASSWORD = 'test'
username = factory.Sequence(u'robot{0}'.format)
email = factory.Sequence(u'robot+test+{0}@edx.org'.format)
username = factory.Sequence('robot{}'.format)
email = factory.Sequence('robot+test+{}@edx.org'.format)
password = factory.PostGenerationMethodCall('set_password', _DEFAULT_PASSWORD)
first_name = factory.Sequence(u'Robot{0}'.format)
first_name = factory.Sequence('Robot{}'.format)
last_name = 'Test'
is_staff = False
is_active = True
@@ -104,7 +104,7 @@ class UserFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-
if extracted is None:
return
if isinstance(extracted, six.string_types):
if isinstance(extracted, str):
extracted = [extracted]
for group_name in extracted:
@@ -112,7 +112,7 @@ class UserFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-
class AnonymousUserFactory(factory.Factory):
class Meta(object):
class Meta:
model = AnonymousUser
@@ -125,7 +125,7 @@ class SuperuserFactory(UserFactory):
class CourseEnrollmentFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = CourseEnrollment
user = factory.SubFactory(UserFactory)
@@ -147,7 +147,7 @@ class CourseEnrollmentFactory(DjangoModelFactory): # lint-amnesty, pylint: disa
# foreign key constraint to CourseEnrollment.
del kwargs['course_id']
if isinstance(course_id, six.string_types):
if isinstance(course_id, str):
course_id = CourseKey.from_string(course_id)
course_kwargs.setdefault('id', course_id)
@@ -174,7 +174,7 @@ class CourseEnrollmentCelebrationFactory(DjangoModelFactory):
class CourseAccessRoleFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = CourseAccessRole
user = factory.SubFactory(UserFactory)
@@ -183,7 +183,7 @@ class CourseAccessRoleFactory(DjangoModelFactory): # lint-amnesty, pylint: disa
class CourseEnrollmentAllowedFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = CourseEnrollmentAllowed
email = 'test@edx.org'
@@ -197,23 +197,23 @@ class PendingEmailChangeFactory(DjangoModelFactory):
new_email: sequence of new+email+{}@edx.org
activation_key: sequence of integers, padded to 30 characters
"""
class Meta(object):
class Meta:
model = PendingEmailChange
user = factory.SubFactory(UserFactory)
new_email = factory.Sequence(u'new+email+{0}@edx.org'.format)
activation_key = factory.Sequence(u'{:0<30d}'.format)
new_email = factory.Sequence('new+email+{}@edx.org'.format)
activation_key = factory.Sequence('{:0<30d}'.format)
class ContentTypeFactory(DjangoModelFactory):
class Meta(object):
class Meta:
model = ContentType
app_label = factory.Faker('app_name')
class PermissionFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = Permission
codename = factory.Faker('codename')
@@ -221,10 +221,10 @@ class PermissionFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=mi
class AccountRecoveryFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
class Meta(object):
class Meta:
model = AccountRecovery
django_get_or_create = ('user',)
user = None
secondary_email = factory.Sequence(u'robot+test+recovery+{0}@edx.org'.format)
secondary_email = factory.Sequence('robot+test+recovery+{}@edx.org'.format)
is_active = True

View File

@@ -2,21 +2,20 @@
import unittest
from uuid import uuid4
from datetime import datetime
from unittest.mock import patch
from uuid import uuid4
from django.conf import settings
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.test import TestCase, override_settings
from django.urls import reverse
from edx_toggles.toggles.testutils import override_waffle_flag
from mock import patch
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_authn.toggles import REDIRECT_TO_AUTHN_MICROFRONTEND
from common.djangoapps.student.models import Registration
from common.djangoapps.student.tests.factories import UserFactory
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.user_authn.toggles import REDIRECT_TO_AUTHN_MICROFRONTEND
FEATURES_WITH_AUTHN_MFE_ENABLED = settings.FEATURES.copy()
FEATURES_WITH_AUTHN_MFE_ENABLED['ENABLE_AUTHN_MICROFRONTEND'] = True
@@ -27,7 +26,7 @@ class TestActivateAccount(TestCase):
"""Tests for account creation"""
def setUp(self):
super(TestActivateAccount, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.username = "jack"
self.email = "jack@fake.edx.org"
self.password = "test-password"
@@ -108,8 +107,8 @@ class TestActivateAccount(TestCase):
# Log in with test user.
self.login()
expected_message = (
u"Check your {email_start}{email}{email_end} inbox for an account activation link from "
u"{platform_name}. If you need help, contact {link_start}{platform_name} Support{link_end}."
"Check your {email_start}{email}{email_end} inbox for an account activation link from "
"{platform_name}. If you need help, contact {link_start}{platform_name} Support{link_end}."
).format(
platform_name=self.platform_name,
email_start="<strong>",

View File

@@ -1,10 +1,10 @@
# coding=UTF-8
"""
Tests student admin.py
"""
import datetime
from unittest.mock import Mock
import ddt
import pytest
@@ -16,17 +16,20 @@ from django.test import TestCase, override_settings
from django.urls import reverse
from django.utils.timezone import now
from edx_toggles.toggles.testutils import override_waffle_switch
from mock import Mock
from pytz import UTC
from common.djangoapps.student.admin import AllowedAuthUserForm, COURSE_ENROLLMENT_ADMIN_SWITCH, UserAdmin, CourseEnrollmentForm # lint-amnesty, pylint: disable=line-too-long
from common.djangoapps.student.admin import ( # lint-amnesty, pylint: disable=line-too-long
COURSE_ENROLLMENT_ADMIN_SWITCH,
AllowedAuthUserForm,
CourseEnrollmentForm,
UserAdmin
)
from common.djangoapps.student.models import AllowedAuthUser, CourseEnrollment, LoginFailures
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
class AdminCourseRolesPageTest(SharedModuleStoreTestCase):
@@ -34,18 +37,18 @@ class AdminCourseRolesPageTest(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
super(AdminCourseRolesPageTest, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create(org='edx')
def setUp(self):
super(AdminCourseRolesPageTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create(is_staff=True, is_superuser=True)
self.user.save()
def test_save_valid_data(self):
data = {
'course_id': six.text_type(self.course.id),
'course_id': str(self.course.id),
'role': 'finance_admin',
'org': 'edx',
'email': self.user.email
@@ -61,7 +64,7 @@ class AdminCourseRolesPageTest(SharedModuleStoreTestCase):
self.assertContains(response, 'Select course access role to change')
self.assertContains(response, 'Add course access role')
self.assertContains(response, 'finance_admin')
self.assertContains(response, six.text_type(self.course.id))
self.assertContains(response, str(self.course.id))
self.assertContains(response, '1 course access role')
#try adding with same information raise error.
@@ -73,7 +76,7 @@ class AdminCourseRolesPageTest(SharedModuleStoreTestCase):
data = {
'role': 'staff',
'email': self.user.email,
'course_id': six.text_type(self.course.id)
'course_id': str(self.course.id)
}
self.client.login(username=self.user.username, password='test')
@@ -125,7 +128,7 @@ class AdminCourseRolesPageTest(SharedModuleStoreTestCase):
def test_save_with_invalid_course(self):
course = six.text_type('no/edx/course')
course = 'no/edx/course'
email = "invalid@email.com"
data = {
'course_id': course,
@@ -155,7 +158,7 @@ class AdminCourseRolesPageTest(SharedModuleStoreTestCase):
def test_save_valid_course_invalid_org(self):
data = {
'course_id': six.text_type(self.course.id),
'course_id': str(self.course.id),
'role': 'finance_admin',
'org': 'edxxx',
'email': self.user.email
@@ -178,7 +181,7 @@ class AdminUserPageTest(TestCase):
Unit tests for the UserAdmin view.
"""
def setUp(self):
super(AdminUserPageTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.admin = UserAdmin(User, AdminSite())
def test_username_is_writable_for_user_creation(self):
@@ -221,7 +224,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
)
def setUp(self):
super(CourseEnrollmentAdminTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create(is_staff=True, is_superuser=True)
self.course = CourseFactory()
self.course_enrollment = CourseEnrollmentFactory(
@@ -253,7 +256,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
"""
Ensure that course enrollment searches return exact matches on username first.
"""
user2 = UserFactory.create(username='aaa_{}'.format(self.user.username))
user2 = UserFactory.create(username=f'aaa_{self.user.username}')
CourseEnrollmentFactory(
user=user2,
course_id=self.course.id, # pylint: disable=no-member
@@ -279,8 +282,8 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
# is_active will change from True to False
assert self.course_enrollment.is_active
data = {
'user': six.text_type(self.course_enrollment.user.id),
'course': six.text_type(self.course_enrollment.course.id),
'user': str(self.course_enrollment.user.id),
'course': str(self.course_enrollment.course.id),
'is_active': 'false',
'mode': self.course_enrollment.mode,
}
@@ -300,7 +303,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
Send an invalid course ID instead of "org.0/course_0/Run_0" when saving, and verify that it fails.
"""
data = {
'user': six.text_type(self.course_enrollment.user.id),
'user': str(self.course_enrollment.user.id),
'course': 'invalid-course-id',
'is_active': 'true',
'mode': self.course_enrollment.mode,
@@ -321,22 +324,22 @@ class LoginFailuresAdminTest(TestCase):
@classmethod
def setUpClass(cls):
"""Setup class"""
super(LoginFailuresAdminTest, cls).setUpClass()
cls.user = UserFactory.create(username=u'§', is_staff=True, is_superuser=True)
super().setUpClass()
cls.user = UserFactory.create(username='§', is_staff=True, is_superuser=True)
cls.user.save()
def setUp(self):
"""Setup."""
super(LoginFailuresAdminTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.client.login(username=self.user.username, password='test')
self.user2 = UserFactory.create(username=u'Zażółć gęślą jaźń')
self.user2 = UserFactory.create(username='Zażółć gęślą jaźń')
self.user_lockout_until = datetime.datetime.now(UTC)
LoginFailures.objects.create(user=self.user, failure_count=10, lockout_until=self.user_lockout_until)
LoginFailures.objects.create(user=self.user2, failure_count=2)
def tearDown(self):
"""Tear Down."""
super(LoginFailuresAdminTest, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
super().tearDown()
LoginFailures.objects.all().delete()
def test_unicode_username(self):
@@ -374,7 +377,7 @@ class LoginFailuresAdminTest(TestCase):
url,
data={
'action': 'unlock_student_accounts',
'_selected_action': [six.text_type(o.pk) for o in LoginFailures.objects.all()]
'_selected_action': [str(o.pk) for o in LoginFailures.objects.all()]
},
follow=True
)
@@ -400,11 +403,11 @@ class CourseEnrollmentAdminFormTest(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
super(CourseEnrollmentAdminFormTest, cls).setUpClass()
super().setUpClass()
cls.course = CourseOverviewFactory(start=now())
def setUp(self):
super(CourseEnrollmentAdminFormTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create()
def test_admin_model_form_create(self):
@@ -415,7 +418,7 @@ class CourseEnrollmentAdminFormTest(SharedModuleStoreTestCase):
form = CourseEnrollmentForm({
'user': self.user.id,
'course': six.text_type(self.course.id),
'course': str(self.course.id),
'is_active': True,
'mode': 'audit',
})
@@ -432,7 +435,7 @@ class CourseEnrollmentAdminFormTest(SharedModuleStoreTestCase):
count = CourseEnrollment.objects.count()
form = CourseEnrollmentForm({
'user': self.user.id,
'course': six.text_type(self.course.id),
'course': str(self.course.id),
'is_active': False,
'mode': 'audit'},
instance=enrollment
@@ -450,11 +453,11 @@ class AllowedAuthUserFormTest(SiteMixin, TestCase):
"""
@classmethod
def setUpClass(cls):
super(AllowedAuthUserFormTest, cls).setUpClass()
super().setUpClass()
cls.email_domain_name = "dummy.com"
cls.email_with_wrong_domain = "dummy@example.com"
cls.valid_email = "dummy@{email_domain_name}".format(email_domain_name=cls.email_domain_name)
cls.other_valid_email = "dummy1@{email_domain_name}".format(email_domain_name=cls.email_domain_name)
cls.valid_email = f"dummy@{cls.email_domain_name}"
cls.other_valid_email = f"dummy1@{cls.email_domain_name}"
UserFactory(email=cls.valid_email)
UserFactory(email=cls.email_with_wrong_domain)

View File

@@ -2,7 +2,7 @@
Tests authz.py
"""
import mock
from unittest import mock
import pytest
from ccx_keys.locator import CCXLocator
@@ -23,7 +23,7 @@ class CreatorGroupTest(TestCase):
def setUp(self):
""" Test case setup """
super(CreatorGroupTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = User.objects.create_user('testuser', 'test+courses@edx.org', 'foo')
self.admin = User.objects.create_user('Mark', 'admin+courses@edx.org', 'foo')
self.admin.is_staff = True
@@ -151,7 +151,7 @@ class CCXCourseGroupTest(TestCase):
"""
Set up test variables
"""
super(CCXCourseGroupTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.global_admin = AdminFactory()
self.staff = User.objects.create_user('teststaff', 'teststaff+courses@edx.org', 'foo')
self.ccx_course_key = CCXLocator.from_string('ccx-v1:edX+DemoX+Demo_Course+ccx@1')
@@ -189,7 +189,7 @@ class CourseGroupTest(TestCase):
def setUp(self):
""" Test case setup """
super(CourseGroupTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.global_admin = AdminFactory()
self.creator = User.objects.create_user('testcreator', 'testcreator+courses@edx.org', 'foo')
self.staff = User.objects.create_user('teststaff', 'teststaff+courses@edx.org', 'foo')

View File

@@ -27,11 +27,11 @@ class TestStudentDashboardEmailView(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
super(TestStudentDashboardEmailView, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
super(TestStudentDashboardEmailView, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
# Create student account
student = UserFactory.create()
@@ -51,7 +51,7 @@ class TestStudentDashboardEmailView(SharedModuleStoreTestCase):
)
def tearDown(self):
super(TestStudentDashboardEmailView, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
super().tearDown()
BulkEmailFlag.objects.all().delete()
def test_email_flag_true(self):

View File

@@ -3,21 +3,22 @@
import datetime
import unittest
from unittest.mock import patch
import ddt
from django.conf import settings
from django.test.utils import override_settings
from django.urls import reverse
from mock import patch
from pytz import UTC
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from lms.djangoapps.certificates.api import get_certificate_url
from lms.djangoapps.certificates.models import CertificateStatuses
from lms.djangoapps.certificates.tests.factories import (
GeneratedCertificateFactory, LinkedInAddToProfileConfigurationFactory
GeneratedCertificateFactory,
LinkedInAddToProfileConfigurationFactory
)
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -37,7 +38,7 @@ class CertificateDisplayTestBase(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(CertificateDisplayTestBase, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory()
cls.course.certificates_display_behavior = "early_with_info"
@@ -45,7 +46,7 @@ class CertificateDisplayTestBase(SharedModuleStoreTestCase):
cls.store.update_item(cls.course, cls.USERNAME)
def setUp(self):
super(CertificateDisplayTestBase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD)
result = self.client.login(username=self.USERNAME, password=self.PASSWORD)
assert result, 'Could not log in'
@@ -56,9 +57,9 @@ class CertificateDisplayTestBase(SharedModuleStoreTestCase):
"""
response = self.client.get(reverse('dashboard'))
if is_visible:
self.assertContains(response, u'Add Certificate to LinkedIn Profile')
self.assertContains(response, 'Add Certificate to LinkedIn Profile')
else:
self.assertNotContains(response, u'Add Certificate to LinkedIn Profile')
self.assertNotContains(response, 'Add Certificate to LinkedIn Profile')
def _create_certificate(self, enrollment_mode, download_url=DOWNLOAD_URL):
"""Simulate that the user has a generated certificate. """
@@ -80,7 +81,7 @@ class CertificateDisplayTestBase(SharedModuleStoreTestCase):
Inspect the dashboard to see if a certificate can be downloaded.
"""
response = self.client.get(reverse('dashboard'))
self.assertContains(response, u'Download Your ID Verified')
self.assertContains(response, 'Download Your ID Verified')
self.assertContains(response, self.DOWNLOAD_URL)
def _check_can_download_certificate_no_id(self):
@@ -89,8 +90,8 @@ class CertificateDisplayTestBase(SharedModuleStoreTestCase):
is present
"""
response = self.client.get(reverse('dashboard'))
self.assertContains(response, u'Download')
self.assertContains(response, u'(PDF)')
self.assertContains(response, 'Download')
self.assertContains(response, '(PDF)')
self.assertContains(response, self.DOWNLOAD_URL)
def _check_can_not_download_certificate(self):
@@ -98,9 +99,9 @@ class CertificateDisplayTestBase(SharedModuleStoreTestCase):
Make sure response does not have any of the download certificate buttons
"""
response = self.client.get(reverse('dashboard'))
self.assertNotContains(response, u'View Test_Certificate')
self.assertNotContains(response, u'Download Your Test_Certificate (PDF)')
self.assertNotContains(response, u'Download Test_Certificate (PDF)')
self.assertNotContains(response, 'View Test_Certificate')
self.assertNotContains(response, 'Download Your Test_Certificate (PDF)')
self.assertNotContains(response, 'Download Test_Certificate (PDF)')
self.assertNotContains(response, self.DOWNLOAD_URL)
@@ -115,7 +116,7 @@ class CertificateDashboardMessageDisplayTest(CertificateDisplayTestBase):
@classmethod
def setUpClass(cls):
super(CertificateDashboardMessageDisplayTest, cls).setUpClass()
super().setUpClass()
cls.course.certificates_display_behavior = "end"
cls.course.save()
cls.store.update_item(cls.course, cls.USERNAME)
@@ -124,11 +125,11 @@ class CertificateDashboardMessageDisplayTest(CertificateDisplayTestBase):
response = self.client.get(reverse('dashboard'))
if certificate_available_date is None:
self.assertNotContains(response, u"Your certificate will be available on")
self.assertNotContains(response, u"View Test_Certificate")
self.assertNotContains(response, "Your certificate will be available on")
self.assertNotContains(response, "View Test_Certificate")
elif datetime.datetime.now(UTC) < certificate_available_date:
self.assertContains(response, u"Your certificate will be available on")
self.assertNotContains(response, u"View Test_Certificate")
self.assertContains(response, "Your certificate will be available on")
self.assertNotContains(response, "View Test_Certificate")
else:
self._check_can_download_certificate()
@@ -188,7 +189,7 @@ class CertificateDisplayTest(CertificateDisplayTestBase):
response = self.client.get(reverse('dashboard'))
self.assertContains(
response,
u'do not have a current verified identity with {platform_name}'
'do not have a current verified identity with {platform_name}'
.format(platform_name=settings.PLATFORM_NAME))
def test_post_to_linkedin_visibility(self):
@@ -218,7 +219,7 @@ class CertificateDisplayTestHtmlView(CertificateDisplayTestBase):
@classmethod
def setUpClass(cls):
super(CertificateDisplayTestHtmlView, cls).setUpClass()
super().setUpClass()
cls.course.cert_html_view_enabled = True
cls.course.save()
cls.store.update_item(cls.course, cls.USERNAME)
@@ -246,7 +247,7 @@ class CertificateDisplayTestLinkedHtmlView(CertificateDisplayTestBase):
@classmethod
def setUpClass(cls):
super(CertificateDisplayTestLinkedHtmlView, cls).setUpClass()
super().setUpClass()
cls.course.cert_html_view_enabled = True
certificates = [
@@ -274,5 +275,5 @@ class CertificateDisplayTestLinkedHtmlView(CertificateDisplayTestBase):
response = self.client.get(reverse('dashboard'))
self.assertContains(response, u'View Test_Certificate')
self.assertContains(response, 'View Test_Certificate')
self.assertContains(response, test_url)

View File

@@ -5,7 +5,7 @@ Test for user creation from sites with configuration overrides.
import json
import mock
from unittest import mock
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.test import TestCase
from django.urls import reverse
@@ -53,7 +53,7 @@ def fake_get_value(name, default=None):
class TestSite(TestCase):
"""Test for Account Creation from white labeled Sites"""
def setUp(self):
super(TestSite, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.username = "test_user"
self.url = reverse("create_account")
self.params = {

View File

@@ -6,7 +6,7 @@ by reversing group name formats.
import unittest
import mock
from unittest import mock
import six
from django.conf import settings
from django.test.client import Client
@@ -35,7 +35,7 @@ class TestCourseListing(ModuleStoreTestCase, MilestonesTestCaseMixin):
"""
Add a student & teacher
"""
super(TestCourseListing, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.student = UserFactory()
self.teacher = UserFactory()
@@ -65,7 +65,7 @@ class TestCourseListing(ModuleStoreTestCase, MilestonesTestCaseMixin):
Reverse the setup
"""
self.client.logout()
super(TestCourseListing, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
super().tearDown()
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
def test_get_course_list(self):
@@ -153,8 +153,8 @@ class TestCourseListing(ModuleStoreTestCase, MilestonesTestCaseMixin):
self._create_course_with_access_groups(pre_requisite_course_location2)
# create a course with pre_requisite_courses
pre_requisite_courses = [
six.text_type(pre_requisite_course_location),
six.text_type(pre_requisite_course_location2),
str(pre_requisite_course_location),
str(pre_requisite_course_location2),
]
course_location = self.store.make_course_key('Org1', 'Course1', 'Run1')
self._create_course_with_access_groups(course_location, {

View File

@@ -5,18 +5,18 @@ Tests for credit courses on the student dashboard.
import datetime
import unittest
from unittest.mock import patch
import ddt
import pytz
from django.conf import settings
from django.test.utils import override_settings
from django.urls import reverse
from mock import patch
from openedx.core.djangoapps.credit import api as credit_api
from openedx.core.djangoapps.credit.models import CreditCourse, CreditEligibility, CreditProvider
from common.djangoapps.student.models import CourseEnrollmentAttribute
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from openedx.core.djangoapps.credit import api as credit_api
from openedx.core.djangoapps.credit.models import CreditCourse, CreditEligibility, CreditProvider
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -43,7 +43,7 @@ class CreditCourseDashboardTest(ModuleStoreTestCase):
def setUp(self):
"""Create a course and an enrollment. """
super(CreditCourseDashboardTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
# Create a user and log in
self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD)
@@ -213,14 +213,14 @@ class CreditCourseDashboardTest(ModuleStoreTestCase):
@ddt.data(
(
[u'Arizona State University'],
['Arizona State University'],
'You are now eligible for credit from Arizona State University'),
(
[u'Arizona State University', u'Hogwarts School of Witchcraft'],
['Arizona State University', 'Hogwarts School of Witchcraft'],
'You are now eligible for credit from Arizona State University and Hogwarts School of Witchcraft'
),
(
[u'Arizona State University', u'Hogwarts School of Witchcraft and Wizardry', u'Charter Oak'],
['Arizona State University', 'Hogwarts School of Witchcraft and Wizardry', 'Charter Oak'],
'You are now eligible for credit from Arizona State University, Hogwarts School'
' of Witchcraft and Wizardry, and Charter Oak'
),

View File

@@ -1,13 +1,11 @@
# coding=utf-8 # lint-amnesty, pylint: disable=missing-module-docstring
import json
import unittest
from string import capwords
from unittest.mock import Mock, patch
import ddt
import six
import pytest
import six
from django.conf import settings
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core import mail
@@ -18,7 +16,6 @@ from django.test.client import RequestFactory
from django.urls import reverse
from django.utils.html import escape
from edx_toggles.toggles.testutils import override_waffle_flag
from mock import Mock, patch
from six import text_type
from common.djangoapps.edxmako.shortcuts import marketing_link
@@ -56,7 +53,7 @@ def mock_render_to_string(template_name, context):
"""
Return a string that encodes template_name and context
"""
return str((template_name, sorted(six.iteritems(context))))
return str((template_name, sorted(context.items())))
def mock_render_to_response(template_name, context):
@@ -68,7 +65,7 @@ def mock_render_to_response(template_name, context):
return HttpResponse(mock_render_to_string(template_name, context))
class EmailTestMixin(object):
class EmailTestMixin:
"""
Adds useful assertions for testing `email_user`
"""
@@ -105,29 +102,29 @@ class ActivationEmailTests(EmailTemplateTagMixin, CacheIsolationTestCase):
Test sending of the activation email.
"""
ACTIVATION_SUBJECT = u"Action Required: Activate your {} account".format(settings.PLATFORM_NAME)
ACTIVATION_SUBJECT = f"Action Required: Activate your {settings.PLATFORM_NAME} account"
# Text fragments we expect in the body of an email
# sent from an OpenEdX installation.
OPENEDX_FRAGMENTS = [
(
u"Use the link below to activate your account to access engaging, "
u"high-quality {platform_name} courses. Note that you will not be able to log back into your "
u"account until you have activated it.".format(
"Use the link below to activate your account to access engaging, "
"high-quality {platform_name} courses. Note that you will not be able to log back into your "
"account until you have activated it.".format(
platform_name=settings.PLATFORM_NAME
)
),
u"{}/activate/".format(settings.LMS_ROOT_URL),
u"If you need help, please use our web form at ", (
f"{settings.LMS_ROOT_URL}/activate/",
"If you need help, please use our web form at ", (
settings.ACTIVATION_EMAIL_SUPPORT_LINK or settings.SUPPORT_SITE_LINK
),
settings.CONTACT_EMAIL,
u"This email message was automatically sent by ",
"This email message was automatically sent by ",
settings.LMS_ROOT_URL,
u" because someone attempted to create an account on {platform_name}".format(
" because someone attempted to create an account on {platform_name}".format(
platform_name=settings.PLATFORM_NAME
),
u" using this email address."
" using this email address."
]
@ddt.data('plain_text', 'html')
@@ -249,7 +246,7 @@ class ProctoringRequirementsEmailTests(EmailTemplateTagMixin, ModuleStoreTestCas
text = message.body
html = message.alternatives[0][0]
assert message.subject == "Proctoring requirements for {}".format(self.course.display_name)
assert message.subject == f"Proctoring requirements for {self.course.display_name}"
for fragment in self._get_fragments():
assert fragment in text
@@ -288,7 +285,7 @@ class EmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, CacheIsolat
"""
def setUp(self, tracker='common.djangoapps.student.views.management.tracker'):
super(EmailChangeRequestTests, self).setUp(tracker) # lint-amnesty, pylint: disable=super-with-arguments
super().setUp(tracker)
self.user = UserFactory.create()
self.new_email = 'new.email@edx.org'
self.req_factory = RequestFactory()
@@ -306,7 +303,7 @@ class EmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, CacheIsolat
try:
validate_new_email(self.request.user, email)
except ValueError as err:
return text_type(err)
return str(err)
def do_email_change(self, user, email, activation_key=None):
"""
@@ -377,22 +374,22 @@ class EmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, CacheIsolat
self.do_email_change(self.user, new_email, registration_key)
self._assert_email(
subject=u'Request to change édX account e-mail',
subject='Request to change édX account e-mail',
body_fragments=[
u'We received a request to change the e-mail associated with',
u'your édX account from {old_email} to {new_email}.'.format(
'We received a request to change the e-mail associated with',
'your édX account from {old_email} to {new_email}.'.format(
old_email=old_email,
new_email=new_email,
),
u'If this is correct, please confirm your new e-mail address by visiting:',
u'http://edx.org/email_confirm/{key}'.format(key=registration_key),
u'Please do not reply to this e-mail; if you require assistance,',
u'check the help section of the édX web site.',
'If this is correct, please confirm your new e-mail address by visiting:',
f'http://edx.org/email_confirm/{registration_key}',
'Please do not reply to this e-mail; if you require assistance,',
'check the help section of the édX web site.',
],
)
self.assert_event_emitted(
SETTING_CHANGE_INITIATED, user_id=self.user.id, setting=u'email', old=old_email, new=new_email
SETTING_CHANGE_INITIATED, user_id=self.user.id, setting='email', old=old_email, new=new_email
)
def _assert_email(self, subject, body_fragments):
@@ -423,7 +420,7 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
"""
def setUp(self):
super(EmailChangeConfirmationTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.clear_caches()
self.addCleanup(self.clear_caches)
self.user = UserFactory.create()
@@ -435,31 +432,31 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
self.key = self.pending_change_request.activation_key
# Expected subject of the email
self.email_subject = u"Email Change Confirmation for {platform_name}".format(
self.email_subject = "Email Change Confirmation for {platform_name}".format(
platform_name=settings.PLATFORM_NAME
)
# Text fragments we expect in the body of the confirmation email
self.email_fragments = [
u"This is to confirm that you changed the e-mail associated with {platform_name}"
u" from {old_email} to {new_email}. If you did not make this request, please contact us immediately."
u" Contact information is listed at:".format(
"This is to confirm that you changed the e-mail associated with {platform_name}"
" from {old_email} to {new_email}. If you did not make this request, please contact us immediately."
" Contact information is listed at:".format(
platform_name=settings.PLATFORM_NAME,
old_email=self.user.email,
new_email=PendingEmailChange.objects.get(activation_key=self.key).new_email
),
u"We keep a log of old e-mails, so if this request was unintentional, we can investigate."
"We keep a log of old e-mails, so if this request was unintentional, we can investigate."
]
@classmethod
def setUpClass(cls):
super(EmailChangeConfirmationTests, cls).setUpClass()
super().setUpClass()
cls.start_cache_isolation()
@classmethod
def tearDownClass(cls):
cls.end_cache_isolation()
super(EmailChangeConfirmationTests, cls).tearDownClass()
super().tearDownClass()
def assertRolledBack(self):
"""
@@ -613,7 +610,7 @@ class SecondaryEmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, Ca
try:
validate_new_email(self.request.user, email)
except ValueError as err:
return text_type(err)
return str(err)
def do_secondary_email_change(self, user, email, activation_key=None):
"""
@@ -664,12 +661,12 @@ class SecondaryEmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, Ca
self.do_secondary_email_change(self.user, new_email, registration_key)
self._assert_email(
subject=u'Confirm your recovery email for édX',
subject='Confirm your recovery email for édX',
body_fragments=[
u'You\'ve registered this recovery email address for édX.',
u'If you set this email address, click "confirm email."',
u'If you didn\'t request this change, you can disregard this email.',
u'http://edx.org/activate_secondary_email/{key}'.format(key=registration_key),
'You\'ve registered this recovery email address for édX.',
'If you set this email address, click "confirm email."',
'If you didn\'t request this change, you can disregard this email.',
f'http://edx.org/activate_secondary_email/{registration_key}',
],
)

View File

@@ -4,18 +4,17 @@ Tests for student enrollment.
import unittest
import pytest
from unittest.mock import patch
import ddt
import pytest
import six
from django.conf import settings
from django.urls import reverse
from edx_toggles.toggles.testutils import override_waffle_flag
from mock import patch
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
from openedx.core.djangoapps.embargo.test_utils import restrict_course
from common.djangoapps.student.models import (
SCORE_RECALCULATION_DELAY_ON_ENROLLMENT_UPDATE,
CourseEnrollment,
@@ -26,6 +25,7 @@ from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRol
from common.djangoapps.student.tests.factories import CourseEnrollmentAllowedFactory, UserFactory
from common.djangoapps.util.testing import UrlResetMixin
from lms.djangoapps.courseware.toggles import COURSEWARE_PROCTORING_IMPROVEMENTS
from openedx.core.djangoapps.embargo.test_utils import restrict_course
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@@ -46,7 +46,7 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(EnrollmentTest, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create()
cls.course_limited = CourseFactory.create()
cls.proctored_course = CourseFactory(
@@ -59,13 +59,13 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
@patch.dict(settings.FEATURES, {'EMBARGO': True})
def setUp(self):
""" Create a course and user, then log in. """
super(EnrollmentTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create(username=self.USERNAME, email=self.EMAIL, password=self.PASSWORD)
self.client.login(username=self.USERNAME, password=self.PASSWORD)
self.course_limited.max_student_enrollments_allowed = 1
self.store.update_item(self.course_limited, self.user.id)
self.urls = [
reverse('course_modes_choose', kwargs={'course_id': six.text_type(self.course.id)})
reverse('course_modes_choose', kwargs={'course_id': str(self.course.id)})
]
# Set up proctored exam
self._create_proctored_exam(self.proctored_course)
@@ -123,7 +123,7 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
# (otherwise, use an empty string, which the JavaScript client
# interprets as a redirect to the dashboard)
full_url = (
reverse(next_url, kwargs={'course_id': six.text_type(self.course.id)})
reverse(next_url, kwargs={'course_id': str(self.course.id)})
if next_url else next_url
)
@@ -384,7 +384,7 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
"""
if course_id is None:
course_id = six.text_type(self.course.id)
course_id = str(self.course.id)
params = {
'enrollment_action': action,

View File

@@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-
"""
Test that various events are fired for models in the student app.
"""
import mock
from unittest import mock
import pytest
from django.db.utils import IntegrityError
@@ -21,7 +20,7 @@ class TestUserProfileEvents(UserSettingsEventTestMixin, TestCase):
Test that we emit field change events when UserProfile models are changed.
"""
def setUp(self):
super(TestUserProfileEvents, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.table = 'auth_userprofile'
self.user = UserFactory.create()
self.profile = self.user.profile
@@ -46,18 +45,18 @@ class TestUserProfileEvents(UserSettingsEventTestMixin, TestCase):
Verify that we emit one event per field when many fields change on the
user profile in one transaction.
"""
self.profile.gender = u'o'
self.profile.gender = 'o'
self.profile.bio = 'test bio'
self.profile.save()
self.assert_user_setting_event_emitted(setting='bio', old=None, new=self.profile.bio)
self.assert_user_setting_event_emitted(setting='gender', old=u'm', new=u'o')
self.assert_user_setting_event_emitted(setting='gender', old='m', new='o')
def test_unicode(self):
"""
Verify that the events we emit can handle unicode characters.
"""
old_name = self.profile.name
self.profile.name = u'Dånîél'
self.profile.name = 'Dånîél'
self.profile.save()
self.assert_user_setting_event_emitted(setting='name', old=old_name, new=self.profile.name)
@@ -65,7 +64,7 @@ class TestUserProfileEvents(UserSettingsEventTestMixin, TestCase):
"""
Verify that we properly serialize the JSON-unfriendly Country field.
"""
self.profile.country = Country(u'AL', 'dummy_flag_url')
self.profile.country = Country('AL', 'dummy_flag_url')
self.profile.save()
self.assert_user_setting_event_emitted(setting='country', old=None, new=self.profile.country)
@@ -73,7 +72,7 @@ class TestUserProfileEvents(UserSettingsEventTestMixin, TestCase):
"""
Verify that we don't emit events for ignored fields.
"""
self.profile.meta = {u'foo': u'bar'}
self.profile.meta = {'foo': 'bar'}
self.profile.save()
self.assert_no_events_were_emitted()
@@ -95,7 +94,7 @@ class TestUserEvents(UserSettingsEventTestMixin, TestCase):
Test that we emit field change events when User models are changed.
"""
def setUp(self):
super(TestUserEvents, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create()
self.reset_tracker()
self.table = 'auth_user'
@@ -105,7 +104,7 @@ class TestUserEvents(UserSettingsEventTestMixin, TestCase):
Verify that we emit an event when a single field changes on the user.
"""
old_username = self.user.username
self.user.username = u'new username'
self.user.username = 'new username'
self.user.save()
self.assert_user_setting_event_emitted(setting='username', old=old_username, new=self.user.username)
@@ -116,7 +115,7 @@ class TestUserEvents(UserSettingsEventTestMixin, TestCase):
"""
old_email = self.user.email
old_is_staff = self.user.is_staff
self.user.email = u'foo@bar.com'
self.user.email = 'foo@bar.com'
self.user.is_staff = True
self.user.save()
self.assert_user_setting_event_emitted(setting='email', old=old_email, new=self.user.email)
@@ -126,7 +125,7 @@ class TestUserEvents(UserSettingsEventTestMixin, TestCase):
"""
Verify that password values are not included in the event payload.
"""
self.user.password = u'new password'
self.user.password = 'new password'
self.user.save()
self.assert_user_setting_event_emitted(setting='password', old=None, new=None)
@@ -145,7 +144,7 @@ class TestUserEvents(UserSettingsEventTestMixin, TestCase):
signal is not called in this case either, but the intent is to make it clear that this model
should never emit an event if save fails.
"""
self.user.password = u'new password'
self.user.password = 'new password'
with pytest.raises(IntegrityError):
self.user.save()
self.assert_no_events_were_emitted()

View File

@@ -3,6 +3,7 @@
import logging
import unittest
from unittest.mock import patch
import ddt
from django.conf import settings
@@ -10,11 +11,10 @@ from django.contrib.sessions.middleware import SessionMiddleware
from django.test import TestCase
from django.test.client import RequestFactory
from django.test.utils import override_settings
from mock import patch
from testfixtures import LogCapture
from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration_context
from common.djangoapps.student.helpers import get_next_url_for_login_page
from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration_context
LOGGER_NAME = "common.djangoapps.student.helpers"
@@ -25,7 +25,7 @@ class TestLoginHelper(TestCase):
static_url = settings.STATIC_URL
def setUp(self):
super(TestLoginHelper, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.request = RequestFactory()
@staticmethod
@@ -56,7 +56,7 @@ class TestLoginHelper(TestCase):
def test_next_failures(self, log_level, log_name, unsafe_url, http_accept, user_agent, expected_log):
""" Test unsafe next parameter """
with LogCapture(LOGGER_NAME, level=log_level) as logger:
req = self.request.get(settings.LOGIN_URL + "?next={url}".format(url=unsafe_url))
req = self.request.get(settings.LOGIN_URL + f"?next={unsafe_url}")
req.META["HTTP_ACCEPT"] = http_accept
req.META["HTTP_USER_AGENT"] = user_agent
get_next_url_for_login_page(req)
@@ -74,7 +74,7 @@ class TestLoginHelper(TestCase):
@override_settings(LOGIN_REDIRECT_WHITELIST=['test.edx.org', 'test2.edx.org'])
def test_safe_next(self, next_url, http_accept, host):
""" Test safe next parameter """
req = self.request.get(settings.LOGIN_URL + "?next={url}".format(url=next_url), HTTP_HOST=host)
req = self.request.get(settings.LOGIN_URL + f"?next={next_url}", HTTP_HOST=host)
req.META["HTTP_ACCEPT"] = http_accept
next_page = get_next_url_for_login_page(req)
assert next_page == next_url
@@ -121,7 +121,7 @@ class TestLoginHelper(TestCase):
Assert that get_next_url_for_login_page returns as expected.
"""
if method == 'GET':
req = self.request.get(settings.LOGIN_URL + "?next={url}".format(url=next_url))
req = self.request.get(settings.LOGIN_URL + f"?next={next_url}")
elif method == 'POST':
req = self.request.post(settings.LOGIN_URL, {'next': next_url})
req.META["HTTP_ACCEPT"] = "text/html"

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""Tests for LinkedIn Add to Profile configuration. """
@@ -60,7 +59,7 @@ class LinkedInAddToProfileUrlTests(TestCase):
assert 'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME' in actual_url
assert f'&name={quote(settings.PLATFORM_NAME.encode("utf-8"))}+{expected_cert_name}' in actual_url
assert '&certUrl={cert_url}'.format(cert_url=quote(self.CERT_URL, safe='')) in actual_url
assert '&organizationId={org_id}'.format(org_id=config.company_identifier) in actual_url
assert f'&organizationId={config.company_identifier}' in actual_url
@ddt.data(
('honor', 'Honor+Code+Credential+for+Test+Course+%E2%98%83'),
@@ -95,4 +94,4 @@ class LinkedInAddToProfileUrlTests(TestCase):
assert 'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME' in actual_url
assert f'&name={quote(settings.PLATFORM_NAME.encode("utf-8"))}+{expected_cert_name}' in actual_url
assert '&certUrl={cert_url}'.format(cert_url=quote(self.CERT_URL, safe='')) in actual_url
assert '&organizationId={org_id}'.format(org_id=config.company_identifier) in actual_url
assert f'&organizationId={config.company_identifier}' in actual_url

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*- # lint-amnesty, pylint: disable=missing-module-docstring
import json
from django.test import TestCase
@@ -12,7 +9,7 @@ from openedx.core.djangoapps.user_api.accounts import USERNAME_BAD_LENGTH_MSG
class TestLongUsernameEmail(TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
def setUp(self):
super(TestLongUsernameEmail, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.url = reverse('create_account')
self.url_params = {
'username': 'username',

View File

@@ -1,10 +1,10 @@
# lint-amnesty, pylint: disable=missing-module-docstring
import datetime
import hashlib
from unittest import mock
import ddt
import factory
import mock
import pytz
from crum import set_current_request
from django.contrib.auth.models import AnonymousUser, User # lint-amnesty, pylint: disable=imported-auth-user
@@ -12,13 +12,24 @@ from django.core.cache import cache
from django.db.models import signals
from django.db.models.functions import Lower
from django.test import TestCase
from edx_toggles.toggles.testutils import override_waffle_flag
from freezegun import freeze_time
from opaque_keys.edx.keys import CourseKey
from pytz import UTC
from edx_toggles.toggles.testutils import override_waffle_flag
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
from common.djangoapps.student.models import (
ALLOWEDTOENROLL_TO_ENROLLED,
AccountRecovery,
CourseEnrollment,
CourseEnrollmentAllowed,
ManualEnrollmentAudit,
PendingEmailChange,
PendingNameChange,
UserCelebration
)
from common.djangoapps.student.tests.factories import AccountRecoveryFactory, CourseEnrollmentFactory, UserFactory
from lms.djangoapps.courseware.models import DynamicUpgradeDeadlineConfiguration
from lms.djangoapps.courseware.toggles import (
COURSEWARE_MICROFRONTEND_PROGRESS_MILESTONES,
@@ -29,17 +40,6 @@ from openedx.core.djangoapps.content.course_overviews.models import CourseOvervi
from openedx.core.djangoapps.schedules.models import Schedule
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
from openedx.core.djangolib.testing.utils import skip_unless_lms
from common.djangoapps.student.models import (
ALLOWEDTOENROLL_TO_ENROLLED,
AccountRecovery,
CourseEnrollment,
CourseEnrollmentAllowed,
UserCelebration,
ManualEnrollmentAudit,
PendingEmailChange,
PendingNameChange,
)
from common.djangoapps.student.tests.factories import AccountRecoveryFactory, CourseEnrollmentFactory, UserFactory
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -49,11 +49,11 @@ from xmodule.modulestore.tests.factories import CourseFactory
class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint: disable=missing-class-docstring
@classmethod
def setUpClass(cls):
super(CourseEnrollmentTests, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory()
def setUp(self):
super(CourseEnrollmentTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory()
self.user_2 = UserFactory()
@@ -465,7 +465,7 @@ class PendingNameChangeTests(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
super(PendingNameChangeTests, cls).setUpClass()
super().setUpClass()
cls.user = UserFactory()
cls.user2 = UserFactory()
@@ -494,7 +494,7 @@ class PendingEmailChangeTests(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
super(PendingEmailChangeTests, cls).setUpClass()
super().setUpClass()
cls.user = UserFactory()
cls.user2 = UserFactory()
@@ -519,7 +519,7 @@ class PendingEmailChangeTests(SharedModuleStoreTestCase):
class TestCourseEnrollmentAllowed(TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
def setUp(self):
super(TestCourseEnrollmentAllowed, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.email = 'learner@example.com'
self.course_key = CourseKey.from_string("course-v1:edX+DemoX+Demo_Course")
self.user = UserFactory.create()
@@ -558,7 +558,7 @@ class TestManualEnrollmentAudit(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
super(TestManualEnrollmentAudit, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory()
cls.other_course = CourseFactory()
cls.user = UserFactory()
@@ -625,7 +625,7 @@ class TestUserPostSaveCallback(SharedModuleStoreTestCase):
changing any existing course mode states.
"""
def setUp(self):
super(TestUserPostSaveCallback, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create()
@ddt.data(*(set(CourseMode.ALL_MODES) - set(CourseMode.AUDIT_MODES)))
@@ -675,7 +675,7 @@ class TestUserPostSaveCallback(SharedModuleStoreTestCase):
actual_student = User.objects.get(email=student.email)
actual_cea = CourseEnrollmentAllowed.objects.get(email=student.email)
assert actual_course_enrollment.mode == u'audit'
assert actual_course_enrollment.mode == 'audit'
assert actual_student.is_active is True
assert actual_cea.user == student
@@ -687,7 +687,7 @@ class TestUserPostSaveCallback(SharedModuleStoreTestCase):
student = self._set_up_invited_student(
course=self.course,
active=True,
course_mode=u'verified'
course_mode='verified'
)
old_email = student.email
@@ -699,7 +699,7 @@ class TestUserPostSaveCallback(SharedModuleStoreTestCase):
actual_course_enrollment = CourseEnrollment.objects.get(user=student, course_id=self.course.id)
actual_student = User.objects.get(email=student.email)
assert actual_course_enrollment.mode == u'verified'
assert actual_course_enrollment.mode == 'verified'
assert actual_student.is_active is True
def _set_up_invited_student(self, course, active=False, enrolled=True, course_mode=''):

View File

@@ -17,7 +17,7 @@ class ProfileParentalControlsTest(TestCase):
password = "test"
def setUp(self):
super(ProfileParentalControlsTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create(password=self.password)
self.profile = UserProfile.objects.get(id=self.user.id)

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
This test file will verify proper password policy enforcement, which is an option feature
"""
@@ -17,7 +16,7 @@ class TestPasswordPolicy(TestCase):
Go through some password policy tests to make sure things are properly working
"""
def setUp(self):
super(TestPasswordPolicy, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.url = reverse('create_account')
self.request_factory = RequestFactory()
self.url_params = {
@@ -125,7 +124,7 @@ class TestPasswordPolicy(TestCase):
])
def test_not_enough_numeric_characters(self):
# The unicode ២ is the number 2 in Khmer and the ٧ is the Arabic-Indic number 7
self.url_params['password'] = u'thisShouldFail២٧'
self.url_params['password'] = 'thisShouldFail២٧'
response = self.client.post(self.url, self.url_params)
assert response.status_code == 400
obj = json.loads(response.content.decode('utf-8'))
@@ -136,7 +135,7 @@ class TestPasswordPolicy(TestCase):
])
def test_enough_numeric_characters(self):
# The unicode ២ is the number 2 in Khmer
self.url_params['password'] = u'thisShouldPass២33'
self.url_params['password'] = 'thisShouldPass២33'
response = self.client.post(self.url, self.url_params)
assert response.status_code == 200
obj = json.loads(response.content.decode('utf-8'))
@@ -156,7 +155,7 @@ class TestPasswordPolicy(TestCase):
create_validator_config('common.djangoapps.util.password_policy_validators.AlphabeticValidator', {'min_alphabetic': 3}) # lint-amnesty, pylint: disable=line-too-long
])
def test_enough_alphabetic_characters(self):
self.url_params['password'] = u'𝒯𝓗Ï𝓼𝒫å𝓼𝓼𝔼𝓼'
self.url_params['password'] = '𝒯𝓗Ï𝓼𝒫å𝓼𝓼𝔼𝓼'
response = self.client.post(self.url, self.url_params)
assert response.status_code == 200
obj = json.loads(response.content.decode('utf-8'))
@@ -189,7 +188,7 @@ class TestPasswordPolicy(TestCase):
create_validator_config('common.djangoapps.util.password_policy_validators.PunctuationValidator', {'min_punctuation': 3}), # lint-amnesty, pylint: disable=line-too-long
])
def test_multiple_errors_pass(self):
self.url_params['password'] = u'tH1s Sh0u!d P3#$!'
self.url_params['password'] = 'tH1s Sh0u!d P3#$!'
response = self.client.post(self.url, self.url_params)
assert response.status_code == 200
obj = json.loads(response.content.decode('utf-8'))
@@ -220,7 +219,7 @@ class TestPasswordPolicy(TestCase):
create_validator_config('common.djangoapps.util.password_policy_validators.MaximumLengthValidator', {'max_length': 75}), # lint-amnesty, pylint: disable=line-too-long
])
def test_with_unicode(self):
self.url_params['password'] = u'四節比分和七年前'
self.url_params['password'] = '四節比分和七年前'
response = self.client.post(self.url, self.url_params)
assert response.status_code == 200
obj = json.loads(response.content.decode('utf-8'))
@@ -232,7 +231,7 @@ class TestUsernamePasswordNonmatch(TestCase):
Test that registration username and password fields differ
"""
def setUp(self):
super(TestUsernamePasswordNonmatch, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.url = reverse('create_account')
self.url_params = {

View File

@@ -12,7 +12,6 @@ from django.urls import reverse
from django.utils.timezone import now
from opaque_keys.edx import locator
from pytz import UTC
from six.moves import range, zip
from common.test.utils import XssTestMixin
from common.djangoapps.student.models import CourseEnrollment, DashboardConfiguration
@@ -35,7 +34,7 @@ class TestRecentEnrollments(ModuleStoreTestCase, XssTestMixin):
"""
Add a student
"""
super(TestRecentEnrollments, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.student = UserFactory()
self.student.set_password(self.PASSWORD)
self.student.save()
@@ -102,9 +101,9 @@ class TestRecentEnrollments(ModuleStoreTestCase, XssTestMixin):
courses = []
for idx, seconds_past in zip(list(range(2, 6)), [5, 10, 15, 20]):
course_location = locator.CourseLocator(
'Org{num}'.format(num=idx),
'Course{num}'.format(num=idx),
'Run{num}'.format(num=idx)
f'Org{idx}',
f'Course{idx}',
f'Run{idx}'
)
course, enrollment = self._create_course_and_enrollment(course_location)
enrollment.created = now() - datetime.timedelta(seconds=seconds_past)
@@ -126,10 +125,7 @@ class TestRecentEnrollments(ModuleStoreTestCase, XssTestMixin):
response = self.client.get(reverse("dashboard"))
# verify recent enrollment message
self.assertContains(
response,
'Thank you for enrolling in:'.format(course_name=self.course.display_name)
)
self.assertContains(response, 'Thank you for enrolling in:')
self.assertContains(
response,
', '.join(enrollment.course.display_name for enrollment in recent_course_list)
@@ -144,7 +140,7 @@ class TestRecentEnrollments(ModuleStoreTestCase, XssTestMixin):
response = self.client.get(reverse("dashboard"))
self.assertContains(
response,
"Thank you for enrolling in {course_name}".format(course_name=self.course.display_name)
f"Thank you for enrolling in {self.course.display_name}"
)
def test_dashboard_rendering_with_two_courses(self):
@@ -171,7 +167,7 @@ class TestRecentEnrollments(ModuleStoreTestCase, XssTestMixin):
self.assertContains(
response,
"Thank you for enrolling in:".format(course_name=self.course.display_name)
"Thank you for enrolling in:"
)
self.assertContains(
response,

View File

@@ -6,6 +6,7 @@
import logging
import unittest
from datetime import datetime, timedelta
from unittest.mock import patch
import ddt
import httpretty
@@ -16,17 +17,15 @@ from django.conf import settings
from django.test.client import Client
from django.test.utils import override_settings
from django.urls import reverse
from mock import patch
from six.moves import range
# These imports refer to lms djangoapps.
# Their testcases are only run under lms.
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
from common.djangoapps.student.models import CourseEnrollment, CourseEnrollmentAttribute, EnrollmentRefundConfiguration
from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.certificates.models import CertificateStatuses, GeneratedCertificate
from lms.djangoapps.certificates.tests.factories import GeneratedCertificateFactory
from openedx.core.djangoapps.commerce.utils import ECOMMERCE_DATE_FORMAT
from common.djangoapps.student.models import CourseEnrollment, CourseEnrollmentAttribute, EnrollmentRefundConfiguration
from common.djangoapps.student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -46,12 +45,12 @@ class RefundableTest(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(RefundableTest, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
""" Setup components used by each refund test."""
super(RefundableTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create(password=self.USER_PASSWORD)
self.verified_mode = CourseModeFactory.create(
course_id=self.course.id,
@@ -136,11 +135,11 @@ class RefundableTest(SharedModuleStoreTestCase):
expected_date = now + expected_date_delta
refund_period = timedelta(days=days)
date_placed = order_date.strftime(ECOMMERCE_DATE_FORMAT)
expected_content = '{{"date_placed": "{date}"}}'.format(date=date_placed)
expected_content = f'{{"date_placed": "{date_placed}"}}'
httpretty.register_uri(
httpretty.GET,
'{url}/orders/{order}/'.format(url=TEST_API_URL, order=self.ORDER_NUMBER),
f'{TEST_API_URL}/orders/{self.ORDER_NUMBER}/',
status=200, body=expected_content,
adding_headers={'Content-Type': JSON}
)
@@ -202,7 +201,7 @@ class RefundableTest(SharedModuleStoreTestCase):
httpretty.register_uri(
httpretty.GET,
'{url}/orders/{order}/'.format(url=TEST_API_URL, order=self.ORDER_NUMBER),
f'{TEST_API_URL}/orders/{self.ORDER_NUMBER}/',
status=200, body=expected_content,
adding_headers={'Content-Type': JSON}
)

View File

@@ -270,7 +270,7 @@ class TestRegisterRetiredUsername(TestCase):
INVALID_ERR_MSG = ('It looks like', 'belongs to an existing account. Try again with a different username.')
def setUp(self):
super(TestRegisterRetiredUsername, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.url = reverse('user_api_registration')
self.url_params = {
'username': 'username',

View File

@@ -28,7 +28,7 @@ class RolesTestCase(TestCase):
"""
def setUp(self):
super(RolesTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course_key = CourseKey.from_string('edX/toy/2012_Fall')
self.course_loc = self.course_key.make_usage_key('course', '2012_Fall')
self.anonymous_user = AnonymousUserFactory()
@@ -156,7 +156,7 @@ class RoleCacheTestCase(TestCase): # lint-amnesty, pylint: disable=missing-clas
)
def setUp(self):
super(RoleCacheTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory()
@ddt.data(*ROLES)

View File

@@ -3,10 +3,9 @@ Tests for the Sending activation email celery tasks
"""
import mock
from unittest import mock
from django.conf import settings
from django.test import TestCase
from six.moves import range
from edx_ace.errors import ChannelError, RecoverableChannelDeliveryError
from lms.djangoapps.courseware.tests.factories import UserFactory
@@ -21,7 +20,7 @@ class SendActivationEmailTestCase(TestCase):
"""
def setUp(self):
""" Setup components used by each test."""
super(SendActivationEmailTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.student = UserFactory()
registration = Registration()

View File

@@ -21,7 +21,7 @@ class UserProfilePropertiesTest(CacheIsolationTestCase):
ENABLED_CACHES = ['default']
def setUp(self):
super(UserProfilePropertiesTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory.create(password=self.password)
self.profile = self.user.profile

View File

@@ -18,7 +18,7 @@ class UserStandingTest(TestCase):
"""test suite for user standing view for enabling and disabling accounts"""
def setUp(self):
super(UserStandingTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
# create users
self.bad_user = UserFactory.create(
username='bad_user',

View File

@@ -3,6 +3,7 @@
import unittest
from datetime import datetime, timedelta
from unittest.mock import patch
import ddt
import six
@@ -10,12 +11,9 @@ from django.conf import settings
from django.test import override_settings
from django.urls import reverse
from django.utils.timezone import now
from mock import patch
from pytz import UTC
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, VerificationDeadline
from common.djangoapps.student.helpers import (
VERIFY_STATUS_APPROVED,
VERIFY_STATUS_MISSED_DEADLINE,
@@ -26,6 +24,7 @@ from common.djangoapps.student.helpers import (
)
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from common.djangoapps.util.testing import UrlResetMixin
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, VerificationDeadline
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -48,7 +47,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
def setUp(self):
# Invoke UrlResetMixin
super(TestCourseVerificationStatus, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory(password="edx")
self.course = CourseFactory.create()
@@ -379,7 +378,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
response = self.client.get(self.dashboard_url)
# Sanity check: verify that the course is on the page
self.assertContains(response, six.text_type(self.course.id))
self.assertContains(response, str(self.course.id))
# Verify that the correct banner is rendered on the dashboard
alt_text = self.BANNER_ALT_MESSAGES.get(status)

View File

@@ -8,6 +8,7 @@ import json
import re
import unittest
from datetime import timedelta # lint-amnesty, pylint: disable=unused-import
from unittest.mock import patch
import ddt
import six
@@ -18,14 +19,22 @@ from django.test.utils import override_settings
from django.urls import reverse
from django.utils.timezone import now
from milestones.tests.utils import MilestonesTestCaseMixin
from mock import patch
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from pyquery import PyQuery as pq
from six.moves import range
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.entitlements.tests.factories import CourseEntitlementFactory
from common.djangoapps.student.helpers import DISABLE_UNENROLL_CERT_STATES
from common.djangoapps.student.models import CourseEnrollment, UserProfile
from common.djangoapps.student.signals import REFUND_ORDER
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from common.djangoapps.util.milestones_helpers import ( # lint-amnesty, pylint: disable=line-too-long
get_course_milestones,
remove_prerequisite_course,
set_prerequisite_courses
)
from common.djangoapps.util.testing import UrlResetMixin
from lms.djangoapps.certificates.tests.factories import GeneratedCertificateFactory
from openedx.core.djangoapps.catalog.tests.factories import ProgramFactory
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
@@ -33,12 +42,6 @@ from openedx.core.djangoapps.content.course_overviews.tests.factories import Cou
from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration_context
from openedx.features.course_duration_limits.models import CourseDurationLimitConfig
from openedx.features.course_experience.tests.views.helpers import add_course_mode
from common.djangoapps.student.helpers import DISABLE_UNENROLL_CERT_STATES
from common.djangoapps.student.models import CourseEnrollment, UserProfile
from common.djangoapps.student.signals import REFUND_ORDER
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from common.djangoapps.util.milestones_helpers import get_course_milestones, remove_prerequisite_course, set_prerequisite_courses # lint-amnesty, pylint: disable=line-too-long
from common.djangoapps.util.testing import UrlResetMixin
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@@ -56,12 +59,12 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(TestStudentDashboardUnenrollments, cls).setUpClass()
super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
""" Create a course and user, then log in. """
super(TestStudentDashboardUnenrollments, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory()
self.enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user)
self.cert_status = 'processing'
@@ -193,7 +196,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
"""
Create a course and user, then log in.
"""
super(StudentDashboardTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory()
self.client.login(username=self.user.username, password=PASSWORD)
self.path = reverse('dashboard')
@@ -287,11 +290,11 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
org='edx',
number='998',
display_name='Test Course',
pre_requisite_courses=[six.text_type(self.pre_requisite_course.id)]
pre_requisite_courses=[str(self.pre_requisite_course.id)]
)
self.course_enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user) # lint-amnesty, pylint: disable=attribute-defined-outside-init
set_prerequisite_courses(self.course.id, [six.text_type(self.pre_requisite_course.id)])
set_prerequisite_courses(self.course.id, [str(self.pre_requisite_course.id)])
response = self.client.get(reverse('dashboard'))
self.assertContains(response, '<div class="prerequisites">')
@@ -319,7 +322,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
mock_course_overview.return_value = CourseOverviewFactory.create(start=self.TOMORROW, id=course_key)
mock_course_runs.return_value = [
{
'key': six.text_type(course_key),
'key': str(course_key),
'enrollment_end': str(self.TOMORROW),
'pacing_type': 'instructor_paced',
'type': 'verified',
@@ -327,7 +330,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
}
]
mock_pseudo_session.return_value = {
'key': six.text_type(course_key),
'key': str(course_key),
'type': 'verified'
}
response = self.client.get(self.path)
@@ -404,7 +407,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
start=self.TOMORROW, end=self.THREE_YEARS_FROM_NOW, self_paced=True, enrollment_end=self.THREE_YEARS_AGO
)
mock_course_overview.return_value = mocked_course_overview
course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=six.text_type(mocked_course_overview.id))
course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=str(mocked_course_overview.id))
mock_course_runs.return_value = [
{
'key': str(mocked_course_overview.id),
@@ -468,7 +471,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
start=self.TOMORROW, self_paced=True, enrollment_end=self.TOMORROW
)
mock_course_overview.return_value = mocked_course_overview
course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=six.text_type(mocked_course_overview.id))
course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=str(mocked_course_overview.id))
mock_course_runs.return_value = [
{
'key': str(mocked_course_overview.id),
@@ -480,7 +483,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
]
entitlement = CourseEntitlementFactory(user=self.user, enrollment_course_run=course_enrollment)
program = ProgramFactory()
program['courses'][0]['course_runs'] = [{'key': six.text_type(mocked_course_overview.id)}]
program['courses'][0]['course_runs'] = [{'key': str(mocked_course_overview.id)}]
program['courses'][0]['uuid'] = entitlement.course_uuid
mock_get_programs.return_value = [program]
response = self.client.get(self.path)
@@ -503,7 +506,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
start=self.TOMORROW, self_paced=True, enrollment_end=self.TOMORROW
)
mock_course_overview.return_value = mocked_course_overview
course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=six.text_type(mocked_course_overview.id), created=self.THREE_YEARS_AGO) # lint-amnesty, pylint: disable=line-too-long
course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=str(mocked_course_overview.id), created=self.THREE_YEARS_AGO) # lint-amnesty, pylint: disable=line-too-long
mock_course_runs.return_value = [
{
'key': str(mocked_course_overview.id),
@@ -515,7 +518,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
]
entitlement = CourseEntitlementFactory(user=self.user, enrollment_course_run=course_enrollment, created=self.THREE_YEARS_AGO) # lint-amnesty, pylint: disable=line-too-long
program = ProgramFactory()
program['courses'][0]['course_runs'] = [{'key': six.text_type(mocked_course_overview.id)}]
program['courses'][0]['course_runs'] = [{'key': str(mocked_course_overview.id)}]
program['courses'][0]['uuid'] = entitlement.course_uuid
mock_get_programs.return_value = [program]
response = self.client.get(self.path)
@@ -536,7 +539,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
course_enrollment = CourseEnrollmentFactory(user=self.user, course_id=course_overview.id)
entitlement = CourseEntitlementFactory(user=self.user, enrollment_course_run=course_enrollment)
course_runs = [{
'key': six.text_type(course_overview.id),
'key': str(course_overview.id),
'uuid': entitlement.course_uuid
}]
mock_get_course_runs.return_value = course_runs
@@ -722,7 +725,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
ItemFactory.create(
category='video',
parent_location=course.location,
display_name='Video {0}'.format(six.text_type(number))
display_name='Video {}'.format(str(number))
).location
for number in range(5)
]
@@ -823,7 +826,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
ItemFactory.create(
category='video',
parent_location=course.location,
display_name='Video {0}'.format(six.text_type(number))
display_name='Video {}'.format(str(number))
).location
for number in range(5)
]

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
"""
Miscellaneous tests for the student app.
"""
@@ -7,6 +6,7 @@ Miscellaneous tests for the student app.
import logging
import unittest
from datetime import datetime, timedelta
from unittest.mock import Mock, patch
from urllib.parse import quote
import ddt
@@ -18,13 +18,26 @@ from django.test import TestCase, override_settings
from django.test.client import Client
from django.urls import reverse
from markupsafe import escape
from mock import Mock, patch
from opaque_keys.edx.keys import CourseKey
from opaque_keys.edx.locations import CourseLocator
from pyquery import PyQuery as pq
from common.djangoapps.course_modes.models import CourseMode
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
from common.djangoapps.student.helpers import _cert_info, process_survey_link
from common.djangoapps.student.models import (
AnonymousUserId,
CourseEnrollment,
LinkedInAddToProfileConfiguration,
UserAttribute,
anonymous_id_for_user,
unique_id_for_user,
user_by_anonymous_id
)
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from common.djangoapps.student.views import complete_course_mode_info
from common.djangoapps.util.model_utils import USER_SETTINGS_CHANGED_EVENT_NAME
from common.djangoapps.util.testing import EventTestMixin
from lms.djangoapps.certificates.models import CertificateStatuses
from lms.djangoapps.certificates.tests.factories import GeneratedCertificateFactory
from lms.djangoapps.verify_student.tests import TestVerificationBase
@@ -34,20 +47,6 @@ from openedx.core.djangoapps.content.course_overviews.tests.factories import Cou
from openedx.core.djangoapps.programs.tests.mixins import ProgramsApiConfigMixin
from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms
from common.djangoapps.student.helpers import _cert_info, process_survey_link
from common.djangoapps.student.models import (
CourseEnrollment,
LinkedInAddToProfileConfiguration,
UserAttribute,
AnonymousUserId,
anonymous_id_for_user,
unique_id_for_user,
user_by_anonymous_id
)
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from common.djangoapps.student.views import complete_course_mode_info
from common.djangoapps.util.model_utils import USER_SETTINGS_CHANGED_EVENT_NAME
from common.djangoapps.util.testing import EventTestMixin
from xmodule.modulestore.tests.django_utils import ModuleStoreEnum, ModuleStoreTestCase, SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls
@@ -67,7 +66,7 @@ class CourseEndingTest(ModuleStoreTestCase):
assert process_survey_link(link1, user) == link1
link2 = "http://www.mysurvey.com?unique={UNIQUE_ID}"
link2_expected = "http://www.mysurvey.com?unique={UNIQUE_ID}".format(UNIQUE_ID=user_id)
link2_expected = f"http://www.mysurvey.com?unique={user_id}"
assert process_survey_link(link2, user) == link2_expected
@patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': False})
@@ -217,7 +216,7 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
ENABLED_SIGNALS = ['course_published']
def setUp(self):
super(DashboardTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create()
self.user = UserFactory.create(username="jack", email="jack@fake.edx.org", password='test')
self.client = Client()
@@ -240,7 +239,7 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
if mode in ['professional', 'no-id-professional']:
self.assertContains(response, 'class="course professional"')
else:
self.assertContains(response, 'class="course {0}"'.format(mode))
self.assertContains(response, f'class="course {mode}"')
self.assertContains(response, value)
@patch.dict("django.conf.settings.FEATURES", {'ENABLE_VERIFIED_CERTIFICATES': True})
@@ -277,7 +276,7 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
# Audit mode does not have a banner. Assert no banner element.
assert pq(response.content)('.sts-enrollment').length == 0
else:
self.assertNotContains(response, "class=\"course {0}\"".format(mode))
self.assertNotContains(response, f"class=\"course {mode}\"")
self.assertNotContains(response, value)
@patch.dict("django.conf.settings.FEATURES", {'ENABLE_VERIFIED_CERTIFICATES': False})
@@ -325,7 +324,7 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
self.course.start = datetime.now(pytz.UTC) - timedelta(days=2)
self.course.end = datetime.now(pytz.UTC) - timedelta(days=1)
self.course.display_name = u"Omega"
self.course.display_name = "Omega"
self.course = self.update_course(self.course, self.user.id)
download_url = 'www.edx.org'
@@ -485,7 +484,7 @@ class DashboardTestsWithSiteOverrides(SiteMixin, ModuleStoreTestCase):
"""
def setUp(self):
super(DashboardTestsWithSiteOverrides, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.org = 'fakeX'
self.course = CourseFactory.create(org=self.org)
self.user = UserFactory.create(username='jack', email='jack@fake.edx.org', password='test')
@@ -541,7 +540,7 @@ class UserSettingsEventTestMixin(EventTestMixin):
Mixin for verifying that user setting events were emitted during a test.
"""
def setUp(self): # lint-amnesty, pylint: disable=arguments-differ
super(UserSettingsEventTestMixin, self).setUp('common.djangoapps.util.model_utils.tracker') # lint-amnesty, pylint: disable=super-with-arguments
super().setUp('common.djangoapps.util.model_utils.tracker')
def assert_user_setting_event_emitted(self, **kwargs):
"""
@@ -568,7 +567,7 @@ class UserSettingsEventTestMixin(EventTestMixin):
class EnrollmentEventTestMixin(EventTestMixin):
""" Mixin with assertions for validating enrollment events. """
def setUp(self): # lint-amnesty, pylint: disable=arguments-differ
super(EnrollmentEventTestMixin, self).setUp('common.djangoapps.student.models.tracker') # lint-amnesty, pylint: disable=super-with-arguments
super().setUp('common.djangoapps.student.models.tracker')
def assert_enrollment_mode_change_event_was_emitted(self, user, course_key, mode):
"""Ensures an enrollment mode change event was emitted"""
@@ -794,7 +793,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
"""Tests the student.views.change_enrollment view"""
def setUp(self):
super(ChangeEnrollmentViewTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create()
self.user = UserFactory.create(password='secret')
self.client.login(username=self.user.username, password='secret')
@@ -836,7 +835,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
Tests that a student that is a currently enrolled verified student cannot
accidentally change their enrollment mode
"""
CourseEnrollment.enroll(self.user, self.course.id, mode=u'verified')
CourseEnrollment.enroll(self.user, self.course.id, mode='verified')
assert CourseEnrollment.is_enrolled(self.user, self.course.id)
# now try to enroll the student in the default mode:
response = self._enroll_through_view(self.course)
@@ -845,14 +844,14 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
self.user, self.course.id
)
assert is_active
assert enrollment_mode == u'verified'
assert enrollment_mode == 'verified'
def test_change_to_default_if_verified_not_active(self):
"""
Tests that one can renroll for a course if one has already unenrolled
"""
# enroll student
CourseEnrollment.enroll(self.user, self.course.id, mode=u'verified')
CourseEnrollment.enroll(self.user, self.course.id, mode='verified')
# now unenroll student:
CourseEnrollment.unenroll(self.user, self.course.id)
# check that they are verified but inactive
@@ -860,7 +859,7 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
self.user, self.course.id
)
assert not is_active
assert enrollment_mode == u'verified'
assert enrollment_mode == 'verified'
# now enroll them through the view:
response = self._enroll_through_view(self.course)
assert response.status_code == 200
@@ -876,7 +875,7 @@ class AnonymousLookupTable(ModuleStoreTestCase):
Tests for anonymous_id_functions
"""
def setUp(self):
super(AnonymousLookupTable, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.course = CourseFactory.create()
self.user = UserFactory.create()
CourseModeFactory.create(
@@ -916,7 +915,7 @@ class AnonymousLookupTable(ModuleStoreTestCase):
assert anonymous_id == anonymous_id_for_user(self.user, self.course.id)
def test_roundtrip_with_unicode_course_id(self):
course2 = CourseFactory.create(display_name=u"Omega Course Ω")
course2 = CourseFactory.create(display_name="Omega Course Ω")
CourseEnrollment.enroll(self.user, course2.id)
anonymous_id = anonymous_id_for_user(self.user, course2.id)
real_user = user_by_anonymous_id(anonymous_id)
@@ -958,14 +957,14 @@ class RelatedProgramsTests(ProgramsApiConfigMixin, SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super(RelatedProgramsTests, cls).setUpClass()
super().setUpClass()
cls.user = UserFactory()
cls.course = CourseFactory()
cls.enrollment = CourseEnrollmentFactory(user=cls.user, course_id=cls.course.id) # pylint: disable=no-member
def setUp(self):
super(RelatedProgramsTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.url = reverse('dashboard')
@@ -987,7 +986,7 @@ class RelatedProgramsTests(ProgramsApiConfigMixin, SharedModuleStoreTestCase):
def expected_link_text(self, program):
"""Construct expected dashboard link text."""
return u'{title} {type}'.format(title=program['title'], type=program['type'])
return '{title} {type}'.format(title=program['title'], type=program['type'])
def test_related_programs_listed(self, mock_get_programs):
"""Verify that related programs are listed when available."""
@@ -1019,7 +1018,7 @@ class RelatedProgramsTests(ProgramsApiConfigMixin, SharedModuleStoreTestCase):
def test_program_title_unicode(self, mock_get_programs):
"""Verify that the dashboard can deal with programs whose titles contain Unicode."""
self.programs[0]['title'] = u'Bases matemáticas para estudiar ingeniería'
self.programs[0]['title'] = 'Bases matemáticas para estudiar ingeniería'
mock_get_programs.return_value = self.programs
response = self.client.get(self.url)
@@ -1030,7 +1029,7 @@ class UserAttributeTests(TestCase):
"""Tests for the UserAttribute model."""
def setUp(self):
super(UserAttributeTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
super().setUp()
self.user = UserFactory()
self.name = 'test'
self.value = 'test-value'

View File

@@ -19,7 +19,7 @@ urlpatterns = [
url(r'^change_email_settings$', views.change_email_settings, name='change_email_settings'),
url(r'^course_run/{}/refund_status$'.format(settings.COURSE_ID_PATTERN),
url(fr'^course_run/{settings.COURSE_ID_PATTERN}/refund_status$',
views.course_run_refund_status,
name="course_run_refund_status"),

View File

@@ -62,7 +62,7 @@ from xmodule.modulestore.django import modulestore
log = logging.getLogger("edx.student")
experiments_namespace = LegacyWaffleFlagNamespace(name=u'student.experiments')
experiments_namespace = LegacyWaffleFlagNamespace(name='student.experiments')
def get_org_black_and_whitelist_for_site():
@@ -402,10 +402,10 @@ def _credit_statuses(user, course_enrollments):
statuses = {}
for eligibility in credit_api.get_eligibilities_for_user(user.username):
course_key = CourseKey.from_string(text_type(eligibility["course_key"]))
course_key = CourseKey.from_string(str(eligibility["course_key"]))
providers_names = get_credit_provider_attribute_values(course_key, 'display_name')
status = {
"course_key": text_type(course_key),
"course_key": str(course_key),
"eligible": True,
"deadline": eligibility["deadline"],
"purchased": course_key in credit_enrollments,
@@ -425,10 +425,10 @@ def _credit_statuses(user, course_enrollments):
if provider_id is None:
status["error"] = True
log.error(
u"Could not find credit provider associated with credit enrollment "
u"for user %s in course %s. The user will not be able to see their "
u"credit request status on the student dashboard. This attribute should "
u"have been set when the user purchased credit in the course.",
"Could not find credit provider associated with credit enrollment "
"for user %s in course %s. The user will not be able to see their "
"credit request status on the student dashboard. This attribute should "
"have been set when the user purchased credit in the course.",
user.id, course_key
)
else:
@@ -440,8 +440,8 @@ def _credit_statuses(user, course_enrollments):
if not status["provider_name"] and not status["provider_status_url"]:
status["error"] = True
log.error(
u"Could not find credit provider info for [%s] in [%s]. The user will not "
u"be able to see their credit request status on the student dashboard.",
"Could not find credit provider info for [%s] in [%s]. The user will not "
"be able to see their credit request status on the student dashboard.",
provider_id, provider_info_by_id
)
@@ -548,7 +548,7 @@ def student_dashboard(request): # lint-amnesty, pylint: disable=too-many-statem
mode.slug: mode
for mode in modes
}
for course_id, modes in iteritems(unexpired_course_modes)
for course_id, modes in unexpired_course_modes.items()
}
# Check to see if the student has recently enrolled in a course.
@@ -638,7 +638,7 @@ def student_dashboard(request): # lint-amnesty, pylint: disable=too-many-statem
inverted_programs = meter.invert_programs()
urls, programs_data = {}, {}
bundles_on_dashboard_flag = LegacyWaffleFlag(experiments_namespace, u'bundles_on_dashboard', __name__)
bundles_on_dashboard_flag = LegacyWaffleFlag(experiments_namespace, 'bundles_on_dashboard', __name__)
# TODO: Delete this code and the relevant HTML code after testing LEARNER-3072 is complete
if bundles_on_dashboard_flag.is_enabled() and inverted_programs and list(inverted_programs.items()):

View File

@@ -104,7 +104,7 @@ def csrf_token(context):
token = context.get('csrf_token', '')
if token == 'NOTPROVIDED':
return ''
return (HTML(u'<div style="display:none"><input type="hidden"'
return (HTML('<div style="display:none"><input type="hidden"'
' name="csrfmiddlewaretoken" value="{}" /></div>').format(Text(token)))
@@ -241,7 +241,7 @@ def course_run_refund_status(request, course_id):
return JsonResponse({'course_refundable_status': ''}, status=406)
refundable_status = course_enrollment.refundable()
logging.info("Course refund status for course {0} is {1}".format(course_id, refundable_status))
logging.info(f"Course refund status for course {course_id} is {refundable_status}")
return JsonResponse({'course_refundable_status': refundable_status}, status=200)
@@ -308,7 +308,7 @@ def change_enrollment(request, check_access=True):
course_id = CourseKey.from_string(request.POST.get("course_id"))
except InvalidKeyError:
log.warning(
u"User %s tried to %s with invalid course id: %s",
"User %s tried to %s with invalid course id: %s",
user.username,
action,
request.POST.get("course_id"),
@@ -317,14 +317,14 @@ def change_enrollment(request, check_access=True):
# Allow us to monitor performance of this transaction on a per-course basis since we often roll-out features
# on a per-course basis.
monitoring_utils.set_custom_attribute('course_id', text_type(course_id))
monitoring_utils.set_custom_attribute('course_id', str(course_id))
if action == "enroll":
# Make sure the course exists
# We don't do this check on unenroll, or a bad course id can't be unenrolled from
if not modulestore().has_course(course_id):
log.warning(
u"User %s tried to enroll in non-existent course %s",
"User %s tried to enroll in non-existent course %s",
user.username,
course_id
)
@@ -348,7 +348,7 @@ def change_enrollment(request, check_access=True):
return HttpResponse(redirect_url)
if CourseEntitlement.check_for_existing_entitlement_and_enroll(user=user, course_run_key=course_id):
return HttpResponse(reverse('courseware', args=[six.text_type(course_id)]))
return HttpResponse(reverse('courseware', args=[str(course_id)]))
# Check that auto enrollment is allowed for this course
# (= the course is NOT behind a paywall)
@@ -372,7 +372,7 @@ def change_enrollment(request, check_access=True):
# funnels users directly into the verification / payment flow)
if CourseMode.has_verified_mode(available_modes) or CourseMode.has_professional_mode(available_modes):
return HttpResponse(
reverse("course_modes_choose", kwargs={'course_id': text_type(course_id)})
reverse("course_modes_choose", kwargs={'course_id': str(course_id)})
)
# Otherwise, there is only one mode available (the default)
@@ -454,11 +454,11 @@ def disable_account_ajax(request):
if account_action == 'disable':
user_account.account_status = UserStanding.ACCOUNT_DISABLED
context['message'] = _("Successfully disabled {}'s account").format(username)
log.info(u"%s disabled %s's account", request.user, username)
log.info("%s disabled %s's account", request.user, username)
elif account_action == 'reenable':
user_account.account_status = UserStanding.ACCOUNT_ENABLED
context['message'] = _("Successfully reenabled {}'s account").format(username)
log.info(u"%s reenabled %s's account", request.user, username)
log.info("%s reenabled %s's account", request.user, username)
else:
context['message'] = _("Unexpected account status")
return JsonResponse(context, status=400)
@@ -479,7 +479,7 @@ def user_signup_handler(sender, **kwargs): # pylint: disable=unused-argument
if site:
user_signup_source = UserSignupSource(user=kwargs['instance'], site=site)
user_signup_source.save()
log.info(u'user {} originated from a white labeled "Microsite"'.format(kwargs['instance'].id))
log.info('user {} originated from a white labeled "Microsite"'.format(kwargs['instance'].id))
@ensure_csrf_cookie
@@ -488,7 +488,7 @@ def activate_account(request, key):
When link in activation e-mail is clicked
"""
# If request is in Studio call the appropriate view
if theming_helpers.get_project_root_name().lower() == u'cms':
if theming_helpers.get_project_root_name().lower() == 'cms':
monitoring_utils.set_custom_attribute('student_activate_account', 'cms')
return activate_account_studio(request, key)
@@ -558,7 +558,7 @@ def activate_account(request, key):
)
if should_redirect_to_authn_microfrontend() and not request.user.is_authenticated:
url_path = '/login?account_activation_status={}'.format(activation_message_type)
url_path = f'/login?account_activation_status={activation_message_type}'
return redirect(settings.AUTHN_MICROFRONTEND_URL + url_path)
return redirect('dashboard')
@@ -692,7 +692,7 @@ def do_email_change_request(user, new_email, activation_key=None, secondary_emai
ace.send(msg)
except Exception:
from_address = configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
log.error(u'Unable to send email activation link to user from "%s"', from_address, exc_info=True)
log.error('Unable to send email activation link to user from "%s"', from_address, exc_info=True)
raise ValueError(_('Unable to send email activation link. Please try again later.')) # lint-amnesty, pylint: disable=raise-missing-from
if not secondary_email_change_request:
@@ -838,7 +838,7 @@ def change_email_settings(request):
if optout_object:
optout_object.delete()
log.info(
u"User %s (%s) opted in to receive emails from course %s",
"User %s (%s) opted in to receive emails from course %s",
user.username,
user.email,
course_id,
@@ -852,7 +852,7 @@ def change_email_settings(request):
else:
Optout.objects.get_or_create(user=user, course_id=course_key)
log.info(
u"User %s (%s) opted out of receiving emails from course %s",
"User %s (%s) opted out of receiving emails from course %s",
user.username,
user.email,
course_id,