Added a ``session`` attribute to the test Client, to make it easier to test if session variables have been modified in a view. Also renamed Client.cookie to Client.cookies, to match documentation and common sense.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4464 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2007-02-09 13:47:36 +00:00
parent 4ccdf127d0
commit 9ba27afce0
5 changed files with 67 additions and 9 deletions

View File

@ -1,4 +1,5 @@
from cStringIO import StringIO from cStringIO import StringIO
from django.conf import settings
from django.core.handlers.base import BaseHandler from django.core.handlers.base import BaseHandler
from django.core.handlers.wsgi import WSGIRequest from django.core.handlers.wsgi import WSGIRequest
from django.dispatch import dispatcher from django.dispatch import dispatcher
@ -97,7 +98,8 @@ class Client:
def __init__(self, **defaults): def __init__(self, **defaults):
self.handler = ClientHandler() self.handler = ClientHandler()
self.defaults = defaults self.defaults = defaults
self.cookie = SimpleCookie() self.cookies = SimpleCookie()
self.session = {}
def request(self, **request): def request(self, **request):
""" """
@ -108,7 +110,7 @@ class Client:
""" """
environ = { environ = {
'HTTP_COOKIE': self.cookie, 'HTTP_COOKIE': self.cookies,
'PATH_INFO': '/', 'PATH_INFO': '/',
'QUERY_STRING': '', 'QUERY_STRING': '',
'REQUEST_METHOD': 'GET', 'REQUEST_METHOD': 'GET',
@ -141,7 +143,13 @@ class Client:
setattr(response, detail, None) setattr(response, detail, None)
if response.cookies: if response.cookies:
self.cookie.update(response.cookies) self.cookies.update(response.cookies)
if 'django.contrib.sessions' in settings.INSTALLED_APPS:
from django.contrib.sessions.middleware import SessionWrapper
cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
if cookie:
self.session = SessionWrapper(cookie.value)
return response return response

View File

@ -198,11 +198,6 @@ used as test conditions.
.. _Twill: http://twill.idyll.org/ .. _Twill: http://twill.idyll.org/
.. _Selenium: http://www.openqa.org/selenium/ .. _Selenium: http://www.openqa.org/selenium/
The Test Client is stateful; if a cookie is returned as part of a response,
that cookie is provided as part of the next request issued to that Client
instance. Expiry policies for these cookies are not followed; if you want
a cookie to expire, either delete it manually from ``client.cookies``, or
create a new Client instance (which will effectively delete all cookies).
Making requests Making requests
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
@ -296,6 +291,33 @@ for testing purposes:
.. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html .. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Persistent state
~~~~~~~~~~~~~~~~
The Test Client is stateful; if a cookie is returned as part of a response,
that cookie is provided as part of the next request issued by that Client
instance. Expiry policies for these cookies are not followed; if you want
a cookie to expire, either delete it manually or create a new Client
instance (which will effectively delete all cookies).
There are two properties of the Test Client which are used to store persistent
state information. If necessary, these properties can be interrogated as
part of a test condition.
=============== ==========================================================
Property Description
=============== ==========================================================
``cookies`` A Python ``SimpleCookie`` object, containing the current
values of all the client cookies.
``session`` A dictionary-like object containing session information.
See the `session documentation`_ for full details.
.. _`session documentation`: ../sessions/
Example
~~~~~~~
The following is a simple unit test using the Test Client:: The following is a simple unit test using the Test Client::
import unittest import unittest

View File

@ -99,3 +99,19 @@ class ClientTest(unittest.TestCase):
response = self.client.login('/test_client/login_protected_view/', 'otheruser', 'nopassword') response = self.client.login('/test_client/login_protected_view/', 'otheruser', 'nopassword')
self.assertFalse(response) self.assertFalse(response)
def test_session_modifying_view(self):
"Request a page that modifies the session"
# Session value isn't set initially
try:
self.client.session['tobacconist']
self.fail("Shouldn't have a session value")
except KeyError:
pass
from django.contrib.sessions.models import Session
response = self.client.post('/test_client/session_view/')
# Check that the session was modified
self.assertEquals(self.client.session['tobacconist'], 'hovercraft')

View File

@ -6,4 +6,5 @@ urlpatterns = patterns('',
(r'^post_view/$', views.post_view), (r'^post_view/$', views.post_view),
(r'^redirect_view/$', views.redirect_view), (r'^redirect_view/$', views.redirect_view),
(r'^login_protected_view/$', views.login_protected_view), (r'^login_protected_view/$', views.login_protected_view),
(r'^session_view/$', views.session_view)
) )

View File

@ -33,3 +33,14 @@ def login_protected_view(request):
return HttpResponse(t.render(c)) return HttpResponse(t.render(c))
login_protected_view = login_required(login_protected_view) login_protected_view = login_required(login_protected_view)
def session_view(request):
"A view that modifies the session"
request.session['tobacconist'] = 'hovercraft'
t = Template('This is a view that modifies the session.',
name='Session Modifying View Template')
c = Context()
return HttpResponse(t.render(c))