diff --git a/lms/djangoapps/survey/admin.py b/lms/djangoapps/survey/admin.py
index 69d63257f1..50a3bc0cc7 100644
--- a/lms/djangoapps/survey/admin.py
+++ b/lms/djangoapps/survey/admin.py
@@ -12,7 +12,7 @@ from lms.djangoapps.survey.models import SurveyForm
class SurveyFormAdminForm(forms.ModelForm):
"""Form providing validation of SurveyForm content."""
- class Meta(object):
+ class Meta:
model = SurveyForm
fields = ('name', 'form')
diff --git a/lms/djangoapps/survey/migrations/0001_initial.py b/lms/djangoapps/survey/migrations/0001_initial.py
index 91f3cc5316..1fc7e579e1 100644
--- a/lms/djangoapps/survey/migrations/0001_initial.py
+++ b/lms/djangoapps/survey/migrations/0001_initial.py
@@ -1,7 +1,3 @@
-# -*- coding: utf-8 -*-
-
-
-
from django.db import migrations, models
import django.utils.timezone
from django.conf import settings
diff --git a/lms/djangoapps/survey/models.py b/lms/djangoapps/survey/models.py
index c978bc7c36..1f234fcf33 100644
--- a/lms/djangoapps/survey/models.py
+++ b/lms/djangoapps/survey/models.py
@@ -13,9 +13,9 @@ from lxml import etree
from model_utils.models import TimeStampedModel
from opaque_keys.edx.django.models import CourseKeyField
-from openedx.core.djangolib.markup import HTML
from common.djangoapps.student.models import User
from lms.djangoapps.survey.exceptions import SurveyFormNameAlreadyExists, SurveyFormNotFound
+from openedx.core.djangolib.markup import HTML
log = logging.getLogger("edx.survey")
@@ -33,7 +33,7 @@ class SurveyForm(TimeStampedModel):
name = models.CharField(max_length=255, db_index=True, unique=True)
form = models.TextField()
- class Meta(object):
+ class Meta:
app_label = 'survey'
def __str__(self):
@@ -48,7 +48,7 @@ class SurveyForm(TimeStampedModel):
self.validate_form_html(self.form)
# now call the actual save method
- super(SurveyForm, self).save(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().save(*args, **kwargs)
@classmethod
def validate_form_html(cls, html):
@@ -58,8 +58,8 @@ class SurveyForm(TimeStampedModel):
try:
fields = cls.get_field_names_from_html(html)
except Exception as ex:
- log.exception(u"Cannot parse SurveyForm html: {}".format(ex))
- raise ValidationError(u"Cannot parse SurveyForm as HTML: {}".format(ex)) # lint-amnesty, pylint: disable=raise-missing-from
+ log.exception(f"Cannot parse SurveyForm html: {ex}")
+ raise ValidationError(f"Cannot parse SurveyForm as HTML: {ex}") # lint-amnesty, pylint: disable=raise-missing-from
if not len(fields): # lint-amnesty, pylint: disable=len-as-condition
raise ValidationError("SurveyForms must contain at least one form input field")
@@ -152,7 +152,7 @@ class SurveyForm(TimeStampedModel):
# make sure the form is wrap in some outer single element
# otherwise lxml can't parse it
# NOTE: This wrapping doesn't change the ability to query it
- tree = etree.fromstring(HTML(u'
{}
').format(HTML(html)))
+ tree = etree.fromstring(HTML('{}
').format(HTML(html)))
input_fields = (
tree.findall('.//input') + tree.findall('.//select') +
@@ -183,7 +183,7 @@ class SurveyAnswer(TimeStampedModel):
# since it didn't exist in the beginning, it is nullable
course_key = CourseKeyField(max_length=255, db_index=True, null=True)
- class Meta(object):
+ class Meta:
app_label = 'survey'
@classmethod
diff --git a/lms/djangoapps/survey/signals.py b/lms/djangoapps/survey/signals.py
index 8e13f6f2ee..c43238e927 100644
--- a/lms/djangoapps/survey/signals.py
+++ b/lms/djangoapps/survey/signals.py
@@ -5,8 +5,8 @@ Signal handlers for the survey app
from django.dispatch.dispatcher import receiver
-from openedx.core.djangoapps.user_api.accounts.signals import USER_RETIRE_LMS_MISC
from lms.djangoapps.survey.models import SurveyAnswer
+from openedx.core.djangoapps.user_api.accounts.signals import USER_RETIRE_LMS_MISC
@receiver(USER_RETIRE_LMS_MISC)
diff --git a/lms/djangoapps/survey/tests/factories.py b/lms/djangoapps/survey/tests/factories.py
index f65732d000..dd3c35b35e 100644
--- a/lms/djangoapps/survey/tests/factories.py
+++ b/lms/djangoapps/survey/tests/factories.py
@@ -6,7 +6,7 @@ from lms.djangoapps.survey.models import SurveyAnswer, SurveyForm
class SurveyFormFactory(factory.DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
- class Meta(object):
+ class Meta:
model = SurveyForm
name = 'Test Survey Form'
@@ -14,7 +14,7 @@ class SurveyFormFactory(factory.DjangoModelFactory): # lint-amnesty, pylint: di
class SurveyAnswerFactory(factory.DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
- class Meta(object):
+ class Meta:
model = SurveyAnswer
user = factory.SubFactory(UserFactory)
diff --git a/lms/djangoapps/survey/tests/test_models.py b/lms/djangoapps/survey/tests/test_models.py
index d15e6f1a55..4c00cd0d24 100644
--- a/lms/djangoapps/survey/tests/test_models.py
+++ b/lms/djangoapps/survey/tests/test_models.py
@@ -4,8 +4,9 @@ Python tests for the Survey models
from collections import OrderedDict
-import pytest
+
import ddt
+import pytest
import six
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.exceptions import ValidationError
@@ -26,7 +27,7 @@ class SurveyModelsTests(TestCase):
"""
Set up the test data used in the specific tests
"""
- super(SurveyModelsTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.client = Client()
# Create two accounts
@@ -96,7 +97,7 @@ class SurveyModelsTests(TestCase):
"""
survey = self._create_test_survey()
assert survey is not None
- assert six.text_type(survey) == self.test_survey_name
+ assert str(survey) == self.test_survey_name
def test_create_form_with_malformed_html(self):
"""
@@ -189,7 +190,7 @@ class SurveyModelsTests(TestCase):
for answer_obj in answer_objs:
if course_id:
- assert six.text_type(answer_obj.course_key) == course_id
+ assert str(answer_obj.course_key) == course_id
else:
assert answer_obj.course_key is None
diff --git a/lms/djangoapps/survey/tests/test_signals.py b/lms/djangoapps/survey/tests/test_signals.py
index a08f4b8bf8..fb4ae8ea7d 100644
--- a/lms/djangoapps/survey/tests/test_signals.py
+++ b/lms/djangoapps/survey/tests/test_signals.py
@@ -3,11 +3,11 @@ Test signal handlers for the survey app
"""
-from lms.djangoapps.survey.signals import _listen_for_lms_retire
-from openedx.core.djangoapps.user_api.accounts.tests.retirement_helpers import fake_completed_retirement
from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.survey.models import SurveyAnswer
+from lms.djangoapps.survey.signals import _listen_for_lms_retire
from lms.djangoapps.survey.tests.factories import SurveyAnswerFactory
+from openedx.core.djangoapps.user_api.accounts.tests.retirement_helpers import fake_completed_retirement
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
diff --git a/lms/djangoapps/survey/tests/test_utils.py b/lms/djangoapps/survey/tests/test_utils.py
index 326b97367d..3a312cc8bd 100644
--- a/lms/djangoapps/survey/tests/test_utils.py
+++ b/lms/djangoapps/survey/tests/test_utils.py
@@ -23,7 +23,7 @@ class SurveyModelsTests(ModuleStoreTestCase):
"""
Set up the test data used in the specific tests
"""
- super(SurveyModelsTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.client = Client()
diff --git a/lms/djangoapps/survey/tests/test_views.py b/lms/djangoapps/survey/tests/test_views.py
index 3d5be2bb35..55910a3210 100644
--- a/lms/djangoapps/survey/tests/test_views.py
+++ b/lms/djangoapps/survey/tests/test_views.py
@@ -25,7 +25,7 @@ class SurveyViewsTests(ModuleStoreTestCase):
"""
Set up the test data used in the specific tests
"""
- super(SurveyViewsTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.client = Client()
@@ -40,10 +40,10 @@ class SurveyViewsTests(ModuleStoreTestCase):
'''
self.student_answers = OrderedDict({
- u'field1': u'value1',
- u'field2': u'value2',
- u'ddl': u'1',
- u'textarea': u'textarea'
+ 'field1': 'value1',
+ 'field2': 'value2',
+ 'ddl': '1',
+ 'textarea': 'textarea'
})
self.course = CourseFactory.create(
@@ -130,7 +130,7 @@ class SurveyViewsTests(ModuleStoreTestCase):
data['csrfmiddlewaretoken'] = 'foo'
data['_redirect_url'] = 'bar'
- data['course_id'] = six.text_type(self.course.id)
+ data['course_id'] = str(self.course.id)
resp = self.client.post(
self.postback_url,
@@ -149,7 +149,7 @@ class SurveyViewsTests(ModuleStoreTestCase):
)
for answer_obj in answer_objs:
- assert six.text_type(answer_obj.course_key) == data['course_id']
+ assert str(answer_obj.course_key) == data['course_id']
def test_encoding_answers(self):
"""
diff --git a/lms/djangoapps/survey/utils.py b/lms/djangoapps/survey/utils.py
index 246c573d69..889fc90c11 100644
--- a/lms/djangoapps/survey/utils.py
+++ b/lms/djangoapps/survey/utils.py
@@ -16,9 +16,9 @@ class SurveyRequiredAccessError(AccessError):
"""
def __init__(self):
error_code = "survey_required"
- developer_message = u"User must complete a survey"
- user_message = _(u"You must complete a survey")
- super(SurveyRequiredAccessError, self).__init__(error_code, developer_message, user_message) # lint-amnesty, pylint: disable=super-with-arguments
+ developer_message = "User must complete a survey"
+ user_message = _("You must complete a survey")
+ super().__init__(error_code, developer_message, user_message)
def is_survey_required_for_course(course_descriptor):
diff --git a/lms/djangoapps/survey/views.py b/lms/djangoapps/survey/views.py
index b0362ce540..c6a3b56979 100644
--- a/lms/djangoapps/survey/views.py
+++ b/lms/djangoapps/survey/views.py
@@ -15,8 +15,8 @@ from django.views.decorators.http import require_POST
from opaque_keys.edx.keys import CourseKey
from common.djangoapps.edxmako.shortcuts import render_to_response
-from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from lms.djangoapps.survey.models import SurveyForm
+from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
log = logging.getLogger("edx.survey")
diff --git a/lms/djangoapps/teams/api.py b/lms/djangoapps/teams/api.py
index f0f0fe8668..d8297d8ac9 100644
--- a/lms/djangoapps/teams/api.py
+++ b/lms/djangoapps/teams/api.py
@@ -11,12 +11,12 @@ from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from common.djangoapps.course_modes.models import CourseMode
+from common.djangoapps.student.models import CourseEnrollment, anonymous_id_for_user
+from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole
from lms.djangoapps.courseware.courses import has_access
from lms.djangoapps.discussion.django_comment_client.utils import has_discussion_privileges
from lms.djangoapps.teams.models import CourseTeam, CourseTeamMembership
from openedx.core.lib.teams_config import TeamsetType
-from common.djangoapps.student.models import CourseEnrollment, anonymous_id_for_user
-from common.djangoapps.student.roles import CourseInstructorRole, CourseStaffRole
from xmodule.modulestore.django import modulestore
logger = logging.getLogger(__name__)
@@ -349,7 +349,7 @@ def get_team_for_user_course_topic(user, course_id, topic_id):
try:
course_key = CourseKey.from_string(course_id)
except InvalidKeyError:
- raise ValueError(u"The supplied course id {course_id} is not valid.".format( # lint-amnesty, pylint: disable=raise-missing-from
+ raise ValueError("The supplied course id {course_id} is not valid.".format( # lint-amnesty, pylint: disable=raise-missing-from
course_id=course_id
))
try:
diff --git a/lms/djangoapps/teams/csv.py b/lms/djangoapps/teams/csv.py
index e6c672d2e4..d6b6045c6d 100644
--- a/lms/djangoapps/teams/csv.py
+++ b/lms/djangoapps/teams/csv.py
@@ -8,15 +8,16 @@ from collections import Counter
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.db.models import Prefetch
+from common.djangoapps.student.models import CourseEnrollment
+from lms.djangoapps.program_enrollments.models import ProgramCourseEnrollment, ProgramEnrollment
from lms.djangoapps.teams.api import (
+ ORGANIZATION_PROTECTED_MODES,
OrganizationProtectionStatus,
user_organization_protection_status,
- ORGANIZATION_PROTECTED_MODES,
user_protection_status_matches_team
)
from lms.djangoapps.teams.models import CourseTeam, CourseTeamMembership
-from lms.djangoapps.program_enrollments.models import ProgramCourseEnrollment, ProgramEnrollment
-from common.djangoapps.student.models import CourseEnrollment
+
from .utils import emit_team_event
@@ -141,7 +142,7 @@ def _group_teamset_memberships_by_user(course_team_memberships):
return teamset_memberships_by_user
-class TeamMembershipImportManager(object):
+class TeamMembershipImportManager:
"""
A manager class that is responsible the import process of csv file including validation and creation of
team_courseteam and teams_courseteammembership objects.
@@ -170,7 +171,7 @@ class TeamMembershipImportManager(object):
"""
Parse an input CSV file and pass to `set_team_memberships` for processing
"""
- csv_reader = csv.DictReader((line.decode('utf-8-sig').strip() for line in input_file.readlines()))
+ csv_reader = csv.DictReader(line.decode('utf-8-sig').strip() for line in input_file.readlines())
return self.set_team_memberships(csv_reader)
def set_team_memberships(self, csv_reader):
@@ -299,7 +300,7 @@ class TeamMembershipImportManager(object):
Ensures that username exists only once in an input file
"""
if username in usernames_found_so_far:
- error_message = 'Username {} listed more than once in file.'.format(username)
+ error_message = f'Username {username} listed more than once in file.'
if self.add_error_and_check_if_max_exceeded(error_message):
return False
return True
@@ -314,7 +315,7 @@ class TeamMembershipImportManager(object):
This method will add a validation error and return False if this is the case.
"""
if None in row:
- error_message = "Team(s) {0} don't have matching teamsets.".format(
+ error_message = "Team(s) {} don't have matching teamsets.".format(
row[None]
)
if self.add_error_and_check_if_max_exceeded(error_message):
@@ -374,7 +375,7 @@ class TeamMembershipImportManager(object):
if self.is_FERPA_bubble_breached(teamset_id, team_name) or \
not self.is_enrollment_protection_for_existing_team_matches_user(user, team_name, teamset_id):
error_message = \
- 'Team {} cannot have Master’s track users mixed with users in other tracks.'.format(team_name)
+ f'Team {team_name} cannot have Master’s track users mixed with users in other tracks.'
self.add_error_and_check_if_max_exceeded(error_message)
return False
return True
diff --git a/lms/djangoapps/teams/management/commands/reindex_course_team.py b/lms/djangoapps/teams/management/commands/reindex_course_team.py
index 6f047877df..486325a569 100644
--- a/lms/djangoapps/teams/management/commands/reindex_course_team.py
+++ b/lms/djangoapps/teams/management/commands/reindex_course_team.py
@@ -8,7 +8,6 @@ from textwrap import dedent
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.core.management import BaseCommand, CommandError
-from six.moves import map
from lms.djangoapps.teams.models import CourseTeam
@@ -38,7 +37,7 @@ class Command(BaseCommand):
try:
result = CourseTeam.objects.get(team_id=team_id)
except ObjectDoesNotExist:
- raise CommandError('Argument {} is not a course_team team_id'.format(team_id)) # lint-amnesty, pylint: disable=raise-missing-from
+ raise CommandError(f'Argument {team_id} is not a course_team team_id') # lint-amnesty, pylint: disable=raise-missing-from
return result
@@ -67,5 +66,5 @@ class Command(BaseCommand):
course_teams = list(map(self._get_course_team, options['course_team_ids']))
for course_team in course_teams:
- print('Indexing {}'.format(course_team.team_id))
+ print(f'Indexing {course_team.team_id}')
CourseTeamIndexer.index(course_team)
diff --git a/lms/djangoapps/teams/management/commands/tests/test_reindex_course_team.py b/lms/djangoapps/teams/management/commands/tests/test_reindex_course_team.py
index 10b289d039..7ddd2f6249 100644
--- a/lms/djangoapps/teams/management/commands/tests/test_reindex_course_team.py
+++ b/lms/djangoapps/teams/management/commands/tests/test_reindex_course_team.py
@@ -3,9 +3,10 @@ Tests for course_team reindex command.
"""
+from unittest.mock import patch
+
import ddt
from django.core.management import CommandError, call_command
-from mock import patch
from opaque_keys.edx.keys import CourseKey
from search.search_engine_base import SearchEngine
@@ -27,7 +28,7 @@ class ReindexCourseTeamTest(SharedModuleStoreTestCase):
"""
Set up tests.
"""
- super(ReindexCourseTeamTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.team1 = CourseTeamFactory(course_id=COURSE_KEY1, team_id='team1')
self.team2 = CourseTeamFactory(course_id=COURSE_KEY1, team_id='team2')
@@ -61,8 +62,8 @@ class ReindexCourseTeamTest(SharedModuleStoreTestCase):
"""
Test that raises CommandError for invalid team id.
"""
- team_id = u'team4'
- error_str = u'Argument {} is not a course_team team_id'.format(team_id)
+ team_id = 'team4'
+ error_str = f'Argument {team_id} is not a course_team team_id'
with self.assertRaisesRegex(CommandError, error_str):
call_command('reindex_course_team', team_id)
diff --git a/lms/djangoapps/teams/migrations/0001_initial.py b/lms/djangoapps/teams/migrations/0001_initial.py
index 1fdc9a60cf..6c68802753 100644
--- a/lms/djangoapps/teams/migrations/0001_initial.py
+++ b/lms/djangoapps/teams/migrations/0001_initial.py
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-
-
import django_countries.fields
from django.conf import settings
from django.db import migrations, models
@@ -50,6 +47,6 @@ class Migration(migrations.Migration):
),
migrations.AlterUniqueTogether(
name='courseteammembership',
- unique_together=set([('user', 'team')]),
+ unique_together={('user', 'team')},
),
]
diff --git a/lms/djangoapps/teams/migrations/0002_slug_field_ids.py b/lms/djangoapps/teams/migrations/0002_slug_field_ids.py
index 834f51c449..9dbec7acdc 100644
--- a/lms/djangoapps/teams/migrations/0002_slug_field_ids.py
+++ b/lms/djangoapps/teams/migrations/0002_slug_field_ids.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Generated by Django 1.11.25 on 2019-10-22 14:42
diff --git a/lms/djangoapps/teams/migrations/0003_courseteam_organization_protected.py b/lms/djangoapps/teams/migrations/0003_courseteam_organization_protected.py
index 9c201539da..353a2c92b7 100644
--- a/lms/djangoapps/teams/migrations/0003_courseteam_organization_protected.py
+++ b/lms/djangoapps/teams/migrations/0003_courseteam_organization_protected.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Generated by Django 1.11.25 on 2019-11-04 19:15
diff --git a/lms/djangoapps/teams/migrations/0004_alter_defaults.py b/lms/djangoapps/teams/migrations/0004_alter_defaults.py
index 28a878812c..6148090422 100644
--- a/lms/djangoapps/teams/migrations/0004_alter_defaults.py
+++ b/lms/djangoapps/teams/migrations/0004_alter_defaults.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2020-03-18 15:36
diff --git a/lms/djangoapps/teams/models.py b/lms/djangoapps/teams/models.py
index 24fde748d8..7eb6c64de7 100644
--- a/lms/djangoapps/teams/models.py
+++ b/lms/djangoapps/teams/models.py
@@ -18,6 +18,7 @@ from django_countries.fields import CountryField
from model_utils import FieldTracker
from opaque_keys.edx.django.models import CourseKeyField
+from common.djangoapps.student.models import CourseEnrollment, LanguageField
from lms.djangoapps.teams import TEAM_DISCUSSION_CONTEXT
from lms.djangoapps.teams.utils import emit_team_event
from openedx.core.djangoapps.django_comment_common.signals import (
@@ -33,13 +34,12 @@ from openedx.core.djangoapps.django_comment_common.signals import (
thread_unfollowed,
thread_voted
)
-from common.djangoapps.student.models import CourseEnrollment, LanguageField
from .errors import (
+ AddToIncompatibleTeamError,
AlreadyOnTeamInTeamset,
ImmutableMembershipFieldException,
- NotEnrolledInCourseForTeam,
- AddToIncompatibleTeamError
+ NotEnrolledInCourseForTeam
)
@@ -112,7 +112,7 @@ class CourseTeam(models.Model):
.. no_pii:
"""
def __str__(self):
- return "{} in {}".format(self.name, self.course_id)
+ return f"{self.name} in {self.course_id}"
def __repr__(self):
return ( # lint-amnesty, pylint: disable=missing-format-attribute
@@ -125,7 +125,7 @@ class CourseTeam(models.Model):
">"
).format(self)
- class Meta(object):
+ class Meta:
app_label = "teams"
team_id = models.SlugField(max_length=255, unique=True)
@@ -233,7 +233,7 @@ class CourseTeamMembership(models.Model):
"""
def __str__(self):
- return "{} is member of {}".format(self.user.username, self.team)
+ return f"{self.user.username} is member of {self.team}"
def __repr__(self):
return ( # lint-amnesty, pylint: disable=missing-format-attribute
@@ -244,7 +244,7 @@ class CourseTeamMembership(models.Model):
">"
).format(self)
- class Meta(object):
+ class Meta:
app_label = "teams"
unique_together = (('user', 'team'),)
@@ -275,9 +275,9 @@ class CourseTeamMembership(models.Model):
# Allow it *only* if the current value is None.
if current_value is not None:
raise ImmutableMembershipFieldException(
- u"Field %r shouldn't change from %r to %r" % (name, current_value, value)
+ f"Field {name!r} shouldn't change from {current_value!r} to {value!r}"
)
- super(CourseTeamMembership, self).__setattr__(name, value) # lint-amnesty, pylint: disable=super-with-arguments
+ super().__setattr__(name, value)
def save(self, *args, **kwargs): # lint-amnesty, pylint: disable=arguments-differ, signature-differs
"""Customize save method to set the last_activity_at if it does not
@@ -289,13 +289,13 @@ class CourseTeamMembership(models.Model):
should_reset_team_size = True
if not self.last_activity_at:
self.last_activity_at = datetime.utcnow().replace(tzinfo=pytz.utc)
- super(CourseTeamMembership, self).save(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().save(*args, **kwargs)
if should_reset_team_size:
self.team.reset_team_size()
def delete(self, *args, **kwargs): # lint-amnesty, pylint: disable=arguments-differ, signature-differs
"""Recompute the related team's team_size after deleting a membership"""
- super(CourseTeamMembership, self).delete(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().delete(*args, **kwargs)
self.team.reset_team_size()
@classmethod
diff --git a/lms/djangoapps/teams/plugins.py b/lms/djangoapps/teams/plugins.py
index da67b48e76..e60df52fcd 100644
--- a/lms/djangoapps/teams/plugins.py
+++ b/lms/djangoapps/teams/plugins.py
@@ -27,7 +27,7 @@ class TeamsTab(EnrolledTab):
course (CourseDescriptor): the course using the feature
user (User): the user interacting with the course
"""
- if not super(TeamsTab, cls).is_enabled(course, user=user):
+ if not super().is_enabled(course, user=user):
return False
return is_feature_enabled(course)
diff --git a/lms/djangoapps/teams/search_indexes.py b/lms/djangoapps/teams/search_indexes.py
index 048a307194..349a1ba65a 100644
--- a/lms/djangoapps/teams/search_indexes.py
+++ b/lms/djangoapps/teams/search_indexes.py
@@ -33,7 +33,7 @@ def if_search_enabled(f):
return wrapper
-class CourseTeamIndexer(object):
+class CourseTeamIndexer:
"""
This is the index object for searching and storing CourseTeam model instances.
"""
@@ -79,7 +79,7 @@ class CourseTeamIndexer(object):
"""
# Always use the English version of any localizable strings (see TNL-3239)
with translation.override('en'):
- return u"{name}\n{description}\n{country}\n{language}".format(
+ return "{name}\n{description}\n{country}\n{language}".format(
name=self.course_team.name,
description=self.course_team.description,
country=self.course_team.country.name.format(),
@@ -123,7 +123,7 @@ class CourseTeamIndexer(object):
try:
return SearchEngine.get_search_engine(index=cls.INDEX_NAME)
except ConnectionError as err:
- logging.error(u'Error connecting to elasticsearch: %s', err)
+ logging.error('Error connecting to elasticsearch: %s', err)
raise ElasticSearchConnectionError # lint-amnesty, pylint: disable=raise-missing-from
@classmethod
diff --git a/lms/djangoapps/teams/serializers.py b/lms/djangoapps/teams/serializers.py
index 9aab17694a..1439d6cfd6 100644
--- a/lms/djangoapps/teams/serializers.py
+++ b/lms/djangoapps/teams/serializers.py
@@ -29,7 +29,7 @@ class CountryField(serializers.Field):
"""
Represent the country as a 2-character unicode identifier.
"""
- return six.text_type(obj)
+ return str(obj)
def to_internal_value(self, data):
"""
@@ -41,7 +41,7 @@ class CountryField(serializers.Field):
"""
if data and data not in self.COUNTRY_CODES:
raise serializers.ValidationError(
- u"{code} is not a valid country code".format(code=data)
+ f"{data} is not a valid country code"
)
return data
@@ -65,7 +65,7 @@ class UserMembershipSerializer(serializers.ModelSerializer):
expanded_serializer=UserReadOnlySerializer(configuration=profile_configuration),
)
- class Meta(object):
+ class Meta:
model = CourseTeamMembership
fields = ("user", "date_joined", "last_activity_at")
read_only_fields = ("date_joined", "last_activity_at")
@@ -77,7 +77,7 @@ class CourseTeamSerializer(serializers.ModelSerializer):
membership = UserMembershipSerializer(many=True, read_only=True)
country = CountryField()
- class Meta(object):
+ class Meta:
model = CourseTeam
fields = (
"id",
@@ -101,7 +101,7 @@ class CourseTeamCreationSerializer(serializers.ModelSerializer):
country = CountryField(required=False)
- class Meta(object):
+ class Meta:
model = CourseTeam
fields = (
"name",
@@ -135,7 +135,7 @@ class CourseTeamSerializerWithoutMembership(CourseTeamSerializer):
"""
def __init__(self, *args, **kwargs):
- super(CourseTeamSerializerWithoutMembership, self).__init__(*args, **kwargs) # lint-amnesty, pylint: disable=super-with-arguments
+ super().__init__(*args, **kwargs)
del self.fields['membership']
@@ -164,7 +164,7 @@ class MembershipSerializer(serializers.ModelSerializer):
expanded_serializer=CourseTeamSerializerWithoutMembership(read_only=True),
)
- class Meta(object):
+ class Meta:
model = CourseTeamMembership
fields = ("user", "team", "date_joined", "last_activity_at")
read_only_fields = ("date_joined", "last_activity_at")
@@ -209,7 +209,7 @@ class BulkTeamCountTopicListSerializer(serializers.ListSerializer): # pylint: d
def to_representation(self, obj): # pylint: disable=arguments-differ
"""Adds team_count to each topic. """
- data = super(BulkTeamCountTopicListSerializer, self).to_representation(obj) # lint-amnesty, pylint: disable=super-with-arguments
+ data = super().to_representation(obj)
add_team_count(
self.context['request'].user,
data,
@@ -224,5 +224,5 @@ class BulkTeamCountTopicSerializer(BaseTopicSerializer): # pylint: disable=abst
Serializes a set of topics, adding the team_count field to each topic as a bulk operation.
Requires that `context` is provided with a valid course_id in order to filter teams within the course.
"""
- class Meta(object):
+ class Meta:
list_serializer_class = BulkTeamCountTopicListSerializer
diff --git a/lms/djangoapps/teams/services.py b/lms/djangoapps/teams/services.py
index b07622ac4c..5c5b5c6bf0 100644
--- a/lms/djangoapps/teams/services.py
+++ b/lms/djangoapps/teams/services.py
@@ -4,7 +4,7 @@
from django.urls import reverse
-class TeamsService(object):
+class TeamsService:
""" Functions to provide teams functionality to XBlocks"""
def get_team(self, user, course_id, topic_id):
diff --git a/lms/djangoapps/teams/tests/factories.py b/lms/djangoapps/teams/tests/factories.py
index fd76b9f40d..178d926183 100644
--- a/lms/djangoapps/teams/tests/factories.py
+++ b/lms/djangoapps/teams/tests/factories.py
@@ -20,21 +20,21 @@ class CourseTeamFactory(DjangoModelFactory):
Note that team_id is not auto-generated from name when using the factory.
"""
- class Meta(object):
+ class Meta:
model = CourseTeam
django_get_or_create = ('team_id',)
- team_id = factory.Sequence('team-{0}'.format)
- topic_id = factory.Sequence('topic-{0}'.format)
+ team_id = factory.Sequence('team-{}'.format)
+ topic_id = factory.Sequence('topic-{}'.format)
discussion_topic_id = factory.LazyAttribute(lambda a: uuid4().hex)
- name = factory.Sequence(u"Awesome Team {0}".format)
+ name = factory.Sequence("Awesome Team {}".format)
description = "A simple description"
last_activity_at = LAST_ACTIVITY_AT
class CourseTeamMembershipFactory(DjangoModelFactory):
"""Factory for CourseTeamMemberships."""
- class Meta(object):
+ class Meta:
model = CourseTeamMembership
last_activity_at = LAST_ACTIVITY_AT
diff --git a/lms/djangoapps/teams/tests/test_api.py b/lms/djangoapps/teams/tests/test_api.py
index 3aaba90677..103b7b070a 100644
--- a/lms/djangoapps/teams/tests/test_api.py
+++ b/lms/djangoapps/teams/tests/test_api.py
@@ -1,22 +1,21 @@
-# -*- coding: utf-8 -*-
"""
Tests for Python APIs of the Teams app
"""
+from unittest import mock
from uuid import uuid4
import ddt
-import mock
from opaque_keys.edx.keys import CourseKey
from common.djangoapps.course_modes.models import CourseMode
+from common.djangoapps.student.models import AnonymousUserId, CourseEnrollment
+from common.djangoapps.student.roles import CourseStaffRole
+from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from lms.djangoapps.teams import api as teams_api
from lms.djangoapps.teams.models import CourseTeam
from lms.djangoapps.teams.tests.factories import CourseTeamFactory
from openedx.core.lib.teams_config import TeamsConfig, TeamsetType
-from common.djangoapps.student.models import CourseEnrollment, AnonymousUserId
-from common.djangoapps.student.roles import CourseStaffRole
-from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -36,7 +35,7 @@ class PythonAPITests(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(PythonAPITests, cls).setUpClass()
+ super().setUpClass()
cls.user1 = UserFactory.create(username='user1')
cls.user2 = UserFactory.create(username='user2')
cls.user3 = UserFactory.create(username='user3')
@@ -231,7 +230,7 @@ class TeamAccessTests(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(TeamAccessTests, cls).setUpClass()
+ super().setUpClass()
cls.user_audit = UserFactory.create(username='user_audit')
cls.user_staff = UserFactory.create(username='user_staff')
cls.user_masters = UserFactory.create(username='user_masters')
diff --git a/lms/djangoapps/teams/tests/test_csv.py b/lms/djangoapps/teams/tests/test_csv.py
index 842d0a4825..b7e1db2102 100644
--- a/lms/djangoapps/teams/tests/test_csv.py
+++ b/lms/djangoapps/teams/tests/test_csv.py
@@ -1,16 +1,16 @@
""" Tests for the functionality in csv """
-from csv import DictWriter, DictReader
+from csv import DictReader, DictWriter
from io import BytesIO, StringIO, TextIOWrapper
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user, unused-import
-from lms.djangoapps.program_enrollments.tests.factories import ProgramEnrollmentFactory, ProgramCourseEnrollmentFactory
+from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
+from common.djangoapps.util.testing import EventTestMixin
+from lms.djangoapps.program_enrollments.tests.factories import ProgramCourseEnrollmentFactory, ProgramEnrollmentFactory
from lms.djangoapps.teams import csv
from lms.djangoapps.teams.models import CourseTeam, CourseTeamMembership
from lms.djangoapps.teams.tests.factories import CourseTeamFactory
from openedx.core.lib.teams_config import TeamsConfig
-from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
-from common.djangoapps.util.testing import EventTestMixin
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -72,13 +72,13 @@ class TeamMembershipCsvTests(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
# pylint: disable=no-member
- super(TeamMembershipCsvTests, cls).setUpClass()
+ super().setUpClass()
teams_config = TeamsConfig({
'team_sets': [
{
- 'id': 'teamset_{}'.format(i),
- 'name': 'teamset_{}_name'.format(i),
- 'description': 'teamset_{}_desc'.format(i),
+ 'id': f'teamset_{i}',
+ 'name': f'teamset_{i}_name',
+ 'description': f'teamset_{i}_desc',
}
for i in [1, 2, 3, 4]
]
@@ -231,7 +231,7 @@ class TeamMembershipImportManagerTests(TeamMembershipEventTestMixin, SharedModul
""" Tests for TeamMembershipImportManager """
@classmethod
def setUpClass(cls):
- super(TeamMembershipImportManagerTests, cls).setUpClass()
+ super().setUpClass()
teams_config = TeamsConfig({
'team_sets': [{
'id': 'teamset_1',
@@ -246,7 +246,7 @@ class TeamMembershipImportManagerTests(TeamMembershipEventTestMixin, SharedModul
def setUp(self):
""" Initialize import manager """
- super(TeamMembershipImportManagerTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.import_manager = csv.TeamMembershipImportManager(self.course)
self.import_manager.teamset_ids = {ts.teamset_id for ts in self.course.teamsets}
@@ -347,7 +347,7 @@ class TeamMembershipImportManagerTests(TeamMembershipEventTestMixin, SharedModul
# Given a bunch of students enrolled in a course
users = []
for i in range(5):
- user = UserFactory.create(username='max_size_{id}'.format(id=i))
+ user = UserFactory.create(username=f'max_size_{i}')
CourseEnrollmentFactory.create(user=user, course_id=self.course.id, mode='audit')
users.append(user)
@@ -406,7 +406,7 @@ class TeamMembershipImportManagerTests(TeamMembershipEventTestMixin, SharedModul
# Given a bunch of students enrolled in a course
users = []
for i in range(5):
- user = UserFactory.create(username='learner_{id}'.format(id=i))
+ user = UserFactory.create(username=f'learner_{i}')
CourseEnrollmentFactory.create(user=user, course_id=self.course.id, mode='audit')
users.append(user)
@@ -547,7 +547,7 @@ class TeamMembershipImportManagerTests(TeamMembershipEventTestMixin, SharedModul
Example:
[['header1', 'header2'], ['r1:c1', 'r1:c2'], ['r2:c2', 'r3:c3'] ... ]
"""
- return DictReader((','.join(row) for row in rows))
+ return DictReader(','.join(row) for row in rows)
class ExternalKeyCsvTests(TeamMembershipEventTestMixin, SharedModuleStoreTestCase):
diff --git a/lms/djangoapps/teams/tests/test_models.py b/lms/djangoapps/teams/tests/test_models.py
index 3848ed2e88..fe7f3ac01b 100644
--- a/lms/djangoapps/teams/tests/test_models.py
+++ b/lms/djangoapps/teams/tests/test_models.py
@@ -1,21 +1,21 @@
-# -*- coding: utf-8 -*-
"""
Tests for the teams API at the HTTP request level.
"""
import itertools
-import pytest
from contextlib import contextmanager
from datetime import datetime
+from unittest.mock import Mock
import ddt
+import pytest
import pytz
-import six
-from mock import Mock, patch # lint-amnesty, pylint: disable=unused-import
from opaque_keys.edx.keys import CourseKey
from common.djangoapps.course_modes.models import CourseMode
+from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
+from common.djangoapps.util.testing import EventTestMixin
from lms.djangoapps.teams import TEAM_DISCUSSION_CONTEXT
from lms.djangoapps.teams.errors import AddToIncompatibleTeamError
from lms.djangoapps.teams.models import CourseTeam, CourseTeamMembership
@@ -32,9 +32,6 @@ from openedx.core.djangoapps.django_comment_common.signals import (
thread_voted
)
from openedx.core.lib.teams_config import TeamsConfig
-from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
-from common.djangoapps.util.testing import EventTestMixin
-
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -65,7 +62,7 @@ class TestModelStrings(SharedModuleStoreTestCase):
"""
@classmethod
def setUpClass(cls):
- super(TestModelStrings, cls).setUpClass()
+ super().setUpClass()
cls.course_id = "edx/the-course/1"
cls.course1 = create_course(CourseKey.from_string(cls.course_id), TEAMS_CONFIG_1)
cls.user = UserFactory.create(username="the-user")
@@ -90,7 +87,7 @@ class TestModelStrings(SharedModuleStoreTestCase):
)
def test_team_text(self):
- assert six.text_type(self.team) == (
+ assert str(self.team) == (
"The Team in edx/the-course/1"
)
@@ -100,7 +97,7 @@ class TestModelStrings(SharedModuleStoreTestCase):
)
def test_team_membership_text_type(self):
- assert six.text_type(self.team_membership) == (
+ assert str(self.team_membership) == (
"the-user is member of The Team in edx/the-course/1"
)
@@ -110,7 +107,7 @@ class CourseTeamTest(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(CourseTeamTest, cls).setUpClass()
+ super().setUpClass()
cls.course_id = "edx/the-course/1"
cls.course1 = create_course(CourseKey.from_string(cls.course_id), TEAMS_CONFIG_1)
@@ -154,7 +151,7 @@ class TeamMembershipTest(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(TeamMembershipTest, cls).setUpClass()
+ super().setUpClass()
create_course(COURSE_KEY1, TEAMS_CONFIG_1)
create_course(COURSE_KEY2, TEAMS_CONFIG_2)
@@ -162,7 +159,7 @@ class TeamMembershipTest(SharedModuleStoreTestCase):
"""
Set up tests.
"""
- super(TeamMembershipTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.user1 = UserFactory.create(username='user1')
self.user2 = UserFactory.create(username='user2')
@@ -263,7 +260,7 @@ class TeamSignalsTest(EventTestMixin, SharedModuleStoreTestCase):
def setUp(self): # pylint: disable=arguments-differ
"""Create a user with a team to test signals."""
- super(TeamSignalsTest, self).setUp('lms.djangoapps.teams.utils.tracker') # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp('lms.djangoapps.teams.utils.tracker')
self.user = UserFactory.create(username="user")
self.moderator = UserFactory.create(username="moderator")
self.team = CourseTeamFactory(discussion_topic_id=self.DISCUSSION_TOPIC_ID)
diff --git a/lms/djangoapps/teams/tests/test_serializers.py b/lms/djangoapps/teams/tests/test_serializers.py
index b77fea6c85..e8e1fc2554 100644
--- a/lms/djangoapps/teams/tests/test_serializers.py
+++ b/lms/djangoapps/teams/tests/test_serializers.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
"""
Tests for custom Teams Serializers.
"""
@@ -8,10 +7,10 @@ import six
from django.core.paginator import Paginator
from django.test.client import RequestFactory
+from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from lms.djangoapps.teams.serializers import BulkTeamCountTopicSerializer, MembershipSerializer, TopicSerializer
from lms.djangoapps.teams.tests.factories import CourseTeamFactory, CourseTeamMembershipFactory
from openedx.core.lib.teams_config import TeamsConfig
-from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@@ -24,11 +23,11 @@ class SerializerTestCase(SharedModuleStoreTestCase):
"""
Set up a course with a teams configuration.
"""
- super(SerializerTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.course = CourseFactory.create(
teams_configuration=TeamsConfig({
"max_team_size": 10,
- "topics": [{u'name': u'Tøpic', u'description': u'The bést topic!', u'id': u'0'}]
+ "topics": [{'name': 'Tøpic', 'description': 'The bést topic!', 'id': '0'}]
}),
)
@@ -39,7 +38,7 @@ class MembershipSerializerTestCase(SerializerTestCase):
"""
def setUp(self):
- super(MembershipSerializerTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.team = CourseTeamFactory.create(
course_id=self.course.id,
topic_id=self.course.teamsets[0].teamset_id,
@@ -51,7 +50,7 @@ class MembershipSerializerTestCase(SerializerTestCase):
def test_membership_serializer_expand_user_and_team(self):
"""Verify that the serializer only expands the user and team one level."""
data = MembershipSerializer(self.team_membership, context={
- 'expand': [u'team', u'user'],
+ 'expand': ['team', 'user'],
'request': RequestFactory().get('/api/team/v0/team_membership')
}).data
username = self.user.username
@@ -81,8 +80,8 @@ class TopicSerializerTestCase(SerializerTestCase):
self.course.teamsets[0].cleaned_data,
context={'course_id': self.course.id},
)
- assert serializer.data == {u'name': u'Tøpic', u'description': u'The bést topic!', u'id': u'0',
- u'team_count': 0, u'type': u'open', u'max_team_size': None}
+ assert serializer.data == {'name': 'Tøpic', 'description': 'The bést topic!', 'id': '0',
+ 'team_count': 0, 'type': 'open', 'max_team_size': None}
def test_topic_with_team_count(self):
"""
@@ -97,8 +96,8 @@ class TopicSerializerTestCase(SerializerTestCase):
self.course.teamsets[0].cleaned_data,
context={'course_id': self.course.id},
)
- assert serializer.data == {u'name': u'Tøpic', u'description': u'The bést topic!', u'id': u'0',
- u'team_count': 1, u'type': u'open', u'max_team_size': None}
+ assert serializer.data == {'name': 'Tøpic', 'description': 'The bést topic!', 'id': '0',
+ 'team_count': 1, 'type': 'open', 'max_team_size': None}
def test_scoped_within_course(self):
"""Verify that team count is scoped within a course."""
@@ -109,15 +108,15 @@ class TopicSerializerTestCase(SerializerTestCase):
"topics": [duplicate_topic]
}),
)
- CourseTeamFactory.create(course_id=self.course.id, topic_id=duplicate_topic[u'id'])
- CourseTeamFactory.create(course_id=second_course.id, topic_id=duplicate_topic[u'id'])
+ CourseTeamFactory.create(course_id=self.course.id, topic_id=duplicate_topic['id'])
+ CourseTeamFactory.create(course_id=second_course.id, topic_id=duplicate_topic['id'])
with self.assertNumQueries(2):
serializer = TopicSerializer(
self.course.teamsets[0].cleaned_data,
context={'course_id': self.course.id},
)
- assert serializer.data == {u'name': u'Tøpic', u'description': u'The bést topic!', u'id': u'0',
- u'team_count': 1, u'type': u'open', u'max_team_size': None}
+ assert serializer.data == {'name': 'Tøpic', 'description': 'The bést topic!', 'id': '0',
+ 'team_count': 1, 'type': 'open', 'max_team_size': None}
class BaseTopicSerializerTestCase(SerializerTestCase):
@@ -143,9 +142,9 @@ class BaseTopicSerializerTestCase(SerializerTestCase):
"""
topics = [
{
- 'name': 'Tøpic {}'.format(i),
- 'description': 'The bést topic! {}'.format(i),
- 'id': six.text_type(i),
+ 'name': f'Tøpic {i}',
+ 'description': f'The bést topic! {i}',
+ 'id': str(i),
'type': 'open',
'max_team_size': i + 10
}
@@ -172,7 +171,7 @@ class BaseTopicSerializerTestCase(SerializerTestCase):
# pylint: disable=not-callable
serializer = self.serializer(instance=page, context={'course_id': self.course.id})
assert serializer.data['results'] ==\
- [self._merge_dicts(topic, {u'team_count': num_teams_per_topic}) for topic in topics]
+ [self._merge_dicts(topic, {'team_count': num_teams_per_topic}) for topic in topics]
def test_no_topics(self):
"""
@@ -235,7 +234,7 @@ class BulkTeamCountTopicSerializerTestCase(BaseTopicSerializerTestCase):
"topics": [duplicate_topic]
}),
)
- CourseTeamFactory.create(course_id=second_course.id, topic_id=duplicate_topic[u'id'])
+ CourseTeamFactory.create(course_id=second_course.id, topic_id=duplicate_topic['id'])
self.assert_serializer_output(first_course_topics, num_teams_per_topic=teams_per_topic, num_queries=2)
def _merge_dicts(self, first, second):
@@ -262,7 +261,7 @@ class BulkTeamCountTopicSerializerTestCase(BaseTopicSerializerTestCase):
many=True
)
assert serializer.data ==\
- [self._merge_dicts(topic, {u'team_count': num_teams_per_topic}) for topic in topics]
+ [self._merge_dicts(topic, {'team_count': num_teams_per_topic}) for topic in topics]
def test_no_topics(self):
"""
diff --git a/lms/djangoapps/teams/tests/test_services.py b/lms/djangoapps/teams/tests/test_services.py
index d6eb53ad6a..8b467112c0 100644
--- a/lms/djangoapps/teams/tests/test_services.py
+++ b/lms/djangoapps/teams/tests/test_services.py
@@ -1,22 +1,20 @@
-# -*- coding: utf-8 -*-
"""
Tests for any Teams app services
"""
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
-from openedx.core.djangoapps.catalog.tests.factories import CourseRunFactory
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
-
from lms.djangoapps.teams.services import TeamsService
from lms.djangoapps.teams.tests.factories import CourseTeamFactory
+from openedx.core.djangoapps.catalog.tests.factories import CourseRunFactory
+from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
class TeamsServiceTests(ModuleStoreTestCase):
""" Tests for the TeamsService """
def setUp(self):
- super(TeamsServiceTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
self.course_run = CourseRunFactory.create()
self.course_key = self.course_run['key']
self.team = CourseTeamFactory.create(course_id=self.course_key)
diff --git a/lms/djangoapps/teams/tests/test_views.py b/lms/djangoapps/teams/tests/test_views.py
index 1eeec4c186..cf451bbb97 100644
--- a/lms/djangoapps/teams/tests/test_views.py
+++ b/lms/djangoapps/teams/tests/test_views.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
"""
Tests for the teams API at the HTTP request level.
"""
@@ -7,32 +6,31 @@ Tests for the teams API at the HTTP request level.
import json
import unittest
from datetime import datetime
+from unittest.mock import patch
from uuid import UUID
import ddt
import pytz
from dateutil import parser
from django.conf import settings
-from django.db.models.signals import post_save
from django.core.files.uploadedfile import SimpleUploadedFile
+from django.db.models.signals import post_save
from django.urls import reverse
from django.utils import translation
from elasticsearch.exceptions import ConnectionError # lint-amnesty, pylint: disable=redefined-builtin
-from mock import patch
from rest_framework.test import APIClient, APITestCase
from search.search_engine_base import SearchEngine
-from six.moves import range
-from common.test.utils import skip_signal
from common.djangoapps.course_modes.models import CourseMode
+from common.djangoapps.student.models import CourseEnrollment
+from common.djangoapps.student.tests.factories import AdminFactory, CourseEnrollmentFactory, UserFactory
+from common.djangoapps.util.testing import EventTestMixin
+from common.test.utils import skip_signal
from lms.djangoapps.courseware.tests.factories import StaffFactory
+from lms.djangoapps.program_enrollments.tests.factories import ProgramEnrollmentFactory
from openedx.core.djangoapps.django_comment_common.models import FORUM_ROLE_COMMUNITY_TA, Role
from openedx.core.djangoapps.django_comment_common.utils import seed_permissions_roles
from openedx.core.lib.teams_config import TeamsConfig
-from common.djangoapps.student.models import CourseEnrollment
-from lms.djangoapps.program_enrollments.tests.factories import ProgramEnrollmentFactory
-from common.djangoapps.student.tests.factories import AdminFactory, CourseEnrollmentFactory, UserFactory
-from common.djangoapps.util.testing import EventTestMixin
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@@ -50,15 +48,15 @@ class TestDashboard(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
- super(TestDashboard, cls).setUpClass()
+ super().setUpClass()
cls.course = CourseFactory.create(
teams_configuration=TeamsConfig({
"max_team_size": 10,
"topics": [
{
- "name": u"Topic {}".format(topic_id),
+ "name": f"Topic {topic_id}",
"id": topic_id,
- "description": u"Description for topic {}".format(topic_id)
+ "description": f"Description for topic {topic_id}"
}
for topic_id in range(cls.NUM_TOPICS)
]
@@ -69,7 +67,7 @@ class TestDashboard(SharedModuleStoreTestCase):
"""
Set up tests
"""
- super(TestDashboard, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp()
# will be assigned to self.client by default
self.user = UserFactory.create(password=self.test_password)
self.teams_url = reverse('teams_dashboard', args=[self.course.id])
@@ -79,7 +77,7 @@ class TestDashboard(SharedModuleStoreTestCase):
dashboard, and is redirected to the login page."""
anonymous_client = APIClient()
response = anonymous_client.get(self.teams_url)
- redirect_url = '{0}?next={1}'.format(settings.LOGIN_URL, self.teams_url)
+ redirect_url = f'{settings.LOGIN_URL}?next={self.teams_url}'
self.assertRedirects(response, redirect_url)
def test_not_enrolled_not_staff(self):
@@ -132,7 +130,7 @@ class TestDashboard(SharedModuleStoreTestCase):
# Create some teams
for topic_id in range(self.NUM_TOPICS):
team = CourseTeamFactory.create(
- name=u"Team for topic {}".format(topic_id),
+ name=f"Team for topic {topic_id}",
course_id=self.course.id,
topic_id=topic_id,
)
@@ -305,34 +303,34 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
# pylint: disable=super-method-not-called
- with super(TeamAPITestCase, cls).setUpClassAndTestData():
+ with super().setUpClassAndTestData():
base_topics = [{
- 'id': 'topic_{}'.format(i), 'name': name,
- 'description': u'Description for topic {}.'.format(i),
+ 'id': f'topic_{i}', 'name': name,
+ 'description': f'Description for topic {i}.',
'max_team_size': 3
- } for i, name in enumerate([u'Sólar power', 'Wind Power', 'Nuclear Power', 'Coal Power'])]
+ } for i, name in enumerate(['Sólar power', 'Wind Power', 'Nuclear Power', 'Coal Power'])]
base_topics.append(
{
'id': 'private_topic_1_id',
'name': 'private_topic_1_name',
- 'description': u'Description for topic private topic 1.',
- 'type': u'private_managed'
+ 'description': 'Description for topic private topic 1.',
+ 'type': 'private_managed'
}
)
base_topics.append(
{
'id': 'private_topic_2_id',
'name': 'private_topic_2_name',
- 'description': u'Description for topic private topic 2.',
- 'type': u'private_managed'
+ 'description': 'Description for topic private topic 2.',
+ 'type': 'private_managed'
}
)
base_topics.append(
{
'id': 'private_topic_no_teams',
'name': 'private_topic_no_teams_name',
- 'description': u'Description for topic private_topic_no_teams.',
- 'type': u'private_managed'
+ 'description': 'Description for topic private_topic_no_teams.',
+ 'type': 'private_managed'
}
)
teams_configuration_1 = TeamsConfig({
@@ -377,7 +375,7 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
@classmethod
def setUpTestData(cls):
- super(TeamAPITestCase, cls).setUpTestData()
+ super().setUpTestData()
cls.topics_count = 6
cls.users = {
'staff': AdminFactory.create(password=cls.test_password),
@@ -439,7 +437,7 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
dispatch_uid='teams.signals.course_team_post_save_callback'
):
cls.solar_team = CourseTeamFactory.create(
- name=u'Sólar team',
+ name='Sólar team',
course_id=cls.test_course_1.id,
topic_id='topic_0'
)
@@ -472,8 +470,8 @@ class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):
topic_id='topic_7'
)
cls.chinese_team = CourseTeamFactory.create(
- name=u'著文企臺個',
- description=u'共樣地面較,件展冷不護者這與民教過住意,國制銀產物助音是勢一友',
+ name='著文企臺個',
+ description='共樣地面較,件展冷不護者這與民教過住意,國制銀產物助音是勢一友',
country='CN',
language='zh_HANS',
course_id=cls.test_course_2.id,
@@ -773,7 +771,7 @@ class TestListTeamsAPI(EventTestMixin, TeamAPITestCase):
"""Test cases for the team listing API endpoint."""
def setUp(self): # pylint: disable=arguments-differ
- super(TestListTeamsAPI, self).setUp('lms.djangoapps.teams.utils.tracker') # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp('lms.djangoapps.teams.utils.tracker')
@ddt.data(
(None, 401),
@@ -808,27 +806,27 @@ class TestListTeamsAPI(EventTestMixin, TeamAPITestCase):
self.verify_names(
{'course_id': str(self.test_course_2.id)},
200,
- ['Another Team', 'Public Profile Team', 'Search', u'著文企臺個'],
+ ['Another Team', 'Public Profile Team', 'Search', '著文企臺個'],
user='staff'
)
def test_filter_topic_id(self):
- self.verify_names({'course_id': str(self.test_course_1.id), 'topic_id': 'topic_0'}, 200, [u'Sólar team'])
+ self.verify_names({'course_id': str(self.test_course_1.id), 'topic_id': 'topic_0'}, 200, ['Sólar team'])
def test_filter_username(self):
self.verify_names({'course_id': str(self.test_course_1.id),
- 'username': 'student_enrolled'}, 200, [u'Sólar team'])
+ 'username': 'student_enrolled'}, 200, ['Sólar team'])
self.verify_names({'course_id': str(self.test_course_1.id), 'username': 'staff'}, 200, [])
@ddt.data(
- (None, 200, ['Nuclear Team', u'Sólar team', 'Wind Team']),
- ('name', 200, ['Nuclear Team', u'Sólar team', 'Wind Team']),
+ (None, 200, ['Nuclear Team', 'Sólar team', 'Wind Team']),
+ ('name', 200, ['Nuclear Team', 'Sólar team', 'Wind Team']),
# Note that "Nuclear Team" and "Solar team" have the same open_slots.
# "Solar team" comes first due to secondary sort by last_activity_at.
- ('open_slots', 200, ['Wind Team', u'Sólar team', 'Nuclear Team']),
+ ('open_slots', 200, ['Wind Team', 'Sólar team', 'Nuclear Team']),
# Note that "Wind Team" and "Nuclear Team" have the same last_activity_at.
# "Wind Team" comes first due to secondary sort by open_slots.
- ('last_activity_at', 200, [u'Sólar team', 'Wind Team', 'Nuclear Team']),
+ ('last_activity_at', 200, ['Sólar team', 'Wind Team', 'Nuclear Team']),
)
@ddt.unpack
def test_order_by(self, field, status, names):
@@ -841,7 +839,7 @@ class TestListTeamsAPI(EventTestMixin, TeamAPITestCase):
sender=CourseTeam,
dispatch_uid='teams.signals.course_team_post_save_callback'
):
- solar_team = self.test_team_name_id_map[u'Sólar team']
+ solar_team = self.test_team_name_id_map['Sólar team']
solar_team.last_activity_at = datetime.utcnow().replace(tzinfo=pytz.utc)
solar_team.save()
@@ -969,7 +967,7 @@ class TestListTeamsAPI(EventTestMixin, TeamAPITestCase):
('Island', ['Search']),
('not-a-query', []),
('team', ['Another Team', 'Public Profile Team']),
- (u'著文企臺個', [u'著文企臺個']),
+ ('著文企臺個', ['著文企臺個']),
)
@ddt.unpack
def test_text_search(self, text_search, expected_team_names):
@@ -1017,7 +1015,7 @@ class TestListTeamsAPI(EventTestMixin, TeamAPITestCase):
def test_delete_removed_from_search(self):
team = CourseTeamFactory.create(
- name=u'zoinks',
+ name='zoinks',
course_id=self.test_course_1.id,
topic_id='topic_0'
)
@@ -1073,7 +1071,7 @@ class TestCreateTeamAPI(EventTestMixin, TeamAPITestCase):
"""Test cases for the team creation endpoint."""
def setUp(self): # pylint: disable=arguments-differ
- super(TestCreateTeamAPI, self).setUp('lms.djangoapps.teams.utils.tracker') # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp('lms.djangoapps.teams.utils.tracker')
@ddt.data(
(None, 401),
@@ -1378,7 +1376,7 @@ class TestDeleteTeamAPI(EventTestMixin, TeamAPITestCase):
"""Test cases for the team delete endpoint."""
def setUp(self): # pylint: disable=arguments-differ
- super(TestDeleteTeamAPI, self).setUp('lms.djangoapps.teams.utils.tracker') # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp('lms.djangoapps.teams.utils.tracker')
@ddt.data(
('staff', 204),
@@ -1494,7 +1492,7 @@ class TestUpdateTeamAPI(EventTestMixin, TeamAPITestCase):
"""Test cases for the team update endpoint."""
def setUp(self): # pylint: disable=arguments-differ
- super(TestUpdateTeamAPI, self).setUp('lms.djangoapps.teams.utils.tracker') # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp('lms.djangoapps.teams.utils.tracker')
@ddt.data(
(None, 401),
@@ -1732,11 +1730,11 @@ class TestListTopicsAPI(TeamAPITestCase):
self.get_topics_list(400)
@ddt.data(
- (None, 200, ['Coal Power', 'Nuclear Power', u'Sólar power', 'Wind Power'], 'name'),
- ('name', 200, ['Coal Power', 'Nuclear Power', u'Sólar power', 'Wind Power'], 'name'),
+ (None, 200, ['Coal Power', 'Nuclear Power', 'Sólar power', 'Wind Power'], 'name'),
+ ('name', 200, ['Coal Power', 'Nuclear Power', 'Sólar power', 'Wind Power'], 'name'),
# Note that "Nuclear Power" will have 2 teams. "Coal Power" "Wind Power" and "Solar Power"
# all have 1 team. The secondary sort is alphabetical by name.
- ('team_count', 200, ['Nuclear Power', 'Coal Power', u'Sólar power', 'Wind Power'], 'team_count'),
+ ('team_count', 200, ['Nuclear Power', 'Coal Power', 'Sólar power', 'Wind Power'], 'team_count'),
('no_such_field', 400, [], None),
)
@ddt.unpack
@@ -1749,11 +1747,11 @@ class TestListTopicsAPI(TeamAPITestCase):
):
# Add a team to "Nuclear Power", so it has two teams
CourseTeamFactory.create(
- name=u'Nuclear Team 1', course_id=self.test_course_1.id, topic_id='topic_2'
+ name='Nuclear Team 1', course_id=self.test_course_1.id, topic_id='topic_2'
)
# Add a team to "Coal Power", so it has one team, same as "Wind" and "Solar"
CourseTeamFactory.create(
- name=u'Coal Team 1', course_id=self.test_course_1.id, topic_id='topic_3'
+ name='Coal Team 1', course_id=self.test_course_1.id, topic_id='topic_3'
)
data = {'course_id': str(self.test_course_1.id)}
if field:
@@ -1778,16 +1776,16 @@ class TestListTopicsAPI(TeamAPITestCase):
# Add two wind teams, a solar team and a coal team, to bring the totals to
# Wind: 3 Solar: 2 Coal: 1, Nuclear: 1
CourseTeamFactory.create(
- name=u'Wind Team 1', course_id=self.test_course_1.id, topic_id='topic_1'
+ name='Wind Team 1', course_id=self.test_course_1.id, topic_id='topic_1'
)
CourseTeamFactory.create(
- name=u'Wind Team 2', course_id=self.test_course_1.id, topic_id='topic_1'
+ name='Wind Team 2', course_id=self.test_course_1.id, topic_id='topic_1'
)
CourseTeamFactory.create(
- name=u'Solar Team 1', course_id=self.test_course_1.id, topic_id='topic_0'
+ name='Solar Team 1', course_id=self.test_course_1.id, topic_id='topic_0'
)
CourseTeamFactory.create(
- name=u'Coal Team 1', course_id=self.test_course_1.id, topic_id='topic_3'
+ name='Coal Team 1', course_id=self.test_course_1.id, topic_id='topic_3'
)
# Wind power has the most teams, followed by Solar
@@ -1800,7 +1798,7 @@ class TestListTopicsAPI(TeamAPITestCase):
},
user='student_enrolled'
)
- assert ['Wind Power', u'Sólar power'] == [topic['name'] for topic in topics['results']]
+ assert ['Wind Power', 'Sólar power'] == [topic['name'] for topic in topics['results']]
# Coal and Nuclear are tied, so they are alphabetically sorted.
topics = self.get_topics_list(
@@ -2085,7 +2083,7 @@ class TestListMembershipAPI(TeamAPITestCase):
@ddt.data(
('student_enrolled_both_courses_other_team', 'TestX/TS101/Test_Course', 200, 'Nuclear Team'),
('student_enrolled_both_courses_other_team', 'MIT/6.002x/Circuits', 200, 'Another Team'),
- ('student_enrolled', 'TestX/TS101/Test_Course', 200, u'Sólar team'),
+ ('student_enrolled', 'TestX/TS101/Test_Course', 200, 'Sólar team'),
('student_enrolled', 'MIT/6.002x/Circuits', 400, ''),
)
@ddt.unpack
@@ -2288,7 +2286,7 @@ class TestCreateMembershipAPI(EventTestMixin, TeamAPITestCase):
"""Test cases for the membership creation endpoint."""
def setUp(self): # pylint: disable=arguments-differ
- super(TestCreateMembershipAPI, self).setUp('lms.djangoapps.teams.utils.tracker') # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp('lms.djangoapps.teams.utils.tracker')
@ddt.data(
(None, 401),
@@ -2577,7 +2575,7 @@ class TestDeleteMembershipAPI(EventTestMixin, TeamAPITestCase):
"""Test cases for the membership deletion endpoint."""
def setUp(self): # pylint: disable=arguments-differ
- super(TestDeleteMembershipAPI, self).setUp('lms.djangoapps.teams.utils.tracker') # lint-amnesty, pylint: disable=super-with-arguments
+ super().setUp('lms.djangoapps.teams.utils.tracker')
@ddt.data(
(None, 401),
@@ -2933,9 +2931,9 @@ class TestBulkMembershipManagement(TeamAPITestCase):
self.create_and_enroll_student(username=masters_username_b, mode=CourseMode.MASTERS)
csv_content = 'user,mode,topic_1' + '\n'
- csv_content += '{},audit,team wind power'.format(audit_username) + '\n'
- csv_content += '{},masters,team wind power'.format(masters_username_a) + '\n'
- csv_content += '{},masters,team wind power'.format(masters_username_b) + '\n'
+ csv_content += f'{audit_username},audit,team wind power' + '\n'
+ csv_content += f'{masters_username_a},masters,team wind power' + '\n'
+ csv_content += f'{masters_username_b},masters,team wind power' + '\n'
csv_file = SimpleUploadedFile('test_file.csv', csv_content.encode('utf8'), content_type='text/csv')
self.client.login(username=self.users['course_staff'].username, password=self.users['course_staff'].password)
response = self.make_call(reverse(
@@ -2955,7 +2953,7 @@ class TestBulkMembershipManagement(TeamAPITestCase):
for name_enum in enumerate(['a', 'b', 'c', 'd', 'e', 'f', 'g']):
username = 'user_{}'.format(name_enum[1])
self.create_and_enroll_student(username=username, mode=CourseMode.MASTERS)
- csv_content += '{},masters,{},{}'.format(username, team1, team2) + '\n'
+ csv_content += f'{username},masters,{team1},{team2}' + '\n'
csv_file = SimpleUploadedFile('test_file.csv', csv_content.encode('utf8'), content_type='text/csv')
self.client.login(username=self.users['course_staff'].username, password=self.users['course_staff'].password)
@@ -2975,8 +2973,8 @@ class TestBulkMembershipManagement(TeamAPITestCase):
topic_0_id = 'topic_0'
assert CourseTeamMembership.objects.filter(user_id=self.users[username].id, team__topic_id=topic_0_id).exists()
- csv_content = 'user,mode,{},topic_1'.format(topic_0_id) + '\n'
- csv_content += '{},audit'.format(username)
+ csv_content = f'user,mode,{topic_0_id},topic_1' + '\n'
+ csv_content += f'{username},audit'
csv_file = SimpleUploadedFile('test_file.csv', csv_content.encode('utf8'), content_type='text/csv')
self.client.login(username=self.users['course_staff'].username, password=self.users['course_staff'].password)
self.make_call(
@@ -2998,8 +2996,8 @@ class TestBulkMembershipManagement(TeamAPITestCase):
windpower_team_name = 'team wind power'
assert CourseTeamMembership.objects\
.filter(user_id=self.users[username].id, team__topic_id=topic_0_id, team__name=windpower_team_name).exists()
- csv_content = 'user,mode,{}'.format(topic_0_id) + '\n'
- csv_content += '{0},audit,{1}'.format(username, nuclear_team_name)
+ csv_content = f'user,mode,{topic_0_id}' + '\n'
+ csv_content += f'{username},audit,{nuclear_team_name}'
csv_file = SimpleUploadedFile('test_file.csv', csv_content.encode('utf8'), content_type='text/csv')
self.client.login(username=self.users['course_staff'].username, password=self.users['course_staff'].password)
self.make_call(
@@ -3024,8 +3022,8 @@ class TestBulkMembershipManagement(TeamAPITestCase):
topic_0_id = 'topic_0'
nuclear_team_name = 'team wind power'
assert len(CourseTeamMembership.objects.filter(user_id=self.users[username].id, team__topic_id=topic_0_id)) == 1
- csv_content = 'user,mode,{}'.format(topic_0_id) + '\n'
- csv_content += '{0},audit,{1}'.format(username, nuclear_team_name)
+ csv_content = f'user,mode,{topic_0_id}' + '\n'
+ csv_content += f'{username},audit,{nuclear_team_name}'
csv_file = SimpleUploadedFile('test_file.csv', csv_content.encode('utf8'), content_type='text/csv')
self.client.login(username=self.users['course_staff'].username,
password=self.users['course_staff'].password)
@@ -3078,7 +3076,7 @@ class TestBulkMembershipManagement(TeamAPITestCase):
team_name = '著文企臺個'
user_name = '著著文企臺個文企臺個'
self.create_and_enroll_student(username=user_name)
- csv_content += '{},audit,{}'.format(user_name, team_name)
+ csv_content += f'{user_name},audit,{team_name}'
csv_file = SimpleUploadedFile('test_file.csv', csv_content.encode('utf8'), content_type='text/csv')
self.client.login(username=self.users['course_staff'].username, password=self.users['course_staff'].password)
self.make_call(
@@ -3099,8 +3097,8 @@ class TestBulkMembershipManagement(TeamAPITestCase):
masters_a = 'masters_a'
team = self.wind_team
self.create_and_enroll_student(username=masters_a, mode=CourseMode.MASTERS)
- csv_content = 'user,mode,{}'.format(team.topic_id) + '\n'
- csv_content += 'masters_a, masters,{}'.format(team.name)
+ csv_content = f'user,mode,{team.topic_id}' + '\n'
+ csv_content += f'masters_a, masters,{team.name}'
csv_file = SimpleUploadedFile('test_file.csv', csv_content.encode('utf8'), content_type='text/csv')
self.client.login(username=self.users['course_staff'].username, password=self.users['course_staff'].password)
diff --git a/lms/djangoapps/teams/toggles.py b/lms/djangoapps/teams/toggles.py
index d75ca8d662..f9a100e15b 100644
--- a/lms/djangoapps/teams/toggles.py
+++ b/lms/djangoapps/teams/toggles.py
@@ -2,8 +2,8 @@
Togglable settings for Teams behavior
"""
from edx_toggles.toggles import SettingDictToggle
-from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
+from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
# Course Waffle inherited from edx/edx-ora2
WAFFLE_NAMESPACE = "openresponseassessment"
diff --git a/lms/djangoapps/teams/views.py b/lms/djangoapps/teams/views.py
index 896dc7f9b5..88e2eaf060 100644
--- a/lms/djangoapps/teams/views.py
+++ b/lms/djangoapps/teams/views.py
@@ -27,12 +27,13 @@ from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework.reverse import reverse
from rest_framework.views import APIView
-from openedx.core.lib.api.authentication import BearerAuthentication
+from common.djangoapps.student.models import CourseAccessRole, CourseEnrollment
+from common.djangoapps.util.model_utils import truncate_fields
from lms.djangoapps.courseware.courses import get_course_with_access, has_access
from lms.djangoapps.discussion.django_comment_client.utils import has_discussion_privileges
from lms.djangoapps.teams.models import CourseTeam, CourseTeamMembership
-from openedx.core.lib.teams_config import TeamsetType
+from openedx.core.lib.api.authentication import BearerAuthentication
from openedx.core.lib.api.parsers import MergePatchParser
from openedx.core.lib.api.permissions import IsCourseStaffInstructor, IsStaffOrReadOnly
from openedx.core.lib.api.view_utils import (
@@ -41,16 +42,15 @@ from openedx.core.lib.api.view_utils import (
add_serializer_errors,
build_api_error
)
-from common.djangoapps.student.models import CourseAccessRole, CourseEnrollment
-from common.djangoapps.util.model_utils import truncate_fields
+from openedx.core.lib.teams_config import TeamsetType
from xmodule.modulestore.django import modulestore
from . import is_feature_enabled
from .api import (
OrganizationProtectionStatus,
add_team_count,
- can_user_modify_team,
can_user_create_team_in_topic,
+ can_user_modify_team,
get_assignments_for_team,
has_course_staff_privileges,
has_specific_team_access,
@@ -58,7 +58,7 @@ from .api import (
has_team_api_access,
user_organization_protection_status
)
-from .csv import load_team_membership_csv, TeamMembershipImportManager
+from .csv import TeamMembershipImportManager, load_team_membership_csv
from .errors import AlreadyOnTeamInTeamset, ElasticSearchConnectionError, NotEnrolledInCourseForTeam
from .search_indexes import CourseTeamIndexer
from .serializers import (
@@ -68,8 +68,8 @@ from .serializers import (
MembershipSerializer,
TopicSerializer
)
-from .utils import emit_team_event
from .toggles import are_team_submissions_enabled
+from .utils import emit_team_event
TEAM_MEMBERSHIPS_PER_PAGE = 5
TOPICS_PER_PAGE = 12
@@ -87,8 +87,8 @@ def team_post_save_callback(sender, instance, **kwargs): # pylint: disable=unus
for field in changed_fields:
if field not in instance.FIELD_BLACKLIST:
truncated_fields = truncate_fields(
- six.text_type(changed_fields[field]),
- six.text_type(getattr(instance, field))
+ str(changed_fields[field]),
+ str(getattr(instance, field))
)
truncated_fields['team_id'] = instance.team_id
truncated_fields['team_id'] = instance.team_id
@@ -412,7 +412,7 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
course_module = modulestore().get_course(course_key)
except InvalidKeyError:
error = build_api_error(
- ugettext_noop(u"The supplied course id {course_id} is not valid."),
+ ugettext_noop("The supplied course id {course_id} is not valid."),
course_id=course_id_string,
)
return Response(error, status=status.HTTP_400_BAD_REQUEST)
@@ -439,7 +439,7 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
if topic_id is not None:
if topic_id not in course_module.teamsets_by_id:
error = build_api_error(
- ugettext_noop(u'The supplied topic id {topic_id} is not valid'),
+ ugettext_noop('The supplied topic id {topic_id} is not valid'),
topic_id=topic_id
)
return Response(error, status=status.HTTP_400_BAD_REQUEST)
@@ -514,14 +514,14 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
if order_by_input not in ordering_schemes:
return Response(
{
- 'developer_message': u"unsupported order_by value {ordering}".format(
+ 'developer_message': "unsupported order_by value {ordering}".format(
ordering=order_by_input,
),
# Translators: 'ordering' is a string describing a way
# of ordering a list. For example, {ordering} may be
# 'name', indicating that the user wants to sort the
# list by lower case name.
- 'user_message': _(u"The ordering {ordering} is not supported").format(
+ 'user_message': _("The ordering {ordering} is not supported").format(
ordering=order_by_input,
),
},
@@ -548,7 +548,7 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
return Response(status=status.HTTP_404_NOT_FOUND)
except InvalidKeyError:
field_errors['course_id'] = build_api_error(
- ugettext_noop(u'The supplied course_id {course_id} is not valid.'),
+ ugettext_noop('The supplied course_id {course_id} is not valid.'),
course_id=course_id
)
return Response({
@@ -558,7 +558,7 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
topic_id = request.data.get('topic_id')
if not topic_id:
field_errors['topic_id'] = build_api_error(
- ugettext_noop(u'topic_id is required'),
+ ugettext_noop('topic_id is required'),
course_id=course_id
)
return Response({
@@ -596,7 +596,7 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
return Response(error_message, status=status.HTTP_400_BAD_REQUEST)
data = request.data.copy()
- data['course_id'] = six.text_type(course_key)
+ data['course_id'] = str(course_key)
organization_protection_status = user_organization_protection_status(request.user, course_key)
if organization_protection_status != OrganizationProtectionStatus.protection_exempt:
@@ -676,7 +676,7 @@ class IsStaffOrPrivilegedOrReadOnly(IsStaffOrReadOnly):
return (
has_discussion_privileges(request.user, obj.course_id) or
IsCourseStaffInstructor.has_object_permission(self, request, view, obj) or
- super(IsStaffOrPrivilegedOrReadOnly, self).has_object_permission(request, view, obj) # lint-amnesty, pylint: disable=super-with-arguments
+ super().has_object_permission(request, view, obj)
)
@@ -814,7 +814,7 @@ class TeamsDetailView(ExpandableFieldViewMixin, RetrievePatchAPIView):
# Note: also deletes all team memberships associated with this team
team.delete()
- log.info(u'user %d deleted team %s', request.user.id, team_id)
+ log.info('user %d deleted team %s', request.user.id, team_id)
emit_team_event('edx.team.deleted', team.course_id, {
'team_id': team_id,
})
@@ -983,7 +983,7 @@ class TopicListView(GenericAPIView):
return Response({
'field_errors': {
'course_id': build_api_error(
- ugettext_noop(u"The supplied course id {course_id} is not valid."),
+ ugettext_noop("The supplied course id {course_id} is not valid."),
course_id=course_id_string
)
}
@@ -1005,12 +1005,12 @@ class TopicListView(GenericAPIView):
ordering = request.query_params.get('order_by', 'name')
if ordering not in ['name', 'team_count']:
return Response({
- 'developer_message': u"unsupported order_by value {ordering}".format(ordering=ordering),
+ 'developer_message': f"unsupported order_by value {ordering}",
# Translators: 'ordering' is a string describing a way
# of ordering a list. For example, {ordering} may be
# 'name', indicating that the user wants to sort the
# list by lower case name.
- 'user_message': _(u"The ordering {ordering} is not supported").format(ordering=ordering),
+ 'user_message': _("The ordering {ordering} is not supported").format(ordering=ordering),
}, status=status.HTTP_400_BAD_REQUEST)
# Always sort alphabetically, as it will be used as secondary sort
@@ -1636,7 +1636,7 @@ class MembershipBulkManagementView(GenericAPIView):
filename = "team-membership_{}_{}_{}.csv".format(
self.course.id.org, self.course.id.course, self.course.id.run
)
- response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)
+ response['Content-Disposition'] = f'attachment; filename="{filename}"'
load_team_membership_csv(self.course, response)
return response
@@ -1651,7 +1651,7 @@ class MembershipBulkManagementView(GenericAPIView):
team_import_manager.set_team_membership_from_csv(inputfile_handle)
if team_import_manager.import_succeeded:
- msg = "{} learners were affected.".format(team_import_manager.number_of_learners_assigned)
+ msg = f"{team_import_manager.number_of_learners_assigned} learners were affected."
return JsonResponse({'message': msg}, status=status.HTTP_201_CREATED)
else:
return JsonResponse({
@@ -1681,8 +1681,8 @@ class MembershipBulkManagementView(GenericAPIView):
try:
course_id = CourseKey.from_string(course_id_string)
except InvalidKeyError:
- raise Http404('Invalid course key: {}'.format(course_id_string)) # lint-amnesty, pylint: disable=raise-missing-from
+ raise Http404(f'Invalid course key: {course_id_string}') # lint-amnesty, pylint: disable=raise-missing-from
course_module = modulestore().get_course(course_id)
if not course_module:
- raise Http404('Course not found: {}'.format(course_id))
+ raise Http404(f'Course not found: {course_id}')
return course_module