From dc4c2f3add4f15edf05574e6e8eb101be9da4b90 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Mon, 30 May 2011 16:33:23 +0000 Subject: [PATCH] Fixed #15929 - test.client.RequestFactory keeps state/AuthMiddleware does monkey patching Thanks to m.vantellingen for the report and tests, and to aaugustin for work on the tests. git-svn-id: http://code.djangoproject.com/svn/django/trunk@16297 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/auth/middleware.py | 8 ++++- .../test_client_regress/models.py | 31 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/django/contrib/auth/middleware.py b/django/contrib/auth/middleware.py index c1211c9234..2c19a4e840 100644 --- a/django/contrib/auth/middleware.py +++ b/django/contrib/auth/middleware.py @@ -13,7 +13,13 @@ class LazyUser(object): class AuthenticationMiddleware(object): def process_request(self, request): assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'." - request.__class__.user = LazyUser() + + # We dynamically subclass request.__class__ rather than monkey patch the + # original class. + class RequestWithUser(request.__class__): + user = LazyUser() + + request.__class__ = RequestWithUser return None diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py index 6757695fec..8b47fe2e5b 100644 --- a/tests/regressiontests/test_client_regress/models.py +++ b/tests/regressiontests/test_client_regress/models.py @@ -12,7 +12,7 @@ from django.template import (TemplateDoesNotExist, TemplateSyntaxError, Context, Template, loader) import django.template.context from django.test import Client, TestCase -from django.test.client import encode_file +from django.test.client import encode_file, RequestFactory from django.test.utils import ContextList @@ -908,3 +908,32 @@ class RawPostDataTest(TestCase): response = self.client.get("/test_client_regress/raw_post_data/") except AssertionError: self.fail("Accessing request.raw_post_data from a view fetched with GET by the test client shouldn't fail.") + + +class RequestFactoryStateTest(TestCase): + """Regression tests for #15929.""" + # These tests are checking that certain middleware don't change certain + # global state. Alternatively, from the point of view of a test, they are + # ensuring test isolation behaviour. So, unusually, it doesn't make sense to + # run the tests individually, and if any are failing it is confusing to run + # them with any other set of tests. + + def setUp(self): + self.factory = RequestFactory() + + def common_test_that_should_always_pass(self): + request = self.factory.get('/') + request.session = {} + self.assertFalse(hasattr(request, 'user')) + + def test_request(self): + self.common_test_that_should_always_pass() + + def test_request_after_client(self): + # apart from the next line the three tests are identical + self.client.get('/') + self.common_test_that_should_always_pass() + + def test_request_after_client_2(self): + # This test is executed after the previous one + self.common_test_that_should_always_pass()