Fix problems that drf-yasg uncovered.
These were originally fixed individually, but had to be reverted, and are now combined in one commit. The originals were:7b9040f6b0This enum was backwards8774ff1f9bUse ref_name to disambiguate serializers that drf-yasg would otherwise assume are the same.8a44397139Is this field missing because it is None?4a1154a7caGive a safer buffer for clearing the rate limiting64c47856ddDRF 3.7.4 changed how you delegate to another view, so don't7359ca4fb2Is this right? It fixes two testsfdd66e5390Adjust the expected error message for DRF 3.7.79257f68fd8The default TIME_ZONE should be UTC
This commit is contained in:
@@ -125,7 +125,7 @@ class CourseRunImageSerializer(serializers.Serializer):
|
||||
class CourseRunSerializerCommonFieldsMixin(serializers.Serializer):
|
||||
schedule = CourseRunScheduleSerializer(source='*', required=False)
|
||||
pacing_type = CourseRunPacingTypeField(source='self_paced', required=False,
|
||||
choices=(('instructor_paced', False), ('self_paced', True),))
|
||||
choices=((False, 'instructor_paced'), (True, 'self_paced'),))
|
||||
|
||||
|
||||
class CourseRunSerializer(CourseRunSerializerCommonFieldsMixin, CourseRunTeamSerializerMixin, serializers.Serializer):
|
||||
|
||||
@@ -680,7 +680,7 @@ STATICFILES_DIRS = [
|
||||
|
||||
# Locale/Internationalization
|
||||
CELERY_TIMEZONE = 'UTC'
|
||||
TIME_ZONE = 'America/New_York' # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
TIME_ZONE = 'UTC'
|
||||
LANGUAGE_CODE = 'en' # http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGES_BIDI = lms.envs.common.LANGUAGES_BIDI
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ class CourseModeSerializer(serializers.Serializer):
|
||||
sku = serializers.CharField(required=False)
|
||||
bulk_sku = serializers.CharField(required=False)
|
||||
|
||||
class Meta(object):
|
||||
# For disambiguating within the drf-yasg swagger schema
|
||||
ref_name = 'course_modes.CourseMode'
|
||||
|
||||
def create(self, validated_data):
|
||||
"""
|
||||
This method must be implemented for use in our
|
||||
|
||||
@@ -30,7 +30,6 @@ class EntitlementsSerializerTests(ModuleStoreTestCase):
|
||||
'course_uuid': str(entitlement.course_uuid),
|
||||
'mode': entitlement.mode,
|
||||
'refund_locked': False,
|
||||
'enrollment_course_run': None,
|
||||
'order_number': entitlement.order_number,
|
||||
'created': entitlement.created.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
|
||||
'modified': entitlement.modified.strftime('%Y-%m-%dT%H:%M:%S.%fZ'),
|
||||
|
||||
@@ -36,6 +36,8 @@ class CourseModeSerializer(serializers.ModelSerializer):
|
||||
class Meta(object):
|
||||
model = CourseMode
|
||||
fields = ('name', 'currency', 'price', 'sku', 'bulk_sku', 'expires')
|
||||
# For disambiguating within the drf-yasg swagger schema
|
||||
ref_name = 'commerce.CourseMode'
|
||||
|
||||
|
||||
def validate_course_id(course_id):
|
||||
@@ -77,6 +79,10 @@ class CourseSerializer(serializers.Serializer):
|
||||
verification_deadline = PossiblyUndefinedDateTimeField(format=None, allow_null=True, required=False)
|
||||
modes = CourseModeSerializer(many=True)
|
||||
|
||||
class Meta(object):
|
||||
# For disambiguating within the drf-yasg swagger schema
|
||||
ref_name = 'commerce.Course'
|
||||
|
||||
def validate(self, attrs):
|
||||
""" Ensure the verification deadline occurs AFTER the course mode enrollment deadlines. """
|
||||
verification_deadline = attrs.get('verification_deadline', None)
|
||||
|
||||
@@ -61,6 +61,7 @@ from openedx.core.djangoapps.django_comment_common.signals import (
|
||||
thread_voted
|
||||
)
|
||||
from openedx.core.djangoapps.django_comment_common.utils import get_course_discussion_settings
|
||||
from openedx.core.djangoapps.user_api.accounts.api import get_account_settings
|
||||
from openedx.core.djangoapps.user_api.accounts.views import AccountViewSet
|
||||
from openedx.core.lib.exceptions import CourseNotFoundError, DiscussionNotFoundError, PageNotFoundError
|
||||
|
||||
@@ -365,10 +366,11 @@ def _get_user_profile_dict(request, usernames):
|
||||
|
||||
A dict with username as key and user profile details as value.
|
||||
"""
|
||||
request.GET = request.GET.copy() # Make a mutable copy of the GET parameters.
|
||||
request.GET['username'] = usernames
|
||||
user_profile_details = AccountViewSet.as_view({'get': 'list'})(request).data
|
||||
|
||||
if usernames:
|
||||
username_list = usernames.split(",")
|
||||
else:
|
||||
username_list = []
|
||||
user_profile_details = get_account_settings(request, username_list)
|
||||
return {user['username']: user for user in user_profile_details}
|
||||
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ class GradingPolicyTestMixin(object):
|
||||
"""
|
||||
The view should return HTTP status 401 if user is unauthenticated.
|
||||
"""
|
||||
self.assert_get_for_course(expected_status_code=401, HTTP_AUTHORIZATION=None)
|
||||
self.assert_get_for_course(expected_status_code=401, HTTP_AUTHORIZATION="")
|
||||
|
||||
def test_staff_authorized(self):
|
||||
"""
|
||||
|
||||
@@ -147,3 +147,5 @@ class UserSerializer(serializers.ModelSerializer):
|
||||
model = User
|
||||
fields = ('id', 'username', 'email', 'name', 'course_enrollments')
|
||||
lookup_field = 'username'
|
||||
# For disambiguating within the drf-yasg swagger schema
|
||||
ref_name = 'mobile_api.User'
|
||||
|
||||
@@ -1738,8 +1738,8 @@ class ProgramCourseEnrollmentOverviewViewTests(ProgramCacheTestCaseMixin, Shared
|
||||
|
||||
course_run_overview = response.data['course_runs'][0]
|
||||
|
||||
self.assertEqual(course_run_overview['start_date'], '2018-12-31T05:00:00Z')
|
||||
self.assertEqual(course_run_overview['end_date'], '2019-01-02T05:00:00Z')
|
||||
self.assertEqual(course_run_overview['start_date'], '2018-12-31T00:00:00Z')
|
||||
self.assertEqual(course_run_overview['end_date'], '2019-01-02T00:00:00Z')
|
||||
|
||||
# course run end date may not exist
|
||||
self.course_overview.end = None
|
||||
|
||||
@@ -1749,8 +1749,8 @@ class RegistrationCodeRedemptionCourseEnrollment(SharedModuleStoreTestCase):
|
||||
response = self.client.post(url)
|
||||
self.assertEquals(response.status_code, 403)
|
||||
|
||||
# now reset the time to 5 mins from now in future in order to unblock
|
||||
reset_time = datetime.now(UTC) + timedelta(seconds=300)
|
||||
# now reset the time to 6 mins from now in future in order to unblock
|
||||
reset_time = datetime.now(UTC) + timedelta(seconds=361)
|
||||
with freeze_time(reset_time):
|
||||
response = self.client.post(url)
|
||||
self.assertEquals(response.status_code, 404)
|
||||
@@ -1773,8 +1773,8 @@ class RegistrationCodeRedemptionCourseEnrollment(SharedModuleStoreTestCase):
|
||||
response = self.client.get(url)
|
||||
self.assertEquals(response.status_code, 403)
|
||||
|
||||
# now reset the time to 5 mins from now in future in order to unblock
|
||||
reset_time = datetime.now(UTC) + timedelta(seconds=300)
|
||||
# now reset the time to 6 mins from now in future in order to unblock
|
||||
reset_time = datetime.now(UTC) + timedelta(seconds=361)
|
||||
with freeze_time(reset_time):
|
||||
response = self.client.get(url)
|
||||
self.assertEquals(response.status_code, 404)
|
||||
|
||||
@@ -997,7 +997,7 @@ MEDIA_URL = '/media/'
|
||||
|
||||
# Locale/Internationalization
|
||||
CELERY_TIMEZONE = 'UTC'
|
||||
TIME_ZONE = 'America/New_York' # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
TIME_ZONE = 'UTC'
|
||||
LANGUAGE_CODE = 'en' # http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
# these languages display right to left
|
||||
LANGUAGES_BIDI = ("he", "ar", "fa", "ur", "fa-ir", "rtl")
|
||||
|
||||
@@ -45,6 +45,10 @@ class CourseSerializer(serializers.Serializer): # pylint: disable=abstract-meth
|
||||
invite_only = serializers.BooleanField(source="invitation_only")
|
||||
course_modes = serializers.SerializerMethodField()
|
||||
|
||||
class Meta(object):
|
||||
# For disambiguating within the drf-yasg swagger schema
|
||||
ref_name = 'enrollment.Course'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.include_expired = kwargs.pop("include_expired", False)
|
||||
super(CourseSerializer, self).__init__(*args, **kwargs)
|
||||
|
||||
@@ -551,7 +551,7 @@ class TestAccountsAPI(CacheIsolationTestCase, UserAPITestCase):
|
||||
("level_of_education", "none", u"ȻħȺɍłɇs", u'"ȻħȺɍłɇs" is not a valid choice.'),
|
||||
("country", "GB", "XY", u'"XY" is not a valid choice.'),
|
||||
("year_of_birth", 2009, "not_an_int", u"A valid integer is required."),
|
||||
("name", "bob", "z" * 256, u"Ensure this value has at most 255 characters (it has 256)."),
|
||||
("name", "bob", "z" * 256, u"Ensure this field has no more than 255 characters."),
|
||||
("name", u"ȻħȺɍłɇs", " ", u"The name field must be at least 1 character long."),
|
||||
("goals", "Smell the roses"),
|
||||
("mailing_address", "Sesame Street"),
|
||||
|
||||
@@ -470,7 +470,7 @@ def get_expected_validation_developer_message(preference_key, preference_value):
|
||||
preference_key=preference_key,
|
||||
preference_value=preference_value,
|
||||
error={
|
||||
"key": [u"Ensure this value has at most 255 characters (it has 256)."]
|
||||
"key": [u"Ensure this field has no more than 255 characters."]
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ class UserSerializer(serializers.HyperlinkedModelSerializer):
|
||||
# This list is the minimal set required by the notification service
|
||||
fields = ("id", "url", "email", "name", "username", "preferences")
|
||||
read_only_fields = ("id", "email", "username")
|
||||
# For disambiguating within the drf-yasg swagger schema
|
||||
ref_name = 'user_api.User'
|
||||
|
||||
|
||||
class UserPreferenceSerializer(serializers.HyperlinkedModelSerializer):
|
||||
|
||||
@@ -207,7 +207,7 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
|
||||
all_configs[CourseLocator('7-True', 'test_course', 'run-None')],
|
||||
{
|
||||
'enabled': (True, Provenance.org),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run),
|
||||
'studio_override_enabled': (None, Provenance.default),
|
||||
}
|
||||
)
|
||||
@@ -215,7 +215,7 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
|
||||
all_configs[CourseLocator('7-True', 'test_course', 'run-False')],
|
||||
{
|
||||
'enabled': (False, Provenance.run),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run),
|
||||
'studio_override_enabled': (None, Provenance.default),
|
||||
}
|
||||
)
|
||||
@@ -223,7 +223,7 @@ class TestContentTypeGatingConfig(CacheIsolationTestCase):
|
||||
all_configs[CourseLocator('7-None', 'test_course', 'run-None')],
|
||||
{
|
||||
'enabled': (True, Provenance.site),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run),
|
||||
'studio_override_enabled': (None, Provenance.default),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -236,21 +236,21 @@ class TestCourseDurationLimitConfig(CacheIsolationTestCase):
|
||||
all_configs[CourseLocator('7-True', 'test_course', 'run-None')],
|
||||
{
|
||||
'enabled': (True, Provenance.org),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run),
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
all_configs[CourseLocator('7-True', 'test_course', 'run-False')],
|
||||
{
|
||||
'enabled': (False, Provenance.run),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run),
|
||||
}
|
||||
)
|
||||
self.assertEqual(
|
||||
all_configs[CourseLocator('7-None', 'test_course', 'run-None')],
|
||||
{
|
||||
'enabled': (True, Provenance.site),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 5, tzinfo=pytz.UTC), Provenance.run),
|
||||
'enabled_as_of': (datetime(2018, 1, 1, 0, tzinfo=pytz.UTC), Provenance.run),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user