summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBrian Rosner <brosner@gmail.com>2008-07-18 21:42:08 +0000
committerBrian Rosner <brosner@gmail.com>2008-07-18 21:42:08 +0000
commit66893002f306cd35d0ddbd840a16d927acbac3ec (patch)
treed4abcdd8b06fc00dfe8b4990633be850ae42f333 /tests
parentefc84a8a6348c9932a8a1bd14e7a30ba272df648 (diff)
newforms-admin: Merged from trunk up to [7952].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7954 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
-rw-r--r--tests/regressiontests/views/fixtures/testdata.json29
-rw-r--r--tests/regressiontests/views/models.py24
-rw-r--r--tests/regressiontests/views/tests/__init__.py3
-rw-r--r--tests/regressiontests/views/tests/generic/create_update.py211
-rw-r--r--tests/regressiontests/views/urls.py72
-rw-r--r--tests/regressiontests/views/views.py24
-rw-r--r--tests/templates/views/article_confirm_delete.html1
-rw-r--r--tests/templates/views/article_detail.html2
-rw-r--r--tests/templates/views/article_form.html3
-rw-r--r--tests/templates/views/urlarticle_detail.html1
-rw-r--r--tests/templates/views/urlarticle_form.html3
11 files changed, 345 insertions, 28 deletions
diff --git a/tests/regressiontests/views/fixtures/testdata.json b/tests/regressiontests/views/fixtures/testdata.json
index 449e91913a..e3fed9eac7 100644
--- a/tests/regressiontests/views/fixtures/testdata.json
+++ b/tests/regressiontests/views/fixtures/testdata.json
@@ -1,5 +1,23 @@
[
{
+ "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"
+ }
+ },
+ {
"pk": 1,
"model": "views.article",
"fields": {
@@ -29,7 +47,16 @@
"date_created": "3000-01-01 21:22:23"
}
},
-
+ {
+ "pk": 1,
+ "model": "views.urlarticle",
+ "fields": {
+ "author": 1,
+ "title": "Old Article",
+ "slug": "old_article",
+ "date_created": "2001-01-01 21:22:23"
+ }
+ },
{
"pk": 1,
"model": "views.author",
diff --git a/tests/regressiontests/views/models.py b/tests/regressiontests/views/models.py
index 4bed1f3bde..ce31778177 100644
--- a/tests/regressiontests/views/models.py
+++ b/tests/regressiontests/views/models.py
@@ -1,9 +1,8 @@
"""
-Regression tests for Django built-in views
+Regression tests for Django built-in views.
"""
from django.db import models
-from django.conf import settings
class Author(models.Model):
name = models.CharField(max_length=100)
@@ -14,13 +13,28 @@ class Author(models.Model):
def get_absolute_url(self):
return '/views/authors/%s/' % self.id
-
-class Article(models.Model):
+class BaseArticle(models.Model):
+ """
+ An abstract article Model so that we can create article models with and
+ without a get_absolute_url method (for create_update generic views tests).
+ """
title = models.CharField(max_length=100)
slug = models.SlugField()
author = models.ForeignKey(Author)
date_created = models.DateTimeField()
-
+
+ class Meta:
+ abstract = True
+
def __unicode__(self):
return self.title
+class Article(BaseArticle):
+ pass
+
+class UrlArticle(BaseArticle):
+ """
+ An Article class with a get_absolute_url defined.
+ """
+ def get_absolute_url(self):
+ return '/urlarticles/%s/' % self.slug
diff --git a/tests/regressiontests/views/tests/__init__.py b/tests/regressiontests/views/tests/__init__.py
index 2c8c5b4a92..9964cd5833 100644
--- a/tests/regressiontests/views/tests/__init__.py
+++ b/tests/regressiontests/views/tests/__init__.py
@@ -1,4 +1,5 @@
from defaults import *
from i18n import *
from static import *
-from generic.date_based import * \ No newline at end of file
+from generic.date_based import *
+from generic.create_update import *
diff --git a/tests/regressiontests/views/tests/generic/create_update.py b/tests/regressiontests/views/tests/generic/create_update.py
new file mode 100644
index 0000000000..3975c65706
--- /dev/null
+++ b/tests/regressiontests/views/tests/generic/create_update.py
@@ -0,0 +1,211 @@
+import datetime
+
+from django.test import TestCase
+from django.core.exceptions import ImproperlyConfigured
+from regressiontests.views.models import Article, UrlArticle
+
+class CreateObjectTest(TestCase):
+
+ fixtures = ['testdata.json']
+
+ def test_login_required_view(self):
+ """
+ Verifies that an unauthenticated user attempting to access a
+ login_required view gets redirected to the login page and that
+ an authenticated user is let through.
+ """
+ view_url = '/views/create_update/member/create/article/'
+ response = self.client.get(view_url)
+ self.assertRedirects(response, '/accounts/login/?next=%s' % view_url)
+ # Now login and try again.
+ login = self.client.login(username='testclient', password='password')
+ self.failUnless(login, 'Could not log in')
+ response = self.client.get(view_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'views/article_form.html')
+
+ def test_create_article_display_page(self):
+ """
+ Ensures the generic view returned the page and contains a form.
+ """
+ view_url = '/views/create_update/create/article/'
+ response = self.client.get(view_url)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'views/article_form.html')
+ if not response.context.get('form'):
+ self.fail('No form found in the response.')
+
+ def test_create_article_with_errors(self):
+ """
+ POSTs a form that contains validation errors.
+ """
+ view_url = '/views/create_update/create/article/'
+ num_articles = Article.objects.count()
+ response = self.client.post(view_url, {
+ 'title': 'My First Article',
+ })
+ self.assertFormError(response, 'form', 'slug', [u'This field is required.'])
+ self.assertTemplateUsed(response, 'views/article_form.html')
+ self.assertEqual(num_articles, Article.objects.count(),
+ "Number of Articles should not have changed.")
+
+ def test_create_custom_save_article(self):
+ """
+ Creates a new article using a custom form class with a save method
+ that alters the slug entered.
+ """
+ view_url = '/views/create_update/create_custom/article/'
+ response = self.client.post(view_url, {
+ 'title': 'Test Article',
+ 'slug': 'this-should-get-replaced',
+ 'author': 1,
+ 'date_created': datetime.datetime(2007, 6, 25),
+ })
+ self.assertRedirects(response,
+ '/views/create_update/view/article/some-other-slug/',
+ target_status_code=404)
+
+class UpdateDeleteObjectTest(TestCase):
+
+ fixtures = ['testdata.json']
+
+ def test_update_object_form_display(self):
+ """
+ Verifies that the form was created properly and with initial values.
+ """
+ response = self.client.get('/views/create_update/update/article/old_article/')
+ self.assertTemplateUsed(response, 'views/article_form.html')
+ self.assertEquals(unicode(response.context['form']['title']),
+ u'<input id="id_title" type="text" name="title" value="Old Article" maxlength="100" />')
+
+ def test_update_object(self):
+ """
+ Verifies the updating of an Article.
+ """
+ response = self.client.post('/views/create_update/update/article/old_article/', {
+ 'title': 'Another Article',
+ 'slug': 'another-article-slug',
+ 'author': 1,
+ 'date_created': datetime.datetime(2007, 6, 25),
+ })
+ article = Article.objects.get(pk=1)
+ self.assertEquals(article.title, "Another Article")
+
+ def test_delete_object_confirm(self):
+ """
+ Verifies the confirm deletion page is displayed using a GET.
+ """
+ response = self.client.get('/views/create_update/delete/article/old_article/')
+ self.assertTemplateUsed(response, 'views/article_confirm_delete.html')
+
+ def test_delete_object(self):
+ """
+ Verifies the object actually gets deleted on a POST.
+ """
+ view_url = '/views/create_update/delete/article/old_article/'
+ response = self.client.post(view_url)
+ try:
+ Article.objects.get(slug='old_article')
+ except Article.DoesNotExist:
+ pass
+ else:
+ self.fail('Object was not deleted.')
+
+class PostSaveRedirectTests(TestCase):
+ """
+ Verifies that the views redirect to the correct locations depending on
+ if a post_save_redirect was passed and a get_absolute_url method exists
+ on the Model.
+ """
+
+ fixtures = ['testdata.json']
+ article_model = Article
+
+ create_url = '/views/create_update/create/article/'
+ update_url = '/views/create_update/update/article/old_article/'
+ delete_url = '/views/create_update/delete/article/old_article/'
+
+ create_redirect = '/views/create_update/view/article/my-first-article/'
+ update_redirect = '/views/create_update/view/article/another-article-slug/'
+ delete_redirect = '/views/create_update/'
+
+ def test_create_article(self):
+ num_articles = self.article_model.objects.count()
+ response = self.client.post(self.create_url, {
+ 'title': 'My First Article',
+ 'slug': 'my-first-article',
+ 'author': '1',
+ 'date_created': datetime.datetime(2007, 6, 25),
+ })
+ self.assertRedirects(response, self.create_redirect,
+ target_status_code=404)
+ self.assertEqual(num_articles + 1, self.article_model.objects.count(),
+ "A new Article should have been created.")
+
+ def test_update_article(self):
+ num_articles = self.article_model.objects.count()
+ response = self.client.post(self.update_url, {
+ 'title': 'Another Article',
+ 'slug': 'another-article-slug',
+ 'author': 1,
+ 'date_created': datetime.datetime(2007, 6, 25),
+ })
+ self.assertRedirects(response, self.update_redirect,
+ target_status_code=404)
+ self.assertEqual(num_articles, self.article_model.objects.count(),
+ "A new Article should not have been created.")
+
+ def test_delete_article(self):
+ num_articles = self.article_model.objects.count()
+ response = self.client.post(self.delete_url)
+ self.assertRedirects(response, self.delete_redirect,
+ target_status_code=404)
+ self.assertEqual(num_articles - 1, self.article_model.objects.count(),
+ "An Article should have been deleted.")
+
+class NoPostSaveNoAbsoluteUrl(PostSaveRedirectTests):
+ """
+ Tests that when no post_save_redirect is passed and no get_absolute_url
+ method exists on the Model that the view raises an ImproperlyConfigured
+ error.
+ """
+
+ create_url = '/views/create_update/no_redirect/create/article/'
+ update_url = '/views/create_update/no_redirect/update/article/old_article/'
+
+ def test_create_article(self):
+ self.assertRaises(ImproperlyConfigured,
+ super(NoPostSaveNoAbsoluteUrl, self).test_create_article)
+
+ def test_update_article(self):
+ self.assertRaises(ImproperlyConfigured,
+ super(NoPostSaveNoAbsoluteUrl, self).test_update_article)
+
+ def test_delete_article(self):
+ """
+ The delete_object view requires a post_delete_redirect, so skip testing
+ here.
+ """
+ pass
+
+class AbsoluteUrlNoPostSave(PostSaveRedirectTests):
+ """
+ Tests that the views redirect to the Model's get_absolute_url when no
+ post_save_redirect is passed.
+ """
+
+ # Article model with get_absolute_url method.
+ article_model = UrlArticle
+
+ create_url = '/views/create_update/no_url/create/article/'
+ update_url = '/views/create_update/no_url/update/article/old_article/'
+
+ create_redirect = '/urlarticles/my-first-article/'
+ update_redirect = '/urlarticles/another-article-slug/'
+
+ def test_delete_article(self):
+ """
+ The delete_object view requires a post_delete_redirect, so skip testing
+ here.
+ """
+ pass
diff --git a/tests/regressiontests/views/urls.py b/tests/regressiontests/views/urls.py
index 5ef0c5129d..3a4700b998 100644
--- a/tests/regressiontests/views/urls.py
+++ b/tests/regressiontests/views/urls.py
@@ -5,6 +5,7 @@ from django.conf.urls.defaults import *
from models import *
import views
+
base_dir = path.dirname(path.abspath(__file__))
media_dir = path.join(base_dir, 'media')
locale_dir = path.join(base_dir, 'locale')
@@ -14,35 +15,66 @@ js_info_dict = {
'packages': ('regressiontests.views',),
}
-date_based_info_dict = {
- 'queryset': Article.objects.all(),
- 'date_field': 'date_created',
- 'month_format': '%m',
-}
+date_based_info_dict = {
+ 'queryset': Article.objects.all(),
+ 'date_field': 'date_created',
+ 'month_format': '%m',
+}
urlpatterns = patterns('',
(r'^$', views.index_page),
-
+
# Default views
(r'^shortcut/(\d+)/(.*)/$', 'django.views.defaults.shortcut'),
(r'^non_existing_url/', 'django.views.defaults.page_not_found'),
(r'^server_error/', 'django.views.defaults.server_error'),
-
+
# i18n views
- (r'^i18n/', include('django.conf.urls.i18n')),
+ (r'^i18n/', include('django.conf.urls.i18n')),
(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
-
+
# Static views
(r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': media_dir}),
-
- # Date-based generic views
- (r'^date_based/object_detail/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/$',
- 'django.views.generic.date_based.object_detail',
- dict(slug_field='slug', **date_based_info_dict)),
- (r'^date_based/object_detail/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/allow_future/$',
- 'django.views.generic.date_based.object_detail',
- dict(allow_future=True, slug_field='slug', **date_based_info_dict)),
- (r'^date_based/archive_month/(?P<year>\d{4})/(?P<month>\d{1,2})/$',
- 'django.views.generic.date_based.archive_month',
- date_based_info_dict),
+)
+
+# Date-based generic views.
+urlpatterns += patterns('django.views.generic.date_based',
+ (r'^date_based/object_detail/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/$',
+ 'object_detail',
+ dict(slug_field='slug', **date_based_info_dict)),
+ (r'^date_based/object_detail/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/(?P<slug>[-\w]+)/allow_future/$',
+ 'object_detail',
+ dict(allow_future=True, slug_field='slug', **date_based_info_dict)),
+ (r'^date_based/archive_month/(?P<year>\d{4})/(?P<month>\d{1,2})/$',
+ 'archive_month',
+ date_based_info_dict),
+)
+
+# crud generic views.
+
+urlpatterns += patterns('django.views.generic.create_update',
+ (r'^create_update/member/create/article/$', 'create_object',
+ dict(login_required=True, model=Article)),
+ (r'^create_update/create/article/$', 'create_object',
+ dict(post_save_redirect='/views/create_update/view/article/%(slug)s/',
+ model=Article)),
+ (r'^create_update/update/article/(?P<slug>[-\w]+)/$', 'update_object',
+ dict(post_save_redirect='/views/create_update/view/article/%(slug)s/',
+ slug_field='slug', model=Article)),
+ (r'^create_update/create_custom/article/$', views.custom_create),
+ (r'^create_update/delete/article/(?P<slug>[-\w]+)/$', 'delete_object',
+ dict(post_delete_redirect='/views/create_update/', slug_field='slug',
+ model=Article)),
+
+ # No post_save_redirect and no get_absolute_url on model.
+ (r'^create_update/no_redirect/create/article/$', 'create_object',
+ dict(model=Article)),
+ (r'^create_update/no_redirect/update/article/(?P<slug>[-\w]+)/$',
+ 'update_object', dict(slug_field='slug', model=Article)),
+
+ # get_absolute_url on model, but no passed post_save_redirect.
+ (r'^create_update/no_url/create/article/$', 'create_object',
+ dict(model=UrlArticle)),
+ (r'^create_update/no_url/update/article/(?P<slug>[-\w]+)/$',
+ 'update_object', dict(slug_field='slug', model=UrlArticle)),
)
diff --git a/tests/regressiontests/views/views.py b/tests/regressiontests/views/views.py
index 956432e7d5..eda8aabc50 100644
--- a/tests/regressiontests/views/views.py
+++ b/tests/regressiontests/views/views.py
@@ -1,5 +1,29 @@
from django.http import HttpResponse
+import django.newforms as forms
+from django.views.generic.create_update import create_object
+
+from models import Article
+
def index_page(request):
"""Dummy index page"""
return HttpResponse('<html><body>Dummy page</body></html>')
+
+
+def custom_create(request):
+ """
+ Calls create_object generic view with a custom form class.
+ """
+ class SlugChangingArticleForm(forms.ModelForm):
+ """Custom form class to overwrite the slug."""
+
+ class Meta:
+ model = Article
+
+ def save(self, *args, **kwargs):
+ self.cleaned_data['slug'] = 'some-other-slug'
+ return super(SlugChangingArticleForm, self).save(*args, **kwargs)
+
+ return create_object(request,
+ post_save_redirect='/views/create_update/view/article/%(slug)s/',
+ form_class=SlugChangingArticleForm)
diff --git a/tests/templates/views/article_confirm_delete.html b/tests/templates/views/article_confirm_delete.html
new file mode 100644
index 0000000000..3f8ff55da6
--- /dev/null
+++ b/tests/templates/views/article_confirm_delete.html
@@ -0,0 +1 @@
+This template intentionally left blank \ No newline at end of file
diff --git a/tests/templates/views/article_detail.html b/tests/templates/views/article_detail.html
index 3f8ff55da6..952299db91 100644
--- a/tests/templates/views/article_detail.html
+++ b/tests/templates/views/article_detail.html
@@ -1 +1 @@
-This template intentionally left blank \ No newline at end of file
+Article detail template.
diff --git a/tests/templates/views/article_form.html b/tests/templates/views/article_form.html
new file mode 100644
index 0000000000..e2aa1f9535
--- /dev/null
+++ b/tests/templates/views/article_form.html
@@ -0,0 +1,3 @@
+Article form template.
+
+{{ form.errors }}
diff --git a/tests/templates/views/urlarticle_detail.html b/tests/templates/views/urlarticle_detail.html
new file mode 100644
index 0000000000..924f310300
--- /dev/null
+++ b/tests/templates/views/urlarticle_detail.html
@@ -0,0 +1 @@
+UrlArticle detail template.
diff --git a/tests/templates/views/urlarticle_form.html b/tests/templates/views/urlarticle_form.html
new file mode 100644
index 0000000000..578dd98ca6
--- /dev/null
+++ b/tests/templates/views/urlarticle_form.html
@@ -0,0 +1,3 @@
+UrlArticle form template.
+
+{{ form.errors }}