Ticket #10899: 10899-proposal.patch

File 10899-proposal.patch, 7.8 KB (added by Aymeric Augustin, 7 years ago)
  • django/test/client.py

    commit d2804c0f564d1a5080e7afdae603865b09105578
    Author: Deni Bertovic <deni@kset.org>
    Date:   Sun May 19 14:39:53 2013 +0200
    
        Fixed #10899 -- Manipulating Session via test Client
    
    diff --git a/django/test/client.py b/django/test/client.py
    index 46f55d7..21db42d 100644
    a b from django.db import close_old_connections 
    2222from django.http import SimpleCookie, HttpRequest, QueryDict
    2323from django.template import TemplateDoesNotExist
    2424from django.test import signals
    25 from django.utils.functional import curry
     25from django.utils.functional import cached_property, curry
    2626from django.utils.encoding import force_bytes, force_str
    2727from django.utils.http import urlencode
    2828from django.utils.importlib import import_module
    class Client(RequestFactory): 
    378378        """
    379379        self.exc_info = sys.exc_info()
    380380
    381     def _session(self):
     381    @cached_property
     382    def session(self):
    382383        """
    383384        Obtains the current session variables.
    384385        """
    385         if 'django.contrib.sessions' in settings.INSTALLED_APPS:
    386             engine = import_module(settings.SESSION_ENGINE)
    387             cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
    388             if cookie:
    389                 return engine.SessionStore(cookie.value)
    390         return {}
    391     session = property(_session)
     386        if 'django.contrib.sessions' not in settings.INSTALLED_APPS:
     387            return {}
    392388
     389        engine = import_module(settings.SESSION_ENGINE)
     390        cookie = self.cookies.get(settings.SESSION_COOKIE_NAME)
     391        if cookie:
     392            session_store = engine.SessionStore(cookie.value)
     393        else:
     394            session_store = engine.SessionStore()
     395            session_store.create()
     396            self.cookies[settings.SESSION_COOKIE_NAME] = session_store.session_key
     397        return session_store
    393398
    394399    def request(self, **request):
    395400        """
    class Client(RequestFactory): 
    400405        """
    401406        environ = self._base_environ(**request)
    402407
     408        if self.session:
     409            if getattr(self.session, 'modified'):
     410                self.session.save()
     411
     412            if 'django.contrib.sessions.middleware.SessionMiddleware' in settings.MIDDLEWARE_CLASSES:
     413                # Update the session cookie since the session key can change
     414                # due to login or logout and force the session to be reloaded
     415                # on next access.
     416                self.cookies[settings.SESSION_COOKIE_NAME] = self.session.session_key
     417                self.session = None
     418
    403419        # Curry a data dictionary into an instance of the template renderer
    404420        # callback function.
    405421        data = {}
    class Client(RequestFactory): 
    536552        user = authenticate(**credentials)
    537553        if user and user.is_active \
    538554                and 'django.contrib.sessions' in settings.INSTALLED_APPS:
    539             engine = import_module(settings.SESSION_ENGINE)
    540555
    541556            # Create a fake request to store login details.
    542557            request = HttpRequest()
    543             if self.session:
    544                 request.session = self.session
    545             else:
    546                 request.session = engine.SessionStore()
     558            request.session = self.session
    547559            login(request, user)
    548560
    549561            # Save the session values.
    class Client(RequestFactory): 
    576588        if session_cookie:
    577589            session.delete(session_key=session_cookie.value)
    578590        self.cookies = SimpleCookie()
     591        self.session = None
    579592
    580593    def _handle_redirects(self, response, **extra):
    581594        "Follows any redirects by requesting responses from the server using GET."
  • docs/topics/testing/overview.txt

    diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt
    index d543099..08e1ef8 100644
    a b can access these properties as part of a test condition. 
    794794    A dictionary-like object containing session information. See the
    795795    :doc:`session documentation</topics/http/sessions>` for full details.
    796796
    797     To modify the session and then save it, it must be stored in a variable
    798     first (because a new ``SessionStore`` is created every time this property
    799     is accessed)::
     797.. versionadded:: 1.6
     798
     799    If you wish to manipulate the session directly you can do that directly
     800    on the client and the modified values will be saved on subsequent requests.
    800801
    801802        def test_something(self):
    802             session = self.client.session
    803             session['somekey'] = 'test'
    804             session.save()
     803            self.client.session['somekey'] = value
     804            self.client.session['anotherkey'] = value
     805
    805806
    806807Example
    807808~~~~~~~
  • tests/admin_views/tests.py

    diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
    index 8e678a7..8c57088 100644
    a b class AdminCustomQuerysetTest(TestCase): 
    25832583
    25842584        # 4 queries are expected: 1 for the session, 1 for the user,
    25852585        # 1 for the count and 1 for the objects on the page
    2586         with self.assertNumQueries(4):
     2586        with self.assertNumQueries(6):
    25872587            resp = self.client.get('/test_admin/admin/admin_views/person/')
    25882588            self.assertEqual(resp.context['selection_note'], '0 of 2 selected')
    25892589            self.assertEqual(resp.context['selection_note_all'], 'All 2 selected')
    class UserAdminTest(TestCase): 
    36073607        # Don't depend on a warm cache, see #17377.
    36083608        ContentType.objects.clear_cache()
    36093609
    3610         expected_queries = 10
     3610        expected_queries = 12
    36113611        # Oracle doesn't implement "RELEASE SAVPOINT", see #20387.
    36123612        if connection.vendor == 'oracle':
    36133613            expected_queries -= 1
    class GroupAdminTest(TestCase): 
    36503650    def test_group_permission_performance(self):
    36513651        g = Group.objects.create(name="test_group")
    36523652
    3653         expected_queries = 8
     3653        expected_queries = 10
    36543654        # Oracle doesn't implement "RELEASE SAVPOINT", see #20387.
    36553655        if connection.vendor == 'oracle':
    36563656            expected_queries -= 1
  • tests/test_client_regress/tests.py

    diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py
    index 2582b21..2694ce3 100644
    a b class SessionTests(TestCase): 
    756756        self.client.logout()
    757757        self.client.logout()
    758758
     759    def test_session_manipulation(self):
     760        # Check that the session can be edited as documented before #10899.
     761        session = self.client.session
     762        session['session_var'] = b'foo'
     763        session.save()
     764
     765        response = self.client.get('/test_client_regress/check_session/')
     766        self.assertEqual(response.status_code, 200)
     767        self.assertEqual(response.content, b'foo')
     768
     769    def test_direct_session_manipulation(self):
     770        # Add a value to the session
     771        self.client.session['session_var'] = b'bar'
     772        self.assertEqual(self.client.session['session_var'], b'bar')
     773
     774        # Check that the session has been modified
     775        response = self.client.get('/test_client_regress/check_session/')
     776        self.assertEqual(response.status_code, 200)
     777        self.assertEqual(response.content, b'bar')
     778
     779        # Check that the session variable persists over login
     780        # when cycle_key() is called
     781        self.client.login(username='testclient', password='password')
     782        self.assertEqual(self.client.session['session_var'], b'bar')
     783
     784        response = self.client.get('/test_client_regress/check_session/')
     785        self.assertEqual(response.status_code, 200)
     786        self.assertEqual(response.content, b'bar')
     787
     788        # Check that new session is started after logout
     789        self.client.logout()
     790        self.assertEqual(self.client.session.get('session_var'), None)
     791
     792
    759793class RequestMethodTests(TestCase):
    760794    def test_get(self):
    761795        "Request a view via request method GET"
Back to Top