diff --git a/django/test/client.py b/django/test/client.py
|
a
|
b
|
|
| 13 | 13 | |
| 14 | 14 | from django.conf import settings |
| 15 | 15 | from django.contrib.auth import authenticate, login |
| | 16 | from django.contrib.sessions.middleware import SessionMiddleware |
| 16 | 17 | from django.core.handlers.base import BaseHandler |
| 17 | 18 | from django.core.handlers.wsgi import WSGIRequest |
| 18 | 19 | from django.core.signals import got_request_exception |
| … |
… |
|
| 24 | 25 | from django.utils.http import urlencode |
| 25 | 26 | from django.utils.importlib import import_module |
| 26 | 27 | from django.utils.itercompat import is_iterable |
| | 28 | from django.utils.module_loading import issubclass_by_name |
| 27 | 29 | from django.db import close_connection |
| 28 | 30 | from django.test.utils import ContextList |
| 29 | 31 | |
| … |
… |
|
| 497 | 499 | not available. |
| 498 | 500 | """ |
| 499 | 501 | user = authenticate(**credentials) |
| 500 | | if user and user.is_active \ |
| 501 | | and 'django.contrib.sessions.middleware.SessionMiddleware' in settings.MIDDLEWARE_CLASSES: |
| | 502 | sessions_enabled = False |
| | 503 | if user and user.is_active: |
| | 504 | for middleware in settings.MIDDLEWARE_CLASSES: |
| | 505 | sessions_enabled = issubclass_by_name(middleware, SessionMiddleware) |
| | 506 | if sessions_enabled: |
| | 507 | break |
| | 508 | if sessions_enabled: |
| 502 | 509 | engine = import_module(settings.SESSION_ENGINE) |
| 503 | 510 | |
| 504 | 511 | # Create a fake request to store login details. |
diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py
|
a
|
b
|
|
| 2 | 2 | import os |
| 3 | 3 | import sys |
| 4 | 4 | |
| | 5 | from django.utils.importlib import import_module |
| | 6 | |
| 5 | 7 | |
| 6 | 8 | def module_has_submodule(package, module_name): |
| 7 | 9 | """See if 'module' is in 'package'.""" |
| … |
… |
|
| 67 | 69 | else: |
| 68 | 70 | # Exhausted the search, so the module cannot be found. |
| 69 | 71 | return False |
| | 72 | |
| | 73 | def issubclass_by_name(symbol_name, klass): |
| | 74 | """ |
| | 75 | Verify if possibly dotted, in string form :param symbol_name: is a |
| | 76 | subclass of :param klass:. |
| | 77 | |
| | 78 | Example: |
| | 79 | |
| | 80 | >>> issubclass_by_name('django.utils.datastructures.SortedDict', dict) |
| | 81 | True |
| | 82 | """ |
| | 83 | try: |
| | 84 | mod, dot, klass_name = symbol_name.rpartition('.') |
| | 85 | mod = import_module(mod) |
| | 86 | subclass = getattr(mod, klass_name, None) |
| | 87 | if subclass is None: |
| | 88 | return False |
| | 89 | return issubclass(subclass, klass) |
| | 90 | except ImportError: |
| | 91 | return False |
diff --git a/tests/regressiontests/test_client_regress/middleware.py b/tests/regressiontests/test_client_regress/middleware.py
new file mode 100644
|
-
|
+
|
|
| | 1 | from django.contrib.sessions.middleware import SessionMiddleware |
| | 2 | |
| | 3 | |
| | 4 | class CustomizedDjangoSessionMiddleware(SessionMiddleware): |
| | 5 | pass |
| | 6 | |
| | 7 | |
| | 8 | class ReallyCustomSessionMiddleware(object): |
| | 9 | pass |
diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py
|
a
|
b
|
|
| 2 | 2 | """ |
| 3 | 3 | Regression tests for the Test Client, especially the customized assertions. |
| 4 | 4 | """ |
| | 5 | from __future__ import absolute_import |
| | 6 | |
| 5 | 7 | import os |
| 6 | 8 | import warnings |
| 7 | 9 | |
| … |
… |
|
| 17 | 19 | from django.template.response import SimpleTemplateResponse |
| 18 | 20 | from django.http import HttpResponse |
| 19 | 21 | |
| | 22 | from . import middleware |
| | 23 | |
| | 24 | CUSTOM_SESSION_MIDDLEWARE1 = '%s.CustomizedDjangoSessionMiddleware' % middleware.__name__ |
| | 25 | CUSTOM_SESSION_MIDDLEWARE2 = '%s.ReallyCustomSessionMiddleware' % middleware.__name__ |
| 20 | 26 | |
| 21 | 27 | class AssertContainsTests(TestCase): |
| 22 | 28 | def setUp(self): |
| … |
… |
|
| 564 | 570 | self.assertEqual(response.context['user'].username, 'testclient') |
| 565 | 571 | |
| 566 | 572 | |
| 567 | | class NoSessionsAppInstalled(SessionEngineTests): |
| 568 | | """#7836 - Test client can exercise sessions even when 'django.contrib.sessions' isn't installed.""" |
| | 573 | class SessionMiddlewareTests(TestCase): |
| | 574 | fixtures = ['testdata'] |
| 569 | 575 | |
| 570 | 576 | # Remove the 'session' contrib app from INSTALLED_APPS |
| 571 | 577 | @override_settings(INSTALLED_APPS=tuple(filter(lambda a: a!='django.contrib.sessions', settings.INSTALLED_APPS))) |
| 572 | | def test_session(self): |
| | 578 | def test_no_session_app(self): |
| | 579 | """Test client can exercise sessions even when 'django.contrib.sessions' isn't installed (#7836).""" |
| 573 | 580 | # This request sets a session variable. |
| 574 | 581 | response = self.client.get('/test_client_regress/set_session/') |
| 575 | 582 | self.assertEqual(response.status_code, 200) |
| 576 | 583 | self.assertEqual(self.client.session['session_var'], 'YES') |
| 577 | 584 | |
| | 585 | # Use a custom session middleware that inherits from Django's |
| | 586 | @override_settings( |
| | 587 | MIDDLEWARE_CLASSES=map( |
| | 588 | lambda m: m if m!='django.contrib.sessions.middleware.SessionMiddleware' else CUSTOM_SESSION_MIDDLEWARE1, |
| | 589 | settings.MIDDLEWARE_CLASSES |
| | 590 | ) |
| | 591 | ) |
| | 592 | def test_subclassed_session_middleware(self): |
| | 593 | """Test client can login when a subclass of Django SessionMiddleware is in use (#16605).""" |
| | 594 | login = self.client.login(username='testclient', password='password') |
| | 595 | self.assertTrue(login, 'Could not log in') |
| | 596 | |
| | 597 | # Use a custom session middleware |
| | 598 | @override_settings( |
| | 599 | MIDDLEWARE_CLASSES=map( |
| | 600 | lambda m: m if m!='django.contrib.sessions.middleware.SessionMiddleware' else CUSTOM_SESSION_MIDDLEWARE2, |
| | 601 | settings.MIDDLEWARE_CLASSES |
| | 602 | ) |
| | 603 | ) |
| | 604 | def test_custom_session_middleware(self): |
| | 605 | """Test client can login when a custom session middleware is in use.""" |
| | 606 | login = self.client.login(username='testclient', password='password') |
| | 607 | self.assertTrue(login, 'Could not log in') |
| | 608 | |
| 578 | 609 | |
| 579 | 610 | class URLEscapingTests(TestCase): |
| 580 | 611 | def test_simple_argument_get(self): |
diff --git a/tests/regressiontests/utils/module_loading.py b/tests/regressiontests/utils/module_loading.py
|
a
|
b
|
|
| 5 | 5 | |
| 6 | 6 | from django.utils import unittest |
| 7 | 7 | from django.utils.importlib import import_module |
| 8 | | from django.utils.module_loading import module_has_submodule |
| | 8 | from django.utils.module_loading import module_has_submodule, issubclass_by_name |
| 9 | 9 | |
| 10 | 10 | |
| 11 | 11 | class DefaultLoader(unittest.TestCase): |
| … |
… |
|
| 154 | 154 | def tearDown(self): |
| 155 | 155 | super(CustomLoader, self).tearDown() |
| 156 | 156 | sys.path_hooks.pop(0) |
| | 157 | |
| | 158 | |
| | 159 | class IssubclassByNameTests(unittest.TestCase): |
| | 160 | def test_success(self): |
| | 161 | self.assertTrue(issubclass_by_name('django.utils.datastructures.SortedDict', dict)) |
| | 162 | |
| | 163 | def test_failure(self): |
| | 164 | self.assertFalse(issubclass_by_name('django.utils.datastructures.SortedDict', str)) |
| | 165 | |
| | 166 | def test_import_failure_returns_false(self): |
| | 167 | self.assertFalse(issubclass_by_name('i.dont.exist.SortedDict', str)) |
| | 168 | |
| | 169 | def test_bogus_symbol_name_returns_false(self): |
| | 170 | self.assertFalse(issubclass_by_name('django.utils.module_loading.IDontExist', str)) |
diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py
|
a
|
b
|
|
| 5 | 5 | |
| 6 | 6 | from .dateformat import DateFormatTests |
| 7 | 7 | from .feedgenerator import FeedgeneratorTest |
| 8 | | from .module_loading import DefaultLoader, EggLoader, CustomLoader |
| | 8 | from .module_loading import DefaultLoader, EggLoader, CustomLoader, IssubclassByNameTests |
| 9 | 9 | from .termcolors import TermColorTests |
| 10 | 10 | from .html import TestUtilsHtml |
| 11 | 11 | from .http import TestUtilsHttp |