Merge pull request #21701 from edx/python3-swarm

Python3 swarm
This commit is contained in:
Feanil Patel
2019-09-19 10:23:04 -04:00
committed by GitHub
40 changed files with 199 additions and 142 deletions

View File

@@ -50,7 +50,7 @@ class AccessTokenExchangeFormTest(AccessTokenExchangeTestMixin):
self.assertTrue(form.is_valid())
self.assertEqual(form.cleaned_data["user"], self.user)
self.assertEqual(form.cleaned_data["client"], self.oauth_client)
self.assertEqual(scope.to_names(form.cleaned_data["scope"]), expected_scopes)
self.assertEqual(set(scope.to_names(form.cleaned_data["scope"])), set(expected_scopes))
# This is necessary because cms does not implement third party auth

View File

@@ -63,11 +63,16 @@ class AccessTokenExchangeViewTest(AccessTokenExchangeTestMixin):
timedelta(seconds=int(content["expires_in"])),
provider.constants.EXPIRE_DELTA_PUBLIC
)
self.assertEqual(content["scope"], ' '.join(expected_scopes))
actual_scopes = content["scope"]
if actual_scopes:
actual_scopes = actual_scopes.split(' ')
else:
actual_scopes = []
self.assertEqual(set(actual_scopes), set(expected_scopes))
token = self.oauth2_adapter.get_access_token(token_string=content["access_token"])
self.assertEqual(token.user, self.user)
self.assertEqual(self.oauth2_adapter.get_client_for_token(token), self.oauth_client)
self.assertEqual(self.oauth2_adapter.get_token_scope_names(token), expected_scopes)
self.assertEqual(set(self.oauth2_adapter.get_token_scope_names(token)), set(expected_scopes))
def test_single_access_token(self):
def extract_token(response):
@@ -184,7 +189,7 @@ class TestLoginWithAccessTokenView(TestCase):
Calls the login_with_access_token endpoint and verifies the response given the expected values.
"""
url = reverse("login_with_access_token")
response = self.client.post(url, HTTP_AUTHORIZATION=b"Bearer {0}".format(access_token))
response = self.client.post(url, HTTP_AUTHORIZATION=u"Bearer {0}".format(access_token).encode('utf-8'))
self.assertEqual(response.status_code, expected_status_code)
if expected_cookie_name:
self.assertIn(expected_cookie_name, response.cookies)

View File

@@ -10,7 +10,6 @@ import ddt
import mock
import six
from django.core.management import call_command
from django.utils import six
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@@ -230,6 +229,12 @@ class TestDumpToNeo4jCommand(TestDumpToNeo4jCommandBase):
)
class SomeThing(object):
"""Just to test the stringification of an object."""
def __str__(self):
return "<SomeThing>"
@skip_unless_lms
@ddt.ddt
class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase):
@@ -379,7 +384,7 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase):
@ddt.data(
(1, 1),
(object, "<type 'object'>"),
(SomeThing(), "<SomeThing>"),
(1.5, 1.5),
("úñîçø∂é", "úñîçø∂é"),
(b"plain string", b"plain string"),
@@ -388,7 +393,8 @@ class TestModuleStoreSerializer(TestDumpToNeo4jCommandBase):
((1,), "(1,)"),
# list of elements should be coerced into a list of the
# string representations of those elements
([object, object], ["<type 'object'>", "<type 'object'>"])
([SomeThing(), SomeThing()], ["<SomeThing>", "<SomeThing>"]),
([1, 2], ["1", "2"]),
)
@ddt.unpack
def test_coerce_types(self, original_value, coerced_expected):

View File

@@ -36,7 +36,7 @@ def get_shared_secret_key(provider_id):
if isinstance(secret, six.text_type):
try:
secret = str(secret)
secret.encode('ascii')
except UnicodeEncodeError:
secret = None
log.error(u'Shared secret key for credit provider "%s" contains non-ASCII unicode.', provider_id)

View File

@@ -8,6 +8,7 @@ from datetime import datetime
import six
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from django_mysql.models import ListCharField
from oauth2_provider.settings import oauth2_settings
@@ -19,6 +20,7 @@ from openedx.core.djangolib.markup import HTML
from openedx.core.lib.request_utils import get_request_or_stub
@python_2_unicode_compatible
class RestrictedApplication(models.Model):
"""
This model lists which django-oauth-toolkit Applications are considered 'restricted'
@@ -35,7 +37,7 @@ class RestrictedApplication(models.Model):
class Meta:
app_label = 'oauth_dispatch'
def __unicode__(self):
def __str__(self):
"""
Return a unicode representation of this object
"""
@@ -59,6 +61,7 @@ class RestrictedApplication(models.Model):
return access_token.expires == datetime(1970, 1, 1, tzinfo=utc)
@python_2_unicode_compatible
class ApplicationAccess(models.Model):
"""
Specifies access control information for the associated Application.
@@ -81,7 +84,7 @@ class ApplicationAccess(models.Model):
def get_scopes(cls, application):
return cls.objects.get(application=application).scopes
def __unicode__(self):
def __str__(self):
"""
Return a unicode representation of this object.
"""
@@ -91,6 +94,7 @@ class ApplicationAccess(models.Model):
)
@python_2_unicode_compatible
class ApplicationOrganization(models.Model):
"""
Associates a DOT Application to an Organization.
@@ -129,7 +133,7 @@ class ApplicationOrganization(models.Model):
queryset = queryset.filter(relation_type=relation_type)
return [r.organization.name for r in queryset]
def __unicode__(self):
def __str__(self):
"""
Return a unicode representation of this object.
"""

View File

@@ -63,7 +63,7 @@ class AccessTokenLoginMixin(object):
return self.client.post(
self.login_with_access_token_url,
HTTP_AUTHORIZATION=b"Bearer {0}".format(access_token if access_token else self.access_token)
HTTP_AUTHORIZATION=u"Bearer {0}".format(access_token if access_token else self.access_token).encode('utf-8')
)
def _assert_access_token_is_valid(self, access_token=None):

View File

@@ -210,7 +210,7 @@ def get_all_orgs():
This can be used, for example, to do filtering.
Returns:
A list of all organizations present in the site configuration.
A set of all organizations present in the site configuration.
"""
# Import is placed here to avoid model import at project startup.
from openedx.core.djangoapps.site_configuration.models import SiteConfiguration

View File

@@ -114,7 +114,7 @@ class SiteConfiguration(models.Model):
for example, to do filtering.
Returns:
A list of all organizations present in site configuration.
A set of all organizations present in site configuration.
"""
org_filter_set = set()

View File

@@ -4,6 +4,7 @@ Tests for site configuration's django models.
from __future__ import absolute_import
from mock import patch
import six
from django.test import TestCase
from django.db import IntegrityError, transaction
@@ -321,10 +322,7 @@ class SiteConfigurationTests(TestCase):
)
# Test that the default value is returned if the value for the given key is not found in the configuration
self.assertListEqual(
list(SiteConfiguration.get_all_orgs()),
expected_orgs,
)
six.assertCountEqual(self, SiteConfiguration.get_all_orgs(), expected_orgs)
def test_get_all_orgs_returns_only_enabled(self):
"""
@@ -343,7 +341,4 @@ class SiteConfigurationTests(TestCase):
)
# Test that the default value is returned if the value for the given key is not found in the configuration
self.assertListEqual(
list(SiteConfiguration.get_all_orgs()),
expected_orgs,
)
six.assertCountEqual(self, SiteConfiguration.get_all_orgs(), expected_orgs)

View File

@@ -225,13 +225,13 @@ class StudentViewShimTest(TestCase):
)
response = view(HttpRequest())
self.assertEqual(response.status_code, 403)
self.assertEqual(response.content, "third-party-auth")
self.assertEqual(response.content, b"third-party-auth")
def test_non_json_response(self):
view = self._shimmed_view(HttpResponse(content="Not a JSON dict"))
response = view(HttpRequest())
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, "Not a JSON dict")
self.assertEqual(response.content, b"Not a JSON dict")
@ddt.data("redirect", "redirect_url")
def test_ignore_redirect_from_json(self, redirect_key):
@@ -254,7 +254,7 @@ class StudentViewShimTest(TestCase):
)
response = view(HttpRequest())
self.assertEqual(response.status_code, 400)
self.assertEqual(response.content, "Error!")
self.assertEqual(response.content, b"Error!")
def test_preserve_headers(self):
view_response = HttpResponse()

View File

@@ -8,6 +8,7 @@ from __future__ import absolute_import
import logging
import six
from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth import login as django_login
@@ -110,11 +111,11 @@ def _enforce_password_policy_compliance(request, user):
password_policy_compliance.enforce_compliance_on_login(user, request.POST.get('password'))
except password_policy_compliance.NonCompliantPasswordWarning as e:
# Allow login, but warn the user that they will be required to reset their password soon.
PageLevelMessages.register_warning_message(request, e.message)
PageLevelMessages.register_warning_message(request, six.text_type(e))
except password_policy_compliance.NonCompliantPasswordException as e:
send_password_reset_email_for_user(user, request)
# Prevent the login attempt.
raise AuthFailedError(e.message)
raise AuthFailedError(six.text_type(e))
def _generate_not_activated_message(user):

View File

@@ -323,7 +323,7 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
visible=True,
enabled=True,
icon_class='',
icon_image=SimpleUploadedFile('icon.svg', '<svg><rect width="50" height="100"/></svg>'),
icon_image=SimpleUploadedFile('icon.svg', b'<svg><rect width="50" height="100"/></svg>'),
)
self.hidden_enabled_provider = self.configure_linkedin_provider(
visible=False,
@@ -606,7 +606,7 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
tpa_hint = self.hidden_disabled_provider.provider_id
params = [("next", "/courses/something/?tpa_hint={0}".format(tpa_hint))]
response = self.client.get(reverse('signin_user'), params, HTTP_ACCEPT="text/html")
self.assertNotIn(response.content, tpa_hint)
self.assertNotIn(response.content.decode('utf-8'), tpa_hint)
@ddt.data(
('signin_user', 'login'),
@@ -650,7 +650,7 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
tpa_hint = self.hidden_disabled_provider.provider_id
params = [("next", "/courses/something/?tpa_hint={0}".format(tpa_hint))]
response = self.client.get(reverse(url_name), params, HTTP_ACCEPT="text/html")
self.assertNotIn(response.content, tpa_hint)
self.assertNotIn(response.content.decode('utf-8'), tpa_hint)
@override_settings(FEATURES=dict(settings.FEATURES, THIRD_PARTY_AUTH_HINT='oa2-google-oauth2'))
@ddt.data(

View File

@@ -10,6 +10,7 @@ from config_models.models import ConfigurationModel
from django.db import models
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy
from edx_django_utils.cache import RequestCache
from opaque_keys.edx.django.models import CourseKeyField
@@ -92,6 +93,7 @@ def pre_save_callback(sender, instance, **kwargs): # pylint: disable=unused-arg
instance._old_mode = None # pylint: disable=protected-access
@python_2_unicode_compatible
class VerifiedTrackCohortedCourse(models.Model):
"""
Tracks which courses have verified track auto-cohorting enabled.
@@ -109,7 +111,7 @@ class VerifiedTrackCohortedCourse(models.Model):
CACHE_NAMESPACE = u"verified_track_content.VerifiedTrackCohortedCourse.cache."
def __unicode__(self):
def __str__(self):
return u"Course: {}, enabled: {}".format(six.text_type(self.course_key), self.enabled)
@classmethod

View File

@@ -1,16 +1,18 @@
"""Tests for zendesk_proxy views."""
from __future__ import absolute_import
import json
from copy import deepcopy
import json
import ddt
from django.urls import reverse
from django.test.utils import override_settings
from mock import MagicMock, patch
import six
from six.moves import range
from openedx.core.djangoapps.zendesk_proxy.v0.views import ZENDESK_REQUESTS_PER_HOUR
from openedx.core.lib.api.test_utils import ApiTestCase
from six.moves import range
@ddt.ddt
@@ -45,14 +47,30 @@ class ZendeskProxyTestCase(ApiTestCase):
self.assertHttpCreated(response)
(mock_args, mock_kwargs) = mock_post.call_args
self.assertEqual(mock_args, ('https://www.superrealurlsthataredefinitelynotfake.com/api/v2/tickets.json',))
six.assertCountEqual(self, mock_kwargs.keys(), ['headers', 'data'])
self.assertEqual(
mock_kwargs,
mock_kwargs['headers'],
{
'headers': {
'content-type': 'application/json',
'Authorization': 'Bearer abcdefghijklmnopqrstuvwxyz1234567890'
'content-type': 'application/json',
'Authorization': 'Bearer abcdefghijklmnopqrstuvwxyz1234567890'
}
)
self.assertEqual(
json.loads(mock_kwargs['data']),
{
'ticket': {
'comment': {
'body': "Help! I'm trapped in a unit test factory and I can't get out!",
'uploads': None,
},
'custom_fields': None,
'requester': {
'email': 'JohnQStudent@example.com',
'name': 'John Q. Student',
},
'subject': 'Python Unit Test Help Request',
'tags': ['python_unit_test'],
},
'data': '{"ticket": {"comment": {"body": "Help! I\'m trapped in a unit test factory and I can\'t get out!", "uploads": null}, "tags": ["python_unit_test"], "subject": "Python Unit Test Help Request", "custom_fields": null, "requester": {"name": "John Q. Student", "email": "JohnQStudent@example.com"}}}' # pylint: disable=line-too-long
}
)

View File

@@ -1,16 +1,19 @@
"""Tests for zendesk_proxy views."""
from __future__ import absolute_import
import json
from copy import deepcopy
import json
import ddt
from django.urls import reverse
from django.test.utils import override_settings
from mock import MagicMock, patch
import six
from six.moves import range
from openedx.core.djangoapps.zendesk_proxy.v1.views import ZendeskProxyThrottle
from openedx.core.lib.api.test_utils import ApiTestCase
from six.moves import range
@ddt.ddt
@@ -53,14 +56,30 @@ class ZendeskProxyTestCase(ApiTestCase):
self.assertHttpCreated(response)
(mock_args, mock_kwargs) = mock_post.call_args
self.assertEqual(mock_args, ('https://www.superrealurlsthataredefinitelynotfake.com/api/v2/tickets.json',))
six.assertCountEqual(self, mock_kwargs.keys(), ['headers', 'data'])
self.assertEqual(
mock_kwargs,
mock_kwargs['headers'],
{
'headers': {
'content-type': 'application/json',
'Authorization': 'Bearer abcdefghijklmnopqrstuvwxyz1234567890'
'content-type': 'application/json',
'Authorization': 'Bearer abcdefghijklmnopqrstuvwxyz1234567890'
}
)
self.assertEqual(
json.loads(mock_kwargs['data']),
{
'ticket': {
'comment': {
'body': "Help! I'm trapped in a unit test factory and I can't get out!",
'uploads': None,
},
'custom_fields': [{'id': '001', 'value': 'demo-course'}],
'requester': {
'email': 'JohnQStudent@example.com',
'name': 'John Q. Student',
},
'subject': 'Python Unit Test Help Request',
'tags': ['python_unit_test'],
},
'data': '{"ticket": {"comment": {"body": "Help! I\'m trapped in a unit test factory and I can\'t get out!", "uploads": null}, "tags": ["python_unit_test"], "subject": "Python Unit Test Help Request", "custom_fields": [{"id": "001", "value": "demo-course"}], "requester": {"name": "John Q. Student", "email": "JohnQStudent@example.com"}}}' # pylint: disable=line-too-long
}
)