django-admin2/example/blog/tests/test_views.py
2014-11-26 09:42:17 -06:00

561 lines
21 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from datetime import datetime
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.core.urlresolvers import reverse
from django.test import TestCase, Client
from django.utils.encoding import force_text
from ..models import Post, Comment
class BaseIntegrationTest(TestCase):
"""
Base TestCase for integration tests.
"""
def setUp(self):
self.client = Client()
self.user = get_user_model()(username='user', is_staff=True,
is_superuser=True)
self.user.set_password("password")
self.user.save()
self.client.login(username='user', password='password')
class AdminIndexTest(BaseIntegrationTest):
def test_view_ok(self):
response = self.client.get(reverse("admin2:dashboard"))
self.assertContains(response, reverse("admin2:blog_post_index"))
class UserListTest(BaseIntegrationTest):
def test_search_users_m2m_group(self):
# This test should cause the distinct search path to exectue
group = Group.objects.create(name="Test Group")
self.user.groups.add(group)
params = {"q": "group"}
response = self.client.get(reverse("admin2:auth_user_index"), params)
self.assertContains(response, 'user')
class CommentListTest(BaseIntegrationTest):
def test_search_comments(self):
# Test search across Foriegn Keys
post_1 = Post.objects.create(title="post_1_title", body="body")
post_2 = Post.objects.create(title="post_2_title", body="another body")
Comment.objects.create(body="comment_post_1_a", post=post_1)
Comment.objects.create(body="comment_post_1_b", post=post_1)
Comment.objects.create(body="comment_post_2", post=post_2)
params = {"q": "post_1_title"}
response = self.client.get(
reverse("admin2:blog_comment_index"), params)
self.assertContains(response, "comment_post_1_a")
self.assertContains(response, "comment_post_1_b")
self.assertNotContains(response, "comment_post_2")
def test_list_selected_hides(self):
post_1 = Post.objects.create(title="post_1_title", body="body")
Comment.objects.create(body="comment_post1_body", post=post_1)
response = self.client.get(reverse("admin2:blog_comment_index"))
self.assertNotContains(response, "of 1 selected")
class PostListTest(BaseIntegrationTest):
def _create_posts(self):
Post.objects.bulk_create([
Post(
title="post_1_title",
body="body",
published_date=datetime(
month=7,
day=22,
year=2013
)
),
Post(
title="post_2_title",
body="body",
published_date=datetime(
month=5,
day=20,
year=2012,
)
),
Post(
title="post_3_title",
body="body",
published_date=datetime(
month=5,
day=30,
year=2012,
),
),
Post(
title="post_4_title",
body="body",
published_date=datetime(
month=6,
day=20,
year=2012,
)
),
Post(
title="post_5_title",
body="body",
published_date=datetime(
month=6,
day=20,
year=2012,
)
),
])
def test_view_ok(self):
post = Post.objects.create(title="A Post Title", body="body")
response = self.client.get(reverse("admin2:blog_post_index"))
self.assertContains(response, post.title)
def test_list_filter_presence(self):
Post.objects.create(title="post_1_title", body="body")
Post.objects.create(title="post_2_title", body="another body")
response = self.client.get(reverse("admin2:blog_post_index"))
self.assertContains(response, 'id="list_filter_container"')
def test_list_selected_shows(self):
Post.objects.create(title="post_1_title", body="body")
response = self.client.get(reverse("admin2:blog_post_index"))
self.assertContains(response, 'class="selected-count"')
def test_actions_displayed(self):
response = self.client.get(reverse("admin2:blog_post_index"))
self.assertInHTML(
'<a tabindex="-1" href="#" data-name="action" data-value="DeleteSelectedAction">Delete selected items</a>', force_text(response.content))
def test_actions_displayed_twice(self):
# If actions_on_top and actions_on_bottom are both set
response = self.client.get(reverse("admin2:blog_comment_index"))
self.assertContains(response, '<div class="navbar actions-top">')
self.assertContains(response, '<div class="navbar actions-bottom">')
def test_delete_selected_post(self):
post = Post.objects.create(title="A Post Title", body="body")
params = {'action': 'DeleteSelectedAction',
'selected_model_pk': str(post.pk)}
response = self.client.post(reverse("admin2:blog_post_index"), params)
# caution : uses pluralization
self.assertInHTML(
'<p>Are you sure you want to delete the selected post? The following item will be deleted:</p>', force_text(response.content))
def test_delete_selected_post_confirmation(self):
post = Post.objects.create(title="A Post Title", body="body")
params = {'action': 'DeleteSelectedAction',
'selected_model_pk': str(post.pk), 'confirmed': 'yes'}
response = self.client.post(reverse("admin2:blog_post_index"), params)
self.assertRedirects(response, reverse("admin2:blog_post_index"))
def test_delete_selected_post_none_selected(self):
Post.objects.create(title="A Post Title", body="body")
params = {'action': 'DeleteSelectedAction'}
response = self.client.post(
reverse("admin2:blog_post_index"), params, follow=True)
self.assertContains(
response, "Items must be selected in order to perform actions on them. No items have been changed.")
def test_search_posts(self):
Post.objects.create(title="A Post Title", body="body")
Post.objects.create(title="Another Post Title", body="body")
Post.objects.create(
title="Post With Keyword In Body", body="another post body")
params = {"q": "another"}
response = self.client.get(reverse("admin2:blog_post_index"), params)
self.assertContains(response, "Another Post Title")
self.assertContains(response, "Post With Keyword In Body")
self.assertNotContains(response, "A Post Title")
def test_renderer_title(self):
Post.objects.create(
title='a lowercase title', body='body', published=False)
response = self.client.get(reverse('admin2:blog_post_index'))
self.assertContains(response, 'A Lowercase Title')
def test_renderer_body(self):
Post.objects.create(
title='title', body='a lowercase body', published=False)
response = self.client.get(reverse('admin2:blog_post_index'))
self.assertContains(response, 'a lowercase body')
def test_renderer_unpublished(self):
Post.objects.create(title='title', body='body', published=False)
response = self.client.get(reverse('admin2:blog_post_index'))
self.assertContains(response, 'icon-minus-sign')
def test_renderer_published(self):
Post.objects.create(title='title', body='body', published=True)
response = self.client.get(reverse('admin2:blog_post_index'))
self.assertContains(response, 'icon-ok-sign')
def test_drilldowns(self):
self._create_posts()
response = self.client.get(reverse('admin2:blog_post_index'))
self.assertContains(response, '<a href="?year=2012">2012</a>')
self.assertContains(response, "<tr>", 5)
response = self.client.get(
"%s?%s" % (
reverse('admin2:blog_post_index'),
"year=2012",
)
)
self.assertContains(
response,
'<a href="?year=2012&month=05">May 2012</a>',
)
self.assertContains(
response,
'All dates',
)
self.assertContains(response, "<tr>", 4)
response = self.client.get(
"%s?%s" % (
reverse('admin2:blog_post_index'),
"year=2012&month=5",
)
)
self.assertContains(response, "<tr>", 2)
self.assertContains(
response,
'<a href="?year=2012&month=05&day=20">May 20</a>',
)
self.assertContains(response, '<a href="?year=2012">')
response = self.client.get(
"%s?%s" % (
reverse('admin2:blog_post_index'),
"year=2012&month=05&day=20",
)
)
self.assertContains(response, "<tr>", 1)
self.assertContains(
response,
'<a href="?year=2012&month=05&day=20">May 20</a>',
)
self.assertContains(
response,
'<li class="active">'
)
self.assertContains(
response,
'May 2012'
)
def test_ordering(self):
self._create_posts()
response = self.client.get(reverse("admin2:blog_post_index"))
model_admin = response.context["view"].model_admin
response_queryset = response.context["object_list"]
manual_queryset = Post.objects.order_by("-published_date", "title")
zipped_queryset = zip(
list(response_queryset),
list(manual_queryset),
)
self.assertTrue(all([
model1.pk == model2.pk
for model1, model2 in zipped_queryset
]))
self.assertEqual(
model_admin.get_ordering(response.request),
model_admin.ordering,
)
def test_all_unselected_action(self):
self._create_posts()
response = self.client.get(reverse("admin2:blog_post_index"))
self.assertTrue(all([
not post.published
for post in response.context["object_list"]
]))
response = self.client.post(
reverse("admin2:blog_post_index"),
{
'action': 'PublishAllItemsAction',
},
follow=True
)
self.assertTrue(all([
post.published
for post in response.context["object_list"]
]))
# Test function-based view
response = self.client.post(
reverse("admin2:blog_post_index"),
{
'action': 'PublishAllItemsAction',
},
follow=True,
)
self.assertTrue(all([
post.published
for post in response.context["object_list"]
]))
class PostListTestCustomAction(BaseIntegrationTest):
def test_publish_action_displayed_in_list(self):
response = self.client.get(reverse("admin2:blog_post_index"))
self.assertInHTML(
'<a tabindex="-1" href="#" data-name="action" data-value="CustomPublishAction">Publish selected items</a>', force_text(response.content))
def test_publish_selected_items(self):
post = Post.objects.create(title="A Post Title",
body="body",
published=False)
self.assertEqual(Post.objects.filter(published=True).count(), 0)
params = {'action': 'CustomPublishAction',
'selected_model_pk': str(post.pk),
'confirmed': 'yes'}
response = self.client.post(reverse("admin2:blog_post_index"), params)
self.assertRedirects(response, reverse("admin2:blog_post_index"))
self.assertEqual(Post.objects.filter(published=True).count(), 1)
def test_unpublish_action_displayed_in_list(self):
response = self.client.get(reverse("admin2:blog_post_index"))
self.assertInHTML(
'<a tabindex="-1" href="#" data-name="action" data-value="unpublish_items">Unpublish selected items</a>', force_text(response.content))
def test_unpublish_selected_items(self):
post = Post.objects.create(title="A Post Title",
body="body",
published=True)
self.assertEqual(Post.objects.filter(published=True).count(), 1)
params = {'action': 'unpublish_items',
'selected_model_pk': str(post.pk)}
response = self.client.post(reverse("admin2:blog_post_index"), params)
self.assertRedirects(response, reverse("admin2:blog_post_index"))
self.assertEqual(Post.objects.filter(published=True).count(), 0)
class PostDetailViewTest(BaseIntegrationTest):
def test_view_ok(self):
post = Post.objects.create(title="A Post Title", body="body")
response = self.client.get(reverse("admin2:blog_post_detail",
args=(post.pk, )))
self.assertContains(response, post.title)
class PostCreateViewTest(BaseIntegrationTest):
def test_view_ok(self):
response = self.client.get(reverse("admin2:blog_post_create"))
self.assertNotIn(
'''enctype="multipart/form-data"''', force_text(response.content))
self.assertEqual(response.status_code, 200)
def test_create_post(self):
# Generated by inspecting the request with the pdb debugger
post_data = {
"comments-TOTAL_FORMS": u'2',
"comments-INITIAL_FORMS": u'0',
"comments-MAX_NUM_FORMS": u'',
"comments-0-body": u'Comment Body',
'comments-0-post': '',
'comments-0-id': '',
"title": "A Post Title",
"body": "a_post_body",
}
response = self.client.post(reverse("admin2:blog_post_create"),
post_data,
follow=True)
self.assertTrue(Post.objects.filter(title="A Post Title").exists())
Comment.objects.get(body="Comment Body")
self.assertRedirects(response, reverse("admin2:blog_post_index"))
def test_save_and_add_another_redirects_to_create(self):
"""
Tests that choosing 'Save and add another' from the model create
page redirects the user to the model create page.
"""
post_data = {
"comments-TOTAL_FORMS": u'2',
"comments-INITIAL_FORMS": u'0',
"comments-MAX_NUM_FORMS": u'',
"comments-0-body": u'Comment Body',
'comments-0-post': '',
'comments-0-id': '',
"title": "A Post Title",
"body": "a_post_body",
"_addanother": ""
}
self.client.login(username='admin', password='password')
response = self.client.post(reverse("admin2:blog_post_create"),
post_data)
Post.objects.get(title='A Post Title')
self.assertRedirects(response, reverse("admin2:blog_post_create"))
def test_save_and_continue_editing_redirects_to_update(self):
"""
Tests that choosing "Save and continue editing" redirects
the user to the model update form.
"""
post_data = {
"comments-TOTAL_FORMS": u'2',
"comments-INITIAL_FORMS": u'0',
"comments-MAX_NUM_FORMS": u'',
"title": "Unique",
"body": "a_post_body",
"_continue": ""
}
response = self.client.post(reverse("admin2:blog_post_create"),
post_data)
post = Post.objects.get(title="Unique")
self.assertRedirects(response, reverse("admin2:blog_post_update",
args=(post.pk, )))
class PostDeleteViewTest(BaseIntegrationTest):
def test_view_ok(self):
post = Post.objects.create(title="A Post Title", body="body")
response = self.client.get(reverse("admin2:blog_post_delete",
args=(post.pk, )))
self.assertContains(response, post.title)
def test_delete_post(self):
post = Post.objects.create(title="A Post Title", body="body")
response = self.client.post(reverse("admin2:blog_post_delete",
args=(post.pk, )))
self.assertRedirects(response, reverse("admin2:blog_post_index"))
self.assertFalse(Post.objects.filter(pk=post.pk).exists())
class PostDeleteActionTest(BaseIntegrationTest):
"""
Tests the behaviour of the 'Delete selected items' action.
"""
def test_confirmation_page(self):
p1 = Post.objects.create(title="A Post Title", body="body")
p2 = Post.objects.create(title="A Post Title", body="body")
post_data = {
'action': 'DeleteSelectedAction',
'selected_model_pk': [p1.pk, p2.pk]
}
response = self.client.post(reverse("admin2:blog_post_index"),
post_data)
self.assertContains(response, p1.title)
self.assertContains(response, p2.title)
def test_results_page(self):
p1 = Post.objects.create(title="A Post Title", body="body")
p2 = Post.objects.create(title="A Post Title", body="body")
post_data = {
'action': 'DeleteSelectedAction',
'selected_model_pk': [p1.pk, p2.pk],
'confirmed': 'yes'
}
response = self.client.post(reverse("admin2:blog_post_index"),
post_data, follow=True)
self.assertContains(response, "Successfully deleted 2 post")
class TestAuthViews(TestCase):
def setUp(self):
self.client = Client()
self.user = get_user_model()(username='user', is_staff=True,
is_superuser=True)
self.user.set_password("password")
self.user.save()
def test_login_required_redirect_to_index(self):
index_path = reverse('admin2:dashboard') + '?next=/admin2/blog/post/'
target_path = reverse('admin2:blog_post_index')
self.assertRedirects(self.client.get(target_path), index_path)
def test_login_required_logined_successful(self):
index_path = reverse('admin2:dashboard')
self.client.login(username=self.user.username,
password='password')
self.assertContains(self.client.get(index_path),
reverse('admin2:blog_post_index'))
def test_change_password_for_myself(self):
self.client.login(username=self.user.username,
password='password')
request = self.client.post(reverse('admin2:password_change',
kwargs={'pk': self.user.pk}),
{'old_password': 'password',
'new_password1': 'user',
'new_password2': 'user'})
self.assertRedirects(request, reverse('admin2:password_change_done'))
self.client.logout()
self.assertFalse(self.client.login(username=self.user.username,
password='password'))
self.assertTrue(self.client.login(username=self.user.username,
password='user'))
def test_change_password(self):
self.client.login(username=self.user.username,
password='password')
new_user = get_user_model()(username='new_user')
new_user.set_password("new_user")
new_user.save()
request = self.client.post(reverse('admin2:password_change',
kwargs={'pk': new_user.pk}),
{'old_password': 'new_user',
'password1': 'new_user_password',
'password2': 'new_user_password'})
self.assertRedirects(request, reverse('admin2:password_change_done'))
self.client.logout()
self.assertFalse(self.client.login(username=new_user.username,
password='new_user'))
self.assertTrue(self.client.login(username=new_user.username,
password='new_user_password'))
def test_logout(self):
self.client.login(username=self.user.username,
password='password')
logout_path = reverse('admin2:logout')
request = self.client.get(logout_path)
self.assertContains(request, 'Log in again')
index_path = reverse('admin2:dashboard') + '?next=/admin2/blog/post/'
target_path = reverse('admin2:blog_post_index')
self.assertRedirects(self.client.get(target_path), index_path)