summaryrefslogtreecommitdiff
path: root/tests/modeltests/test_client
diff options
context:
space:
mode:
authorChristopher Long <indirecthit@gmail.com>2007-06-17 22:18:54 +0000
committerChristopher Long <indirecthit@gmail.com>2007-06-17 22:18:54 +0000
commitae22b6d403dcf25098c77f0dfcf59ae58b186461 (patch)
treec37fc631e99a7e4d909d6b6d236f495003731ea7 /tests/modeltests/test_client
parent0cf7bc439129c66df8d64601e885f83b256b4f25 (diff)
per-object-permissions: Merged to trunk [5486] NOTE: Not fully tested, will be working on this over the next few weeks.
git-svn-id: http://code.djangoproject.com/svn/django/branches/per-object-permissions@5488 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/modeltests/test_client')
-rw-r--r--tests/modeltests/test_client/fixtures/testdata.json20
-rw-r--r--tests/modeltests/test_client/management.py10
-rw-r--r--tests/modeltests/test_client/models.py223
-rw-r--r--tests/modeltests/test_client/urls.py11
-rw-r--r--tests/modeltests/test_client/views.py135
5 files changed, 362 insertions, 37 deletions
diff --git a/tests/modeltests/test_client/fixtures/testdata.json b/tests/modeltests/test_client/fixtures/testdata.json
new file mode 100644
index 0000000000..5c9e415240
--- /dev/null
+++ b/tests/modeltests/test_client/fixtures/testdata.json
@@ -0,0 +1,20 @@
+[
+ {
+ "pk": "1",
+ "model": "auth.user",
+ "fields": {
+ "username": "testclient",
+ "first_name": "Test",
+ "last_name": "Client",
+ "is_active": true,
+ "is_superuser": false,
+ "is_staff": false,
+ "last_login": "2006-12-17 07:03:31",
+ "groups": [],
+ "user_permissions": [],
+ "password": "sha1$6efc0$f93efe9fd7542f25a7be94871ea45aa95de57161",
+ "email": "testclient@example.com",
+ "date_joined": "2006-12-17 07:03:31"
+ }
+ }
+] \ No newline at end of file
diff --git a/tests/modeltests/test_client/management.py b/tests/modeltests/test_client/management.py
deleted file mode 100644
index 9b5a5c498e..0000000000
--- a/tests/modeltests/test_client/management.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from django.dispatch import dispatcher
-from django.db.models import signals
-import models as test_client_app
-from django.contrib.auth.models import User
-
-def setup_test(app, created_models, verbosity):
- # Create a user account for the login-based tests
- User.objects.create_user('testclient','testclient@example.com', 'password')
-
-dispatcher.connect(setup_test, sender=test_client_app, signal=signals.post_syncdb)
diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py
index c5b1a241ca..5ebf29678c 100644
--- a/tests/modeltests/test_client/models.py
+++ b/tests/modeltests/test_client/models.py
@@ -1,5 +1,5 @@
"""
-39. Testing using the Test Client
+38. Testing using the Test Client
The test client is a class that can act like a simple
browser for testing purposes.
@@ -19,23 +19,20 @@ testing against the contexts and templates produced by a view,
rather than the HTML rendered to the end-user.
"""
-from django.test.client import Client
-import unittest
+from django.test import Client, TestCase
+from django.core import mail
-class ClientTest(unittest.TestCase):
- def setUp(self):
- "Set up test environment"
- self.client = Client()
-
+class ClientTest(TestCase):
+ fixtures = ['testdata.json']
+
def test_get_view(self):
"GET a view"
response = self.client.get('/test_client/get_view/')
# Check some response details
- self.assertEqual(response.status_code, 200)
+ self.assertContains(response, 'This is a test')
self.assertEqual(response.context['var'], 42)
self.assertEqual(response.template.name, 'GET Template')
- self.failUnless('This is a test.' in response.content)
def test_get_post_view(self):
"GET a view that normally expects POSTs"
@@ -43,7 +40,9 @@ class ClientTest(unittest.TestCase):
# Check some response details
self.assertEqual(response.status_code, 200)
- self.assertEqual(response.template.name, 'Empty POST Template')
+ self.assertEqual(response.template.name, 'Empty GET Template')
+ self.assertTemplateUsed(response, 'Empty GET Template')
+ self.assertTemplateNotUsed(response, 'Empty POST Template')
def test_empty_post(self):
"POST an empty dictionary to a view"
@@ -52,8 +51,10 @@ class ClientTest(unittest.TestCase):
# Check some response details
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template.name, 'Empty POST Template')
+ self.assertTemplateNotUsed(response, 'Empty GET Template')
+ self.assertTemplateUsed(response, 'Empty POST Template')
- def test_post_view(self):
+ def test_post(self):
"POST some data to a view"
post_data = {
'value': 37
@@ -66,13 +67,135 @@ class ClientTest(unittest.TestCase):
self.assertEqual(response.template.name, 'POST Template')
self.failUnless('Data received' in response.content)
+ def test_raw_post(self):
+ "POST raw data (with a content type) to a view"
+ test_doc = """<?xml version="1.0" encoding="utf-8"?><library><book><title>Blink</title><author>Malcolm Gladwell</author></book></library>"""
+ response = self.client.post("/test_client/raw_post_view/", test_doc,
+ content_type="text/xml")
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.template.name, "Book template")
+ self.assertEqual(response.content, "Blink - Malcolm Gladwell")
+
def test_redirect(self):
"GET a URL that redirects elsewhere"
response = self.client.get('/test_client/redirect_view/')
# Check that the response was a 302 (redirect)
- self.assertEqual(response.status_code, 302)
-
+ self.assertRedirects(response, '/test_client/get_view/')
+
+ def test_permanent_redirect(self):
+ "GET a URL that redirects permanently elsewhere"
+ response = self.client.get('/test_client/permanent_redirect_view/')
+
+ # Check that the response was a 301 (permanent redirect)
+ self.assertRedirects(response, '/test_client/get_view/', status_code=301)
+
+ def test_redirect_to_strange_location(self):
+ "GET a URL that redirects to a non-200 page"
+ response = self.client.get('/test_client/double_redirect_view/')
+
+ # Check that the response was a 302, and that
+ # the attempt to get the redirection location returned 301 when retrieved
+ self.assertRedirects(response, '/test_client/permanent_redirect_view/', target_status_code=301)
+
+ def test_notfound_response(self):
+ "GET a URL that responds as '404:Not Found'"
+ response = self.client.get('/test_client/bad_view/')
+
+ # Check that the response was a 404, and that the content contains MAGIC
+ self.assertContains(response, 'MAGIC', status_code=404)
+
+ def test_valid_form(self):
+ "POST valid data to a form"
+ post_data = {
+ 'text': 'Hello World',
+ 'email': 'foo@example.com',
+ 'value': 37,
+ 'single': 'b',
+ 'multi': ('b','c','e')
+ }
+ response = self.client.post('/test_client/form_view/', post_data)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, "Valid POST Template")
+
+ def test_incomplete_data_form(self):
+ "POST incomplete data to a form"
+ post_data = {
+ 'text': 'Hello World',
+ 'value': 37
+ }
+ response = self.client.post('/test_client/form_view/', post_data)
+ self.assertContains(response, 'This field is required.', 3)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, "Invalid POST Template")
+
+ self.assertFormError(response, 'form', 'email', 'This field is required.')
+ self.assertFormError(response, 'form', 'single', 'This field is required.')
+ self.assertFormError(response, 'form', 'multi', 'This field is required.')
+
+ def test_form_error(self):
+ "POST erroneous data to a form"
+ post_data = {
+ 'text': 'Hello World',
+ 'email': 'not an email address',
+ 'value': 37,
+ 'single': 'b',
+ 'multi': ('b','c','e')
+ }
+ response = self.client.post('/test_client/form_view/', post_data)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, "Invalid POST Template")
+
+ self.assertFormError(response, 'form', 'email', 'Enter a valid e-mail address.')
+
+ def test_valid_form_with_template(self):
+ "POST valid data to a form using multiple templates"
+ post_data = {
+ 'text': 'Hello World',
+ 'email': 'foo@example.com',
+ 'value': 37,
+ 'single': 'b',
+ 'multi': ('b','c','e')
+ }
+ response = self.client.post('/test_client/form_view_with_template/', post_data)
+ self.assertContains(response, 'POST data OK')
+ self.assertTemplateUsed(response, "form_view.html")
+ self.assertTemplateUsed(response, 'base.html')
+ self.assertTemplateNotUsed(response, "Valid POST Template")
+
+ def test_incomplete_data_form_with_template(self):
+ "POST incomplete data to a form using multiple templates"
+ post_data = {
+ 'text': 'Hello World',
+ 'value': 37
+ }
+ response = self.client.post('/test_client/form_view_with_template/', post_data)
+ self.assertContains(response, 'POST data has errors')
+ self.assertTemplateUsed(response, 'form_view.html')
+ self.assertTemplateUsed(response, 'base.html')
+ self.assertTemplateNotUsed(response, "Invalid POST Template")
+
+ self.assertFormError(response, 'form', 'email', 'This field is required.')
+ self.assertFormError(response, 'form', 'single', 'This field is required.')
+ self.assertFormError(response, 'form', 'multi', 'This field is required.')
+
+ def test_form_error_with_template(self):
+ "POST erroneous data to a form using multiple templates"
+ post_data = {
+ 'text': 'Hello World',
+ 'email': 'not an email address',
+ 'value': 37,
+ 'single': 'b',
+ 'multi': ('b','c','e')
+ }
+ response = self.client.post('/test_client/form_view_with_template/', post_data)
+ self.assertContains(response, 'POST data has errors')
+ self.assertTemplateUsed(response, "form_view.html")
+ self.assertTemplateUsed(response, 'base.html')
+ self.assertTemplateNotUsed(response, "Invalid POST Template")
+
+ self.assertFormError(response, 'form', 'email', 'Enter a valid e-mail address.')
+
def test_unknown_page(self):
"GET an invalid URL"
response = self.client.get('/test_client/unknown_view/')
@@ -85,17 +208,77 @@ class ClientTest(unittest.TestCase):
# Get the page without logging in. Should result in 302.
response = self.client.get('/test_client/login_protected_view/')
- self.assertEqual(response.status_code, 302)
+ self.assertRedirects(response, '/accounts/login/')
+ # Log in
+ self.client.login(username='testclient', password='password')
+
# Request a page that requires a login
- response = self.client.login('/test_client/login_protected_view/', 'testclient', 'password')
- self.assertTrue(response)
+ response = self.client.get('/test_client/login_protected_view/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['user'].username, 'testclient')
- self.assertEqual(response.template.name, 'Login Template')
def test_view_with_bad_login(self):
"Request a page that is protected with @login, but use bad credentials"
- response = self.client.login('/test_client/login_protected_view/', 'otheruser', 'nopassword')
- self.assertFalse(response)
+ login = self.client.login(username='otheruser', password='nopassword')
+ self.failIf(login)
+
+ 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')
+
+ def test_view_with_exception(self):
+ "Request a page that is known to throw an error"
+ self.assertRaises(KeyError, self.client.get, "/test_client/broken_view/")
+
+ #Try the same assertion, a different way
+ try:
+ self.client.get('/test_client/broken_view/')
+ self.fail('Should raise an error')
+ except KeyError:
+ pass
+
+ def test_mail_sending(self):
+ "Test that mail is redirected to a dummy outbox during test setup"
+
+ response = self.client.get('/test_client/mail_sending_view/')
+ self.assertEqual(response.status_code, 200)
+
+ self.assertEqual(len(mail.outbox), 1)
+ self.assertEqual(mail.outbox[0].subject, 'Test message')
+ self.assertEqual(mail.outbox[0].body, 'This is a test email')
+ self.assertEqual(mail.outbox[0].from_email, 'from@example.com')
+ self.assertEqual(mail.outbox[0].to[0], 'first@example.com')
+ self.assertEqual(mail.outbox[0].to[1], 'second@example.com')
+
+ def test_mass_mail_sending(self):
+ "Test that mass mail is redirected to a dummy outbox during test setup"
+
+ response = self.client.get('/test_client/mass_mail_sending_view/')
+ self.assertEqual(response.status_code, 200)
+
+ self.assertEqual(len(mail.outbox), 2)
+ self.assertEqual(mail.outbox[0].subject, 'First Test message')
+ self.assertEqual(mail.outbox[0].body, 'This is the first test email')
+ self.assertEqual(mail.outbox[0].from_email, 'from@example.com')
+ self.assertEqual(mail.outbox[0].to[0], 'first@example.com')
+ self.assertEqual(mail.outbox[0].to[1], 'second@example.com')
+
+ self.assertEqual(mail.outbox[1].subject, 'Second Test message')
+ self.assertEqual(mail.outbox[1].body, 'This is the second test email')
+ self.assertEqual(mail.outbox[1].from_email, 'from@example.com')
+ self.assertEqual(mail.outbox[1].to[0], 'second@example.com')
+ self.assertEqual(mail.outbox[1].to[1], 'third@example.com')
+ \ No newline at end of file
diff --git a/tests/modeltests/test_client/urls.py b/tests/modeltests/test_client/urls.py
index 09bba5c007..538c0e4b43 100644
--- a/tests/modeltests/test_client/urls.py
+++ b/tests/modeltests/test_client/urls.py
@@ -1,9 +1,20 @@
from django.conf.urls.defaults import *
+from django.views.generic.simple import redirect_to
import views
urlpatterns = patterns('',
(r'^get_view/$', views.get_view),
(r'^post_view/$', views.post_view),
+ (r'^raw_post_view/$', views.raw_post_view),
(r'^redirect_view/$', views.redirect_view),
+ (r'^permanent_redirect_view/$', redirect_to, { 'url': '/test_client/get_view/' }),
+ (r'^double_redirect_view/$', views.double_redirect_view),
+ (r'^bad_view/$', views.bad_view),
+ (r'^form_view/$', views.form_view),
+ (r'^form_view_with_template/$', views.form_view_with_template),
(r'^login_protected_view/$', views.login_protected_view),
+ (r'^session_view/$', views.session_view),
+ (r'^broken_view/$', views.broken_view),
+ (r'^mail_sending_view/$', views.mail_sending_view),
+ (r'^mass_mail_sending_view/$', views.mass_mail_sending_view)
)
diff --git a/tests/modeltests/test_client/views.py b/tests/modeltests/test_client/views.py
index bf131032eb..9bdf213b35 100644
--- a/tests/modeltests/test_client/views.py
+++ b/tests/modeltests/test_client/views.py
@@ -1,6 +1,11 @@
+from xml.dom.minidom import parseString
+from django.core.mail import EmailMessage, SMTPConnection
from django.template import Context, Template
-from django.http import HttpResponse, HttpResponseRedirect
+from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound
from django.contrib.auth.decorators import login_required
+from django.newforms.forms import Form
+from django.newforms import fields
+from django.shortcuts import render_to_response
def get_view(request):
"A simple view that expects a GET request, and returns a rendered template"
@@ -13,23 +18,139 @@ def post_view(request):
"""A view that expects a POST, and returns a different template depending
on whether any POST data is available
"""
- if request.POST:
- t = Template('Data received: {{ data }} is the value.', name='POST Template')
- c = Context({'data': request.POST['value']})
+ if request.method == 'POST':
+ if request.POST:
+ t = Template('Data received: {{ data }} is the value.', name='POST Template')
+ c = Context({'data': request.POST['value']})
+ else:
+ t = Template('Viewing POST page.', name='Empty POST Template')
+ c = Context()
else:
- t = Template('Viewing POST page.', name='Empty POST Template')
+ t = Template('Viewing GET page.', name='Empty GET Template')
c = Context()
-
+
return HttpResponse(t.render(c))
+def raw_post_view(request):
+ """A view which expects raw XML to be posted and returns content extracted
+ from the XML"""
+ if request.method == 'POST':
+ root = parseString(request.raw_post_data)
+ first_book = root.firstChild.firstChild
+ title, author = [n.firstChild.nodeValue for n in first_book.childNodes]
+ t = Template("{{ title }} - {{ author }}", name="Book template")
+ c = Context({"title": title, "author": author})
+ else:
+ t = Template("GET request.", name="Book GET template")
+ c = Context()
+
+ return HttpResponse(t.render(c))
+
def redirect_view(request):
"A view that redirects all requests to the GET view"
return HttpResponseRedirect('/test_client/get_view/')
+
+def double_redirect_view(request):
+ "A view that redirects all requests to a redirection view"
+ return HttpResponseRedirect('/test_client/permanent_redirect_view/')
+
+def bad_view(request):
+ "A view that returns a 404 with some error content"
+ return HttpResponseNotFound('Not found!. This page contains some MAGIC content')
+
+TestChoices = (
+ ('a', 'First Choice'),
+ ('b', 'Second Choice'),
+ ('c', 'Third Choice'),
+ ('d', 'Fourth Choice'),
+ ('e', 'Fifth Choice')
+)
+
+class TestForm(Form):
+ text = fields.CharField()
+ email = fields.EmailField()
+ value = fields.IntegerField()
+ single = fields.ChoiceField(choices=TestChoices)
+ multi = fields.MultipleChoiceField(choices=TestChoices)
+
+def form_view(request):
+ "A view that tests a simple form"
+ if request.method == 'POST':
+ form = TestForm(request.POST)
+ if form.is_valid():
+ t = Template('Valid POST data.', name='Valid POST Template')
+ c = Context()
+ else:
+ t = Template('Invalid POST data. {{ form.errors }}', name='Invalid POST Template')
+ c = Context({'form': form})
+ else:
+ form = TestForm()
+ t = Template('Viewing base form. {{ form }}.', name='Form GET Template')
+ c = Context({'form': form})
-@login_required
+ return HttpResponse(t.render(c))
+
+def form_view_with_template(request):
+ "A view that tests a simple form"
+ if request.method == 'POST':
+ form = TestForm(request.POST)
+ if form.is_valid():
+ message = 'POST data OK'
+ else:
+ message = 'POST data has errors'
+ else:
+ form = TestForm()
+ message = 'GET form page'
+ return render_to_response('form_view.html',
+ {
+ 'form': form,
+ 'message': message
+ }
+ )
+
+
def login_protected_view(request):
"A simple view that is login protected."
t = Template('This is a login protected test. Username is {{ user.username }}.', name='Login Template')
c = Context({'user': request.user})
return HttpResponse(t.render(c))
+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))
+
+def broken_view(request):
+ """A view which just raises an exception, simulating a broken view."""
+ raise KeyError("Oops! Looks like you wrote some bad code.")
+
+def mail_sending_view(request):
+ EmailMessage(
+ "Test message",
+ "This is a test email",
+ "from@example.com",
+ ['first@example.com', 'second@example.com']).send()
+ return HttpResponse("Mail sent")
+
+def mass_mail_sending_view(request):
+ m1 = EmailMessage(
+ 'First Test message',
+ 'This is the first test email',
+ 'from@example.com',
+ ['first@example.com', 'second@example.com'])
+ m2 = EmailMessage(
+ 'Second Test message',
+ 'This is the second test email',
+ 'from@example.com',
+ ['second@example.com', 'third@example.com'])
+
+ c = SMTPConnection()
+ c.send_messages([m1,m2])
+
+ return HttpResponse("Mail sent")