From 02f7b75720edeca09002cec232881772fd5feee8 Mon Sep 17 00:00:00 2001 From: Kevin Nasto Date: Mon, 6 May 2019 22:45:27 -0400 Subject: [PATCH] INCR-220 (#20414) * Modernized 220 * Isort 220 * Fixed unused value in key,value dictionary interation --- .../djangoapps/user_api/preferences/api.py | 28 +++++--- .../user_api/preferences/tests/test_api.py | 35 +++++----- .../user_api/preferences/tests/test_views.py | 18 +++-- .../djangoapps/user_api/preferences/views.py | 17 +++-- .../djangoapps/user_api/tests/factories.py | 7 +- .../djangoapps/user_api/tests/test_helpers.py | 10 +-- .../user_api/tests/test_middleware.py | 7 +- .../djangoapps/user_api/tests/test_models.py | 8 ++- .../user_api/tests/test_partition_schemes.py | 3 + .../djangoapps/user_api/tests/test_views.py | 65 +++++++++++-------- .../verification_api/tests/test_views.py | 6 +- .../user_api/verification_api/views.py | 8 ++- 12 files changed, 128 insertions(+), 84 deletions(-) diff --git a/openedx/core/djangoapps/user_api/preferences/api.py b/openedx/core/djangoapps/user_api/preferences/api.py index 3c65f14679..e114aabe79 100644 --- a/openedx/core/djangoapps/user_api/preferences/api.py +++ b/openedx/core/djangoapps/user_api/preferences/api.py @@ -1,24 +1,32 @@ """ API for managing user preferences. """ +from __future__ import absolute_import + import logging +import six from django.conf import settings from django.core.exceptions import ObjectDoesNotExist -from django_countries import countries from django.db import IntegrityError from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_noop - -from openedx.core.lib.time_zone_utils import get_display_time_zone +from django_countries import countries from pytz import common_timezones, common_timezones_set, country_timezones from six import text_type +from openedx.core.lib.time_zone_utils import get_display_time_zone from student.models import User, UserProfile from track import segment + from ..errors import ( - UserAPIInternalError, UserAPIRequestError, UserNotFound, UserNotAuthorized, - PreferenceValidationError, PreferenceUpdateError, CountryCodeError + CountryCodeError, + PreferenceUpdateError, + PreferenceValidationError, + UserAPIInternalError, + UserAPIRequestError, + UserNotAuthorized, + UserNotFound ) from ..helpers import intercept_errors, serializer_is_dirty from ..models import UserOrgTag, UserPreference @@ -102,7 +110,7 @@ def update_user_preferences(requesting_user, update, user=None): PreferenceUpdateError: the operation failed when performing the update. UserAPIInternalError: the operation failed due to an unexpected error. """ - if not user or isinstance(user, basestring): + if not user or isinstance(user, six.string_types): user = _get_authorized_user(requesting_user, user) else: _check_authorized(requesting_user, user.username) @@ -113,7 +121,7 @@ def update_user_preferences(requesting_user, update, user=None): for preference_key in update.keys(): preference_value = update[preference_key] if preference_value is not None: - preference_value = unicode(preference_value) + preference_value = six.text_type(preference_value) try: serializer = create_user_preference_serializer(user, preference_key, preference_value) validate_user_preference_serializer(serializer, preference_key, preference_value) @@ -130,7 +138,7 @@ def update_user_preferences(requesting_user, update, user=None): for preference_key in update.keys(): preference_value = update[preference_key] if preference_value is not None: - preference_value = unicode(preference_value) + preference_value = six.text_type(preference_value) try: serializer = serializers[preference_key] @@ -169,7 +177,7 @@ def set_user_preference(requesting_user, preference_key, preference_value, usern """ existing_user = _get_authorized_user(requesting_user, username) if preference_value is not None: - preference_value = unicode(preference_value) + preference_value = six.text_type(preference_value) serializer = create_user_preference_serializer(existing_user, preference_key, preference_value) validate_user_preference_serializer(serializer, preference_key, preference_value) @@ -365,7 +373,7 @@ def validate_user_preference_serializer(serializer, preference_key, preference_v Raises: PreferenceValidationError: the supplied key and/or value for a user preference are invalid. """ - if preference_value is None or unicode(preference_value).strip() == '': + if preference_value is None or six.text_type(preference_value).strip() == '': format_string = ugettext_noop(u"Preference '{preference_key}' cannot be set to an empty value.") raise PreferenceValidationError({ preference_key: { diff --git a/openedx/core/djangoapps/user_api/preferences/tests/test_api.py b/openedx/core/djangoapps/user_api/preferences/tests/test_api.py index 9c0e1e4818..092c05aee0 100644 --- a/openedx/core/djangoapps/user_api/preferences/tests/test_api.py +++ b/openedx/core/djangoapps/user_api/preferences/tests/test_api.py @@ -2,40 +2,41 @@ """ Unit tests for preference APIs. """ -import datetime -import ddt -from mock import patch -from pytz import common_timezones, utc +from __future__ import absolute_import +import datetime + +import ddt +from dateutil.parser import parse as parse_datetime from django.contrib.auth.models import User from django.test.utils import override_settings -from dateutil.parser import parse as parse_datetime +from mock import patch +from pytz import common_timezones, utc from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms from openedx.core.lib.time_zone_utils import get_display_time_zone from student.models import UserProfile from student.tests.factories import UserFactory - from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory from ...accounts.api import create_account from ...errors import ( - UserNotFound, - UserNotAuthorized, - PreferenceValidationError, - PreferenceUpdateError, CountryCodeError, + PreferenceUpdateError, + PreferenceValidationError, + UserNotAuthorized, + UserNotFound ) from ...models import UserOrgTag from ...preferences.api import ( + delete_user_preference, + get_country_time_zones, get_user_preference, get_user_preferences, set_user_preference, - update_user_preferences, - delete_user_preference, update_email_opt_in, - get_country_time_zones, + update_user_preferences ) @@ -139,7 +140,7 @@ class TestPreferenceAPI(CacheIsolationTestCase): with self.assertRaises(PreferenceValidationError) as context_manager: set_user_preference(self.user, too_long_key, "new_value") errors = context_manager.exception.preference_errors - self.assertEqual(len(errors.keys()), 1) + self.assertEqual(len(list(errors.keys())), 1) self.assertEqual( errors[too_long_key], { @@ -152,7 +153,7 @@ class TestPreferenceAPI(CacheIsolationTestCase): with self.assertRaises(PreferenceValidationError) as context_manager: set_user_preference(self.user, self.test_preference_key, empty_value) errors = context_manager.exception.preference_errors - self.assertEqual(len(errors.keys()), 1) + self.assertEqual(len(list(errors.keys())), 1) self.assertEqual( errors[self.test_preference_key], { @@ -241,7 +242,7 @@ class TestPreferenceAPI(CacheIsolationTestCase): with self.assertRaises(PreferenceValidationError) as context_manager: update_user_preferences(self.user, {too_long_key: "new_value"}) errors = context_manager.exception.preference_errors - self.assertEqual(len(errors.keys()), 1) + self.assertEqual(len(list(errors.keys())), 1) self.assertEqual( errors[too_long_key], { @@ -254,7 +255,7 @@ class TestPreferenceAPI(CacheIsolationTestCase): with self.assertRaises(PreferenceValidationError) as context_manager: update_user_preferences(self.user, {self.test_preference_key: empty_value}) errors = context_manager.exception.preference_errors - self.assertEqual(len(errors.keys()), 1) + self.assertEqual(len(list(errors.keys())), 1) self.assertEqual( errors[self.test_preference_key], { diff --git a/openedx/core/djangoapps/user_api/preferences/tests/test_views.py b/openedx/core/djangoapps/user_api/preferences/tests/test_views.py index 0cf2dbb816..c36fec72c2 100644 --- a/openedx/core/djangoapps/user_api/preferences/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/preferences/tests/test_views.py @@ -3,19 +3,23 @@ Unit tests for preference APIs. """ -import ddt -import json -from mock import patch +from __future__ import absolute_import -from django.urls import reverse +import json + +import ddt +import six from django.test.testcases import TransactionTestCase +from django.urls import reverse +from mock import patch from rest_framework.test import APIClient -from student.tests.factories import UserFactory, TEST_PASSWORD from openedx.core.djangolib.testing.utils import skip_unless_lms +from student.tests.factories import TEST_PASSWORD, UserFactory + from ...accounts.tests.test_views import UserAPITestCase from ..api import set_user_preference -from .test_api import get_expected_validation_developer_message, get_expected_key_error_user_message +from .test_api import get_expected_key_error_user_message, get_expected_validation_developer_message TOO_LONG_PREFERENCE_KEY = u"x" * 256 @@ -546,7 +550,7 @@ class TestPreferencesDetailAPI(UserAPITestCase): self.client.login(username=self.user.username, password=TEST_PASSWORD) self.send_put(self.client, preference_value) response = self.send_get(self.client) - self.assertEqual(unicode(preference_value), response.data) + self.assertEqual(six.text_type(preference_value), response.data) @ddt.data( ("different_client", "different_user"), diff --git a/openedx/core/djangoapps/user_api/preferences/views.py b/openedx/core/djangoapps/user_api/preferences/views.py index 1e87803372..e4ae2ee962 100644 --- a/openedx/core/djangoapps/user_api/preferences/views.py +++ b/openedx/core/djangoapps/user_api/preferences/views.py @@ -4,22 +4,27 @@ An API for retrieving user preference information. For additional information and historical context, see: https://openedx.atlassian.net/wiki/display/TNL/User+API """ -from rest_framework.views import APIView -from rest_framework.response import Response -from rest_framework import status -from rest_framework import permissions +from __future__ import absolute_import from django.db import transaction from django.utils.translation import ugettext as _ from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser +from rest_framework import permissions, status +from rest_framework.response import Response +from rest_framework.views import APIView from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser from openedx.core.lib.api.parsers import MergePatchParser from openedx.core.lib.api.permissions import IsUserInUrlOrStaff -from ..errors import UserNotFound, UserNotAuthorized, PreferenceValidationError, PreferenceUpdateError + +from ..errors import PreferenceUpdateError, PreferenceValidationError, UserNotAuthorized, UserNotFound from .api import ( - get_user_preference, get_user_preferences, set_user_preference, update_user_preferences, delete_user_preference + delete_user_preference, + get_user_preference, + get_user_preferences, + set_user_preference, + update_user_preferences ) diff --git a/openedx/core/djangoapps/user_api/tests/factories.py b/openedx/core/djangoapps/user_api/tests/factories.py index bffcf76e39..9adfc8fc48 100644 --- a/openedx/core/djangoapps/user_api/tests/factories.py +++ b/openedx/core/djangoapps/user_api/tests/factories.py @@ -1,9 +1,12 @@ """Provides factories for User API models.""" -from factory.django import DjangoModelFactory +from __future__ import absolute_import + from factory import SubFactory -from student.tests.factories import UserFactory +from factory.django import DjangoModelFactory from opaque_keys.edx.locator import CourseLocator +from student.tests.factories import UserFactory + from ..models import UserCourseTag, UserOrgTag, UserPreference diff --git a/openedx/core/djangoapps/user_api/tests/test_helpers.py b/openedx/core/djangoapps/user_api/tests/test_helpers.py index a8a46303da..54372a2a43 100644 --- a/openedx/core/djangoapps/user_api/tests/test_helpers.py +++ b/openedx/core/djangoapps/user_api/tests/test_helpers.py @@ -1,20 +1,20 @@ """ Tests for helper functions. """ +from __future__ import absolute_import + import json import re -import mock + import ddt +import mock import pytest from django import forms from django.http import HttpRequest, HttpResponse from django.test import TestCase from six import text_type -from ..helpers import ( - intercept_errors, shim_student_view, - FormDescription, InvalidFieldError -) +from ..helpers import FormDescription, InvalidFieldError, intercept_errors, shim_student_view class FakeInputException(Exception): diff --git a/openedx/core/djangoapps/user_api/tests/test_middleware.py b/openedx/core/djangoapps/user_api/tests/test_middleware.py index bb1e79eb02..b674edd00e 100644 --- a/openedx/core/djangoapps/user_api/tests/test_middleware.py +++ b/openedx/core/djangoapps/user_api/tests/test_middleware.py @@ -1,14 +1,15 @@ """Tests for user API middleware""" -from mock import Mock, patch +from __future__ import absolute_import from django.http import HttpResponse from django.test import TestCase from django.test.client import RequestFactory +from mock import Mock, patch -from student.tests.factories import UserFactory, AnonymousUserFactory +from student.tests.factories import AnonymousUserFactory, UserFactory -from ..tests.factories import UserCourseTagFactory from ..middleware import UserTagsEventContextMiddleware +from ..tests.factories import UserCourseTagFactory class TagsMiddlewareTest(TestCase): diff --git a/openedx/core/djangoapps/user_api/tests/test_models.py b/openedx/core/djangoapps/user_api/tests/test_models.py index 0821b89055..3c51bcb6b2 100644 --- a/openedx/core/djangoapps/user_api/tests/test_models.py +++ b/openedx/core/djangoapps/user_api/tests/test_models.py @@ -1,17 +1,19 @@ """ Test UserPreferenceModel and UserPreference events """ +from __future__ import absolute_import + from django.db import IntegrityError from django.test import TestCase from student.tests.factories import UserFactory from student.tests.tests import UserSettingsEventTestMixin -from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory -from ..tests.factories import UserPreferenceFactory, UserCourseTagFactory, UserOrgTagFactory -from ..models import UserPreference, UserOrgTag +from ..models import UserOrgTag, UserPreference from ..preferences.api import set_user_preference +from ..tests.factories import UserCourseTagFactory, UserOrgTagFactory, UserPreferenceFactory class UserPreferenceModelTest(ModuleStoreTestCase): diff --git a/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py b/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py index 93454844d0..45761bb0e4 100644 --- a/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py +++ b/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py @@ -1,11 +1,14 @@ """ Test the user api's partition extensions. """ +from __future__ import absolute_import + from collections import defaultdict import pytest from django.test import TestCase from mock import patch +from six.moves import range from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme, UserPartitionError from student.tests.factories import UserFactory diff --git a/openedx/core/djangoapps/user_api/tests/test_views.py b/openedx/core/djangoapps/user_api/tests/test_views.py index 6cb70d45ca..5bfe5b0e86 100644 --- a/openedx/core/djangoapps/user_api/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/tests/test_views.py @@ -1,5 +1,7 @@ """Tests for the user API at the HTTP request level. """ +from __future__ import absolute_import + import datetime import json from unittest import skipUnless @@ -7,49 +9,60 @@ from unittest import skipUnless import ddt import httpretty import mock +import six from django.conf import settings from django.contrib.auth.models import User from django.core import mail -from django.urls import reverse from django.test.client import RequestFactory from django.test.testcases import TransactionTestCase from django.test.utils import override_settings +from django.urls import reverse from opaque_keys.edx.keys import CourseKey -from pytz import common_timezones_set, UTC +from pytz import UTC, common_timezones_set from six import text_type -from social_django.models import UserSocialAuth, Partial +from six.moves import range +from social_django.models import Partial, UserSocialAuth from openedx.core.djangoapps.django_comment_common import models from openedx.core.djangoapps.site_configuration.helpers import get_value -from openedx.core.lib.api.test_utils import ApiTestCase, TEST_API_KEY -from openedx.core.lib.time_zone_utils import get_display_time_zone from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms +from openedx.core.lib.api.test_utils import TEST_API_KEY, ApiTestCase +from openedx.core.lib.time_zone_utils import get_display_time_zone from student.tests.factories import UserFactory -from third_party_auth.tests.testutil import simulate_running_pipeline, ThirdPartyAuthTestMixin +from third_party_auth.tests.testutil import ThirdPartyAuthTestMixin, simulate_running_pipeline from third_party_auth.tests.utils import ( - ThirdPartyOAuthTestMixin, ThirdPartyOAuthTestMixinFacebook, ThirdPartyOAuthTestMixinGoogle + ThirdPartyOAuthTestMixin, + ThirdPartyOAuthTestMixinFacebook, + ThirdPartyOAuthTestMixinGoogle ) from util.password_policy_validators import ( - create_validator_config, password_validators_instruction_texts, password_validators_restrictions, DEFAULT_MAX_PASSWORD_LENGTH, + create_validator_config, + password_validators_instruction_texts, + password_validators_restrictions ) -from .test_helpers import TestCaseForm from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory + from ..accounts import ( - NAME_MAX_LENGTH, EMAIL_MIN_LENGTH, EMAIL_MAX_LENGTH, - USERNAME_MIN_LENGTH, USERNAME_MAX_LENGTH, USERNAME_BAD_LENGTH_MSG + EMAIL_MAX_LENGTH, + EMAIL_MIN_LENGTH, + NAME_MAX_LENGTH, + USERNAME_BAD_LENGTH_MSG, + USERNAME_MAX_LENGTH, + USERNAME_MIN_LENGTH ) +from ..accounts.api import get_account_settings from ..accounts.tests.retirement_helpers import ( # pylint: disable=unused-import RetirementTestCase, fake_requested_retirement, setup_retirement_states ) -from ..accounts.api import get_account_settings from ..models import UserOrgTag from ..tests.factories import UserPreferenceFactory from ..tests.test_constants import SORTED_COUNTRIES +from .test_helpers import TestCaseForm USER_LIST_URI = "/user_api/v1/users/" USER_PREFERENCE_LIST_URI = "/user_api/v1/user_prefs/" @@ -80,9 +93,9 @@ class UserAPITestCase(ApiTestCase): def assertUserIsValid(self, user): """Assert that the given user result is valid""" - self.assertItemsEqual(user.keys(), ["email", "id", "name", "username", "preferences", "url"]) + self.assertItemsEqual(list(user.keys()), ["email", "id", "name", "username", "preferences", "url"]) self.assertItemsEqual( - user["preferences"].items(), + list(user["preferences"].items()), [(pref.key, pref.value) for pref in self.prefs if pref.user.id == user["id"]] ) self.assertSelfReferential(user) @@ -91,7 +104,7 @@ class UserAPITestCase(ApiTestCase): """ Assert that the given preference is acknowledged by the system """ - self.assertItemsEqual(pref.keys(), ["user", "key", "value", "url"]) + self.assertItemsEqual(list(pref.keys()), ["user", "key", "value", "url"]) self.assertSelfReferential(pref) self.assertUserIsValid(pref["user"]) @@ -111,7 +124,7 @@ class EmptyUserTestCase(UserAPITestCase): class EmptyRoleTestCase(UserAPITestCase): """Test that the endpoint supports empty result sets""" course_id = CourseKey.from_string("org/course/run") - LIST_URI = ROLE_LIST_URI + "?course_id=" + unicode(course_id) + LIST_URI = ROLE_LIST_URI + "?course_id=" + six.text_type(course_id) def test_get_list_empty(self): """Test that the endpoint properly returns empty result sets""" @@ -147,7 +160,7 @@ class RoleTestCase(UserApiTestCase): Test cases covering Role-related views and their behaviors """ course_id = CourseKey.from_string("org/course/run") - LIST_URI = ROLE_LIST_URI + "?course_id=" + unicode(course_id) + LIST_URI = ROLE_LIST_URI + "?course_id=" + six.text_type(course_id) def setUp(self): super(RoleTestCase, self).setUp() @@ -1294,7 +1307,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): ] + [ { "value": country_code, - "name": unicode(country_name), + "name": six.text_type(country_name), "default": True if country_code == expected_country_code else False } for country_code, country_name in SORTED_COUNTRIES @@ -1483,8 +1496,8 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): } ] + [ { - "value": unicode(year), - "name": unicode(year), + "value": six.text_type(year), + "name": six.text_type(year), "default": False } for year in range(this_year, this_year - 120, -1) @@ -1627,7 +1640,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): ] + [ { "value": country_code, - "name": unicode(country_name), + "name": six.text_type(country_name), "default": False } for country_code, country_name in SORTED_COUNTRIES @@ -2333,7 +2346,7 @@ class RegistrationViewTest(ThirdPartyAuthTestMixin, UserAPITestCase): msg=u"Could not find field {name}".format(name=expected_field["name"]) ) - for key, value in expected_field.iteritems(): + for key in expected_field: self.assertEqual( actual_field[key], expected_field[key], msg=u"Expected {expected} for {key} but got {actual} instead".format( @@ -2624,7 +2637,7 @@ class UpdateEmailOptInTestCase(UserAPITestCase, SharedModuleStoreTestCase): """Tests the email opt in preference""" # Register, which should trigger an activation email response = self.client.post(self.url, { - "course_id": unicode(self.course.id), + "course_id": six.text_type(self.course.id), "email_opt_in": opt }) self.assertHttpOK(response) @@ -2643,7 +2656,7 @@ class UpdateEmailOptInTestCase(UserAPITestCase, SharedModuleStoreTestCase): """Tests the email opt in preference""" params = {} if use_course_id: - params["course_id"] = unicode(self.course.id) + params["course_id"] = six.text_type(self.course.id) if use_opt_in: params["email_opt_in"] = u"True" @@ -2656,7 +2669,7 @@ class UpdateEmailOptInTestCase(UserAPITestCase, SharedModuleStoreTestCase): self.user.save() # Register, which should trigger an activation email response = self.client.post(self.url, { - "course_id": unicode(self.course.id), + "course_id": six.text_type(self.course.id), "email_opt_in": u"True" }) self.assertHttpOK(response) @@ -2672,7 +2685,7 @@ class UpdateEmailOptInTestCase(UserAPITestCase, SharedModuleStoreTestCase): """ self.client.logout() response = self.client.post(self.url, { - "course_id": unicode(self.course.id), + "course_id": six.text_type(self.course.id), "email_opt_in": u"True" }) self.assertEqual(response.status_code, 403) diff --git a/openedx/core/djangoapps/user_api/verification_api/tests/test_views.py b/openedx/core/djangoapps/user_api/verification_api/tests/test_views.py index 94ec816176..a31f72d51b 100644 --- a/openedx/core/djangoapps/user_api/verification_api/tests/test_views.py +++ b/openedx/core/djangoapps/user_api/verification_api/tests/test_views.py @@ -1,14 +1,14 @@ """ Tests for API endpoints. """ -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals import datetime -import freezegun import json +import freezegun from django.conf import settings -from django.urls import reverse from django.test import TestCase from django.test.utils import override_settings +from django.urls import reverse from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification from student.tests.factories import UserFactory diff --git a/openedx/core/djangoapps/user_api/verification_api/views.py b/openedx/core/djangoapps/user_api/verification_api/views.py index 065d4a83ce..d77599ae79 100644 --- a/openedx/core/djangoapps/user_api/verification_api/views.py +++ b/openedx/core/djangoapps/user_api/verification_api/views.py @@ -1,14 +1,18 @@ """ Verification API v1 views. """ +from __future__ import absolute_import + from django.http import Http404 from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication from rest_framework.authentication import SessionAuthentication from rest_framework.generics import RetrieveAPIView from rest_framework_oauth.authentication import OAuth2Authentication -from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification, SSOVerification, ManualVerification +from lms.djangoapps.verify_student.models import ManualVerification, SoftwareSecurePhotoVerification, SSOVerification from lms.djangoapps.verify_student.utils import most_recent_verification from openedx.core.djangoapps.user_api.serializers import ( - SoftwareSecurePhotoVerificationSerializer, SSOVerificationSerializer, ManualVerificationSerializer, + ManualVerificationSerializer, + SoftwareSecurePhotoVerificationSerializer, + SSOVerificationSerializer ) from openedx.core.lib.api.permissions import IsStaffOrOwner