Ensure Python 3 compatibility of Teams djangoapp (#22096)

* For all files, from __future__ import unicode_literals.
* Add @python_2_unicode_compatible to both models.
* Test six.string_type(obj) for both models.

Also, fix some new pylint warnings and improve model repr methods.

MST-24
This commit is contained in:
Kyle McCormick
2019-10-22 13:42:27 -04:00
committed by GitHub
parent 606b91d66b
commit 7dbee1c3dd
18 changed files with 122 additions and 43 deletions

View File

@@ -700,7 +700,10 @@ class SingleThreadAccessTestCase(CohortedTestCase):
None
)
self.assertEqual(403, response.status_code)
self.assertEqual(views.TEAM_PERMISSION_MESSAGE, response.content)
self.assertEqual(
views.TEAM_PERMISSION_MESSAGE,
response.content.decode('utf-8'),
)
@patch('openedx.core.djangoapps.django_comment_common.comment_client.utils.requests.request', autospec=True)

View File

@@ -1,8 +1,7 @@
"""
Defines common methods shared by Teams classes
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from django.conf import settings

View File

@@ -1,7 +1,7 @@
"""
The Python API other app should use to work with Teams feature
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from lms.djangoapps.teams.models import CourseTeam

View File

@@ -1,8 +1,7 @@
"""
Defines the URL routes for the Team API.
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from django.conf import settings
from django.conf.urls import url

View File

@@ -1,4 +1,7 @@
"""Errors thrown in the Team API"""
"""
Errors thrown in the Team API.
"""
from __future__ import absolute_import, unicode_literals
class TeamAPIRequestError(Exception):

View File

@@ -1,8 +1,7 @@
"""
Tests for course_team reindex command
Tests for course_team reindex command.
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
import ddt
from django.core.management import CommandError, call_command

View File

@@ -1,8 +1,7 @@
"""
Django models related to teams functionality.
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from datetime import datetime
from uuid import uuid4
@@ -12,6 +11,7 @@ from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from django.dispatch import receiver
from django.utils.encoding import python_2_unicode_compatible
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy
from django_countries.fields import CountryField
@@ -95,14 +95,26 @@ def handle_activity(user, post, original_author_id=None):
CourseTeamMembership.update_last_activity(user, post.commentable_id)
@python_2_unicode_compatible
class CourseTeam(models.Model):
"""
This model represents team related info.
.. no_pii:
"""
def __unicode__(self):
return '[CourseTeam id={}]'.format(self.team_id)
def __str__(self):
return "{} in {}".format(self.name, self.course_id)
def __repr__(self):
return (
"<CourseTeam"
" id={0.id}"
" team_id={0.team_id}"
" team_size={0.team_size}"
" topic_id={0.topic_id}"
" course_id={0.course_id}"
">"
).format(self)
class Meta(object):
app_label = "teams"
@@ -163,9 +175,6 @@ class CourseTeam(models.Model):
return course_team
def __repr__(self):
return "<CourseTeam team_id={0.team_id}>".format(self)
def add_user(self, user):
"""Adds the given user to the CourseTeam."""
if not CourseEnrollment.is_enrolled(user, self.course_id):
@@ -183,6 +192,7 @@ class CourseTeam(models.Model):
self.save()
@python_2_unicode_compatible
class CourseTeamMembership(models.Model):
"""
This model represents the membership of a single user in a single team.
@@ -190,8 +200,17 @@ class CourseTeamMembership(models.Model):
.. no_pii:
"""
def __unicode__(self):
return "[CourseTeamMembership user={}, team={}]".format(self.user, self.team)
def __str__(self):
return "{} is member of {}".format(self.user.username, self.team)
def __repr__(self):
return (
"<CourseTeamMembership"
" id={0.id}"
" user_id={0.user.id}"
" team_id={0.team.id}"
">"
).format(self)
class Meta(object):
app_label = "teams"

View File

@@ -1,7 +1,7 @@
"""
Definition of the course team feature.
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from django.utils.translation import ugettext_noop

View File

@@ -1,6 +1,8 @@
""" Search index used to load data into elasticsearch"""
"""
Search index used to load data into elasticsearch.
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
import logging
from functools import wraps

View File

@@ -1,5 +1,7 @@
"""Defines serializers used by the Team API."""
from __future__ import absolute_import
"""
Defines serializers used by the Team API.
"""
from __future__ import absolute_import, unicode_literals
from copy import deepcopy

View File

@@ -1,6 +1,7 @@
"""Factories for testing the Teams API."""
from __future__ import absolute_import
"""
Factories for testing the Teams API.
"""
from __future__ import absolute_import, unicode_literals
from datetime import datetime
from uuid import uuid4

View File

@@ -2,10 +2,10 @@
"""
Tests for Python APIs of the Teams app
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from uuid import uuid4
import unittest
from uuid import uuid4
from opaque_keys.edx.keys import CourseKey

View File

@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
"""Tests for the teams API at the HTTP request level."""
from __future__ import absolute_import
"""
Tests for the teams API at the HTTP request level.
"""
from __future__ import absolute_import, unicode_literals
import itertools
from contextlib import contextmanager
@@ -8,6 +10,7 @@ from datetime import datetime
import ddt
import pytz
import six
from mock import Mock
from opaque_keys.edx.keys import CourseKey
@@ -33,6 +36,50 @@ COURSE_KEY1 = CourseKey.from_string('edx/history/1')
COURSE_KEY2 = CourseKey.from_string('edx/history/2')
class TestModelStrings(SharedModuleStoreTestCase):
"""
Test `__repr__` and `__str__` methods of this app's models.
"""
@classmethod
def setUpClass(cls):
super(TestModelStrings, cls).setUpClass()
cls.user = UserFactory.create(username="the-user")
CourseEnrollmentFactory.create(user=cls.user, course_id="edx/the-course/1")
cls.team = CourseTeamFactory(
course_id="edx/the-course/1",
team_id="the-team",
topic_id="the-teamset",
name="The Team"
)
cls.team_membership = cls.team.add_user(cls.user)
def test_team_repr(self):
assert repr(self.team) == (
"<CourseTeam"
" id=1"
" team_id=the-team"
" team_size=1"
" topic_id=the-teamset"
" course_id=edx/the-course/1"
">"
)
def test_team_text(self):
assert six.text_type(self.team) == (
"The Team in edx/the-course/1"
)
def test_team_membership_repr(self):
assert repr(self.team_membership) == (
"<CourseTeamMembership id=1 user_id=1 team_id=1>"
)
def test_team_membership_text_type(self):
assert six.text_type(self.team_membership) == (
"the-user is member of The Team in edx/the-course/1"
)
@ddt.ddt
class TeamMembershipTest(SharedModuleStoreTestCase):
"""Tests for the TeamMembership model."""

View File

@@ -2,7 +2,7 @@
"""
Tests for custom Teams Serializers.
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
import six
from django.core.paginator import Paginator

View File

@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
"""Tests for the teams API at the HTTP request level."""
from __future__ import absolute_import
"""
Tests for the teams API at the HTTP request level.
"""
from __future__ import absolute_import, unicode_literals
import json
import unittest
@@ -180,17 +182,17 @@ class TestDashboard(SharedModuleStoreTestCase):
# Check that initially list of user teams in course one is empty
course_one_teams_url = reverse('teams_dashboard', args=[self.course.id])
response = self.client.get(course_one_teams_url)
self.assertContains(response, '"teams": {"count": 0') # pylint: disable=unicode-format-string
self.assertContains(response, '"teams": {"count": 0')
# Add user to a course one team
course_one_team.add_user(self.user)
# Check that list of user teams in course one is not empty, it is one now
response = self.client.get(course_one_teams_url)
self.assertContains(response, '"teams": {"count": 1') # pylint: disable=unicode-format-string
self.assertContains(response, '"teams": {"count": 1')
# Check that list of user teams in course two is still empty
course_two_teams_url = reverse('teams_dashboard', args=[course_two.id])
response = self.client.get(course_two_teams_url)
self.assertContains(response, '"teams": {"count": 0') # pylint: disable=unicode-format-string
self.assertContains(response, '"teams": {"count": 0')
class TeamAPITestCase(APITestCase, SharedModuleStoreTestCase):

View File

@@ -2,7 +2,7 @@
Defines the URL routes for this app.
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from django.conf.urls import url
from django.contrib.auth.decorators import login_required

View File

@@ -1,6 +1,8 @@
"""Utility methods related to teams."""
"""
Utility methods related to teams.
"""
from __future__ import absolute_import
from __future__ import absolute_import, unicode_literals
from eventtracking import tracker

View File

@@ -1,6 +1,7 @@
"""HTTP endpoints for the Teams API."""
from __future__ import absolute_import
"""
HTTP endpoints for the Teams API.
"""
from __future__ import absolute_import, unicode_literals
import logging