From 0a75f8ece0a2a764004c1279893289f2331e4433 Mon Sep 17 00:00:00 2001 From: Omar Al-Ithawi Date: Sun, 16 Apr 2017 10:24:48 +0300 Subject: [PATCH] Unicode support for request_cached decorator and commentable_id --- common/djangoapps/request_cache/middleware.py | 7 +++--- common/djangoapps/request_cache/tests.py | 23 +++++++++++++++++++ .../django_comment_client/base/tests.py | 4 +++- .../django_comment_client/permissions.py | 2 +- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/common/djangoapps/request_cache/middleware.py b/common/djangoapps/request_cache/middleware.py index 7aa3c0b048..246f490b69 100644 --- a/common/djangoapps/request_cache/middleware.py +++ b/common/djangoapps/request_cache/middleware.py @@ -2,6 +2,7 @@ An implementation of a RequestCache. This cache is reset at the beginning and end of every request. """ +from django.utils.encoding import force_text import crum import threading @@ -108,7 +109,7 @@ def func_call_cache_key(func, *args, **kwargs): the function's name, and a stringified list of arguments and a query string-style stringified list of keyword arguments. """ - converted_args = map(str, args) - converted_kwargs = map(str, reduce(list.__add__, map(list, sorted(kwargs.iteritems())), [])) + converted_args = map(force_text, args) + converted_kwargs = map(force_text, reduce(list.__add__, map(list, sorted(kwargs.iteritems())), [])) cache_keys = [func.__module__, func.func_name] + converted_args + converted_kwargs - return '.'.join(cache_keys) + return u'.'.join(cache_keys) diff --git a/common/djangoapps/request_cache/tests.py b/common/djangoapps/request_cache/tests.py index 8c3dc093f9..1f8d76db61 100644 --- a/common/djangoapps/request_cache/tests.py +++ b/common/djangoapps/request_cache/tests.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """ Tests for the request cache. """ @@ -183,6 +184,28 @@ class TestRequestCache(TestCase): self.assertEqual(result, 4) self.assertEqual(to_be_wrapped.call_count, 4) + def test_request_cached_mixed_unicode_str_args(self): + """ + Ensure that request_cached can work with mixed str and Unicode parameters. + """ + RequestCache.clear_request_cache() + + def dummy_function(arg1, arg2): + """ + A dummy function that expects an str and unicode arguments. + """ + assert isinstance(arg1, str), 'First parameter has to be of type `str`' + assert isinstance(arg2, unicode), 'Second parameter has to be of type `unicode`' + return True + + self.assertTrue(dummy_function('Hello', u'World'), 'Should be callable with ASCII chars') + self.assertTrue(dummy_function('H∂llå', u'Wørld'), 'Should be callable with non-ASCII chars') + + wrapped = request_cached(dummy_function) + + self.assertTrue(wrapped('Hello', u'World'), 'Wrapper should handle ASCII only chars') + self.assertTrue(wrapped('H∂llå', u'Wørld'), 'Wrapper should handle non-ASCII chars') + def test_request_cached_with_none_result(self): """ Ensure that calling a decorated function that returns None diff --git a/lms/djangoapps/django_comment_client/base/tests.py b/lms/djangoapps/django_comment_client/base/tests.py index 720b249753..53680f5ed1 100644 --- a/lms/djangoapps/django_comment_client/base/tests.py +++ b/lms/djangoapps/django_comment_client/base/tests.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """Tests for django comment client views.""" from contextlib import contextmanager import logging @@ -1168,7 +1169,8 @@ class CreateThreadUnicodeTestCase( request.user = self.student request.view_name = "create_thread" response = views.create_thread( - request, course_id=unicode(self.course.id), commentable_id="non_team_dummy_id" + # The commentable ID contains a username, the Unicode char below ensures it works fine + request, course_id=unicode(self.course.id), commentable_id=u"non_tåem_dummy_id" ) self.assertEqual(response.status_code, 200) diff --git a/lms/djangoapps/django_comment_client/permissions.py b/lms/djangoapps/django_comment_client/permissions.py index 8b9d50305c..36e4b2b35e 100644 --- a/lms/djangoapps/django_comment_client/permissions.py +++ b/lms/djangoapps/django_comment_client/permissions.py @@ -81,7 +81,7 @@ def _check_condition(user, condition, content): try: commentable_id = content['commentable_id'] request_cache_dict = RequestCache.get_request_cache().data - cache_key = "django_comment_client.check_team_member.{}.{}".format(user.id, commentable_id) + cache_key = u"django_comment_client.check_team_member.{}.{}".format(user.id, commentable_id) if cache_key in request_cache_dict: return request_cache_dict[cache_key] team = get_team(commentable_id)