diff options
| author | Luke Plant <L.Plant.98@cantab.net> | 2010-02-09 15:02:39 +0000 |
|---|---|---|
| committer | Luke Plant <L.Plant.98@cantab.net> | 2010-02-09 15:02:39 +0000 |
| commit | 4bff19463361927ff752929da1bc04e9aa1c2e72 (patch) | |
| tree | f4f31666ba7dff59b4925ca390bf139f2a3c256b /tests | |
| parent | edb6d753a85d8548d9735b6f253a4a5d9a749c75 (diff) | |
Fixed #12804 - regression with decorating admin views.
This is a BACKWARDS INCOMPATIBLE change, because it removes the flawed
'auto_adapt_to_methods' decorator, and replaces it with 'method_decorator'
which must be applied manually when necessary, as described in the 1.2
release notes.
For users of 1.1 and 1.0, this affects the decorators:
* login_required
* permission_required
* user_passes_test
For those following trunk, this also affects:
* csrf_protect
* anything created with decorator_from_middleware
If a decorator does not depend on the signature of the function it is
supposed to decorate (for example if it only does post-processing of the
result), it will not be affected.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12399 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/modeltests/test_client/views.py | 5 | ||||
| -rw-r--r-- | tests/regressiontests/decorators/tests.py | 56 |
2 files changed, 23 insertions, 38 deletions
diff --git a/tests/modeltests/test_client/views.py b/tests/modeltests/test_client/views.py index 111c72e7f5..68963fff75 100644 --- a/tests/modeltests/test_client/views.py +++ b/tests/modeltests/test_client/views.py @@ -7,6 +7,7 @@ from django.contrib.auth.decorators import login_required, permission_required from django.forms.forms import Form from django.forms import fields from django.shortcuts import render_to_response +from django.utils.decorators import method_decorator def get_view(request): "A simple view that expects a GET request, and returns a rendered template" @@ -147,14 +148,15 @@ def permission_protected_view(request): permission_protected_view = permission_required('modeltests.test_perm')(permission_protected_view) class _ViewManager(object): + @method_decorator(login_required) def login_protected_view(self, request): t = Template('This is a login protected test using a method. ' 'Username is {{ user.username }}.', name='Login Method Template') c = Context({'user': request.user}) return HttpResponse(t.render(c)) - login_protected_view = login_required(login_protected_view) + @method_decorator(permission_required('modeltests.test_perm')) def permission_protected_view(self, request): t = Template('This is a permission protected test using a method. ' 'Username is {{ user.username }}. ' @@ -162,7 +164,6 @@ class _ViewManager(object): name='Permissions Template') c = Context({'user': request.user}) return HttpResponse(t.render(c)) - permission_protected_view = permission_required('modeltests.test_perm')(permission_protected_view) _view_manager = _ViewManager() login_protected_method_view = _view_manager.login_protected_view diff --git a/tests/regressiontests/decorators/tests.py b/tests/regressiontests/decorators/tests.py index b81a5d665a..2330b0e073 100644 --- a/tests/regressiontests/decorators/tests.py +++ b/tests/regressiontests/decorators/tests.py @@ -10,7 +10,7 @@ from django.utils.functional import allow_lazy, lazy, memoize from django.views.decorators.http import require_http_methods, require_GET, require_POST from django.views.decorators.vary import vary_on_headers, vary_on_cookie from django.views.decorators.cache import cache_page, never_cache, cache_control -from django.utils.decorators import auto_adapt_to_methods +from django.utils.decorators import method_decorator from django.contrib.auth.decorators import login_required, permission_required, user_passes_test from django.contrib.admin.views.decorators import staff_member_required @@ -47,6 +47,7 @@ fully_decorated = memoize(fully_decorated, {}, 1) fully_decorated = allow_lazy(fully_decorated) fully_decorated = lazy(fully_decorated) + class DecoratorsTest(TestCase): def test_attributes(self): @@ -112,42 +113,25 @@ class DecoratorsTest(TestCase): my_view_cached2 = cache_page(my_view, 123, key_prefix="test") self.assertEqual(my_view_cached2(HttpRequest()), "response") -class MethodDecoratorAdapterTests(TestCase): - def test_auto_adapt_to_methods(self): - """ - Test that auto_adapt_to_methods actually works. - """ - # Need 2 decorators with auto_adapt_to_methods, - # to check it plays nicely with composing itself. - def my_decorator(func): - def wrapped(*args, **kwargs): - # need to ensure that the first arg isn't 'self' - self.assertEqual(args[0], "test") - return "my_decorator:" + func(*args, **kwargs) - wrapped.my_decorator_custom_attribute = True - return wraps(func)(wrapped) - my_decorator = auto_adapt_to_methods(my_decorator) +# For testing method_decorator, a decorator that assumes a single argument. +# We will get type arguments if there is a mismatch in the number of arguments. +def simple_dec(func): + def wrapper(arg): + return func("test:" + arg) + return wraps(func)(wrapper) + +simple_dec_m = method_decorator(simple_dec) - def my_decorator2(func): - def wrapped(*args, **kwargs): - # need to ensure that the first arg isn't 'self' - self.assertEqual(args[0], "test") - return "my_decorator2:" + func(*args, **kwargs) - wrapped.my_decorator2_custom_attribute = True - return wraps(func)(wrapped) - my_decorator2 = auto_adapt_to_methods(my_decorator2) - class MyClass(object): - def my_method(self, *args, **kwargs): - return "my_method:%r %r" % (args, kwargs) - my_method = my_decorator2(my_decorator(my_method)) +class MethodDecoratorTests(TestCase): + """ + Tests for method_decorator + """ + def test_method_decorator(self): + class Test(object): + @simple_dec_m + def say(self, arg): + return arg - obj = MyClass() - self.assertEqual(obj.my_method("test", 123, name='foo'), - "my_decorator2:my_decorator:my_method:('test', 123) {'name': 'foo'}") - self.assertEqual(obj.my_method.__name__, 'my_method') - self.assertEqual(getattr(obj.my_method, 'my_decorator_custom_attribute', False), - True) - self.assertEqual(getattr(obj.my_method, 'my_decorator2_custom_attribute', False), - True) + self.assertEqual("test:hello", Test().say("hello")) |
