* Modernized 220

* Isort 220

* Fixed unused value in key,value dictionary interation
This commit is contained in:
Kevin Nasto
2019-05-06 22:45:27 -04:00
committed by Michael Youngstrom
parent 4138445ad7
commit 02f7b75720
12 changed files with 128 additions and 84 deletions

View File

@@ -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: {

View File

@@ -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],
{

View File

@@ -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"),

View File

@@ -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
)

View File

@@ -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

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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