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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user