From a333a71411edb58d409275f2d8b4323eec23506f Mon Sep 17 00:00:00 2001 From: David Ormsbee Date: Thu, 19 Nov 2020 09:41:25 -0500 Subject: [PATCH] Format blackout dates to match rest of Discussions API. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Technically, both "2020-10-20T23:59:00Z" and "2020-10-20T23:59:00+00:00" are ISO-8601 compliant, though the latter is preferred. The Discussions API uses the "Z" notation for almost all its dates, except for the course blackout dates (those times when students aren't allowed to post anything because it would threaten exam integrity). That's because the blackout dates are manually formatted using datetime.isoformat(). As best as I can tell, we've always passed back the "+00:00" for the blackout dates. But at some point, this broke the expectations of the mobile apps, which expect the "+Z" format, like the rest of the API. This commit changes the blackout dates to be returned in +Z format when the blackout datetimes are specified by the user in UTC (which is almost always the case–I suspect the mobile clients would break if the dates were specified in other timezones anyhow). --- lms/djangoapps/discussion/rest_api/api.py | 26 ++++++++++++++++++- .../discussion/rest_api/tests/test_api.py | 4 +-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lms/djangoapps/discussion/rest_api/api.py b/lms/djangoapps/discussion/rest_api/api.py index 5bbea6df41..eaa067de8c 100644 --- a/lms/djangoapps/discussion/rest_api/api.py +++ b/lms/djangoapps/discussion/rest_api/api.py @@ -203,11 +203,35 @@ def get_course(request, course_key): CourseNotFoundError: if the course does not exist or is not accessible to the requesting user """ + def _format_datetime(dt): + """ + Provide backwards compatible datetime formatting. + + Technically, both "2020-10-20T23:59:00Z" and "2020-10-20T23:59:00+00:00" + are ISO-8601 compliant, though the latter is preferred. We've always + just passed back whatever datetime.isoformat() generated for the + blackout dates in the get_course function (the "+00:00" format). At some + point, this broke the expectation of the mobile app code, which expects + these dates to be formatted in the same way that DRF formats the other + datetimes in this API (the "Z" format). + + For the sake of compatibility, we're doing a manual substitution back to + the old format here. This is done with a replacement because it's + possible (though really not recommended) to enter blackout dates in + something other than the UTC timezone, in which case we should not do + the substitution... though really, that would probably break mobile + client parsing of the dates as well. :-P + """ + return dt.isoformat().replace('+00:00', 'Z') + course = _get_course(course_key, request.user) return { "id": six.text_type(course_key), "blackouts": [ - {"start": blackout["start"].isoformat(), "end": blackout["end"].isoformat()} + { + "start": _format_datetime(blackout["start"]), + "end": _format_datetime(blackout["end"]), + } for blackout in course.get_discussion_blackout_datetimes() ], "thread_list_url": get_thread_list_url(request, course_key), diff --git a/lms/djangoapps/discussion/rest_api/tests/test_api.py b/lms/djangoapps/discussion/rest_api/tests/test_api.py index df7c838d76..f74680d509 100644 --- a/lms/djangoapps/discussion/rest_api/tests/test_api.py +++ b/lms/djangoapps/discussion/rest_api/tests/test_api.py @@ -179,8 +179,8 @@ class GetCourseTestBlackouts(ForumsEnableMixin, UrlResetMixin, ModuleStoreTestCa self.assertEqual( result["blackouts"], [ - {"start": "2015-06-09T00:00:00+00:00", "end": "2015-06-10T00:00:00+00:00"}, - {"start": "2015-06-11T00:00:00+00:00", "end": "2015-06-12T00:00:00+00:00"}, + {"start": "2015-06-09T00:00:00Z", "end": "2015-06-10T00:00:00Z"}, + {"start": "2015-06-11T00:00:00Z", "end": "2015-06-12T00:00:00Z"}, ] )