Fixes for compatibility with python3.

This commit is contained in:
montiniz 2014-11-26 09:42:17 -06:00
parent dda1211f43
commit a6e7755a55
9 changed files with 198 additions and 85 deletions

View file

@ -18,7 +18,7 @@ class Admin2APISerializer(serializers.HyperlinkedModelSerializer):
_default_view_name = 'admin2:%(app_label)s_%(model_name)s_api_detail'
pk = fields.Field(source='pk')
__str__ = fields.Field(source='__unicode__')
__unicode__ = fields.Field(source='__str__')
class Admin2APIMixin(Admin2Mixin):

View file

@ -7,13 +7,14 @@ from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
@python_2_unicode_compatible
class Post(models.Model):
title = models.CharField(max_length=255, verbose_name=_('title'))
body = models.TextField(verbose_name=_('body'))
published = models.BooleanField(default=False, verbose_name=_('published'))
published_date = models.DateField(blank=True, null=True)
def __unicode__(self):
def __str__(self):
return self.title
class Meta:
@ -21,11 +22,13 @@ class Post(models.Model):
verbose_name_plural = _('posts')
@python_2_unicode_compatible
class Comment(models.Model):
post = models.ForeignKey(Post, verbose_name=_('post'), related_name="comments")
post = models.ForeignKey(
Post, verbose_name=_('post'), related_name="comments")
body = models.TextField(verbose_name=_('body'))
def __unicode__(self):
def __str__(self):
return self.body
class Meta:
@ -33,7 +36,7 @@ class Comment(models.Model):
verbose_name_plural = _('comments')
#### Models needed for testing NestedObjects
# Models needed for testing NestedObjects
@python_2_unicode_compatible
class Count(models.Model):

View file

@ -1,8 +1,10 @@
from __future__ import unicode_literals
from django.contrib.auth.models import AnonymousUser, User
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test.client import RequestFactory
from django.utils.encoding import force_text
import json
@ -69,7 +71,7 @@ class ListCreateAPIViewTest(APITestCase):
response.render()
self.assertEqual(response.status_code, 200)
self.assertIn('"__str__": "Foo"', response.content)
self.assertIn('"__unicode__": "Foo"', force_text(response.content))
def test_pagination(self):
request = self.factory.get(reverse('admin2:blog_post_api_list'))
@ -81,7 +83,7 @@ class ListCreateAPIViewTest(APITestCase):
response.render()
self.assertEqual(response.status_code, 200)
data = json.loads(response.content)
data = json.loads(force_text(response.content))
self.assertEqual(data['count'], 0)
# next and previous fields exist, but are null because we have no
# content

View file

@ -1,3 +1,5 @@
from __future__ import unicode_literals
from django import forms
from django.test import TestCase
@ -8,6 +10,7 @@ from ..models import Post
class ModelFormFactoryTest(TestCase):
def test_modelform_factory(self):
form_class = modelform_factory(Post)
self.assertTrue(form_class)
@ -16,8 +19,9 @@ class ModelFormFactoryTest(TestCase):
class GetFloppyformWidgetTest(TestCase):
def assertExpectWidget(self, instance, new_class_,
equal_attributes=None, new_attributes=None):
equal_attributes=None, new_attributes=None):
new_instance = floppify_widget(instance)
self.assertEqual(new_instance.__class__, new_class_)
if equal_attributes:
@ -33,8 +37,8 @@ class GetFloppyformWidgetTest(TestCase):
old_attr = getattr(instance, attribute)
new_attr = getattr(new_instance, attribute)
self.assertEqual(old_attr, new_attr,
'Original widget\'s attribute was not copied: %r != %r' %
(old_attr, new_attr))
'Original widget\'s attribute was not copied: %r != %r' %
(old_attr, new_attr))
if new_attributes:
for attribute, value in new_attributes.items():
self.assertTrue(
@ -43,8 +47,8 @@ class GetFloppyformWidgetTest(TestCase):
'generated widget %r' % (attribute, new_instance))
new_attr = getattr(new_instance, attribute)
self.assertEqual(new_attr, value,
'Generated widget\'s attribute is not as expected: '
'%r != %r' % (new_attr, value))
'Generated widget\'s attribute is not as expected: '
'%r != %r' % (new_attr, value))
def test_created_widget_doesnt_leak_attributes_into_original_widget(self):
widget = forms.TextInput()
@ -146,7 +150,7 @@ class GetFloppyformWidgetTest(TestCase):
widget,
floppyforms.widgets.ClearableFileInput,
['initial_text', 'input_text', 'clear_checkbox_label',
'template_with_initial', 'template_with_clear'])
'template_with_initial', 'template_with_clear'])
def test_textarea_widget(self):
self.assertExpectWidget(
@ -222,7 +226,7 @@ class GetFloppyformWidgetTest(TestCase):
forms.widgets.NullBooleanSelect(),
floppyforms.widgets.NullBooleanSelect,
('choices', 'allow_multiple_selected',))
widget = forms.widgets.NullBooleanSelect()
widget.choices = list(widget.choices)
@ -349,6 +353,7 @@ class GetFloppyformWidgetTest(TestCase):
class ModelFormTest(TestCase):
def test_custom_base_form(self):
class MyForm(forms.ModelForm):
pass
@ -410,6 +415,7 @@ class ModelFormTest(TestCase):
class FieldWidgetTest(TestCase):
def test_dont_overwrite_none_default_widget(self):
# we don't create the floppyform EmailInput for the email field here
# since we have overwritten the default widget. However we replace the

View file

@ -1,18 +1,22 @@
# -*- 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,
@ -23,12 +27,14 @@ class BaseIntegrationTest(TestCase):
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")
@ -40,6 +46,7 @@ class UserListTest(BaseIntegrationTest):
class CommentListTest(BaseIntegrationTest):
def test_search_comments(self):
# Test search across Foriegn Keys
post_1 = Post.objects.create(title="post_1_title", body="body")
@ -49,7 +56,8 @@ class CommentListTest(BaseIntegrationTest):
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)
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")
@ -62,6 +70,7 @@ class CommentListTest(BaseIntegrationTest):
class PostListTest(BaseIntegrationTest):
def _create_posts(self):
Post.objects.bulk_create([
Post(
@ -129,7 +138,8 @@ class PostListTest(BaseIntegrationTest):
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>', response.content)
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
@ -139,27 +149,33 @@ class PostListTest(BaseIntegrationTest):
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)}
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>', response.content)
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'}
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.")
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")
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")
@ -167,12 +183,14 @@ class PostListTest(BaseIntegrationTest):
self.assertNotContains(response, "A Post Title")
def test_renderer_title(self):
Post.objects.create(title='a lowercase title', body='body', published=False)
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)
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')
@ -311,7 +329,8 @@ 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>', response.content)
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",
@ -329,7 +348,8 @@ class PostListTestCustomAction(BaseIntegrationTest):
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>', response.content)
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",
@ -346,6 +366,7 @@ class PostListTestCustomAction(BaseIntegrationTest):
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",
@ -354,9 +375,11 @@ class PostDetailViewTest(BaseIntegrationTest):
class PostCreateViewTest(BaseIntegrationTest):
def test_view_ok(self):
response = self.client.get(reverse("admin2:blog_post_create"))
self.assertNotIn('''enctype="multipart/form-data"''', response.content)
self.assertNotIn(
'''enctype="multipart/form-data"''', force_text(response.content))
self.assertEqual(response.status_code, 200)
def test_create_post(self):
@ -422,6 +445,7 @@ class PostCreateViewTest(BaseIntegrationTest):
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",
@ -437,9 +461,11 @@ class PostDeleteViewTest(BaseIntegrationTest):
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")

View file

@ -2,14 +2,17 @@
from __future__ import division, absolute_import, unicode_literals
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
@python_2_unicode_compatible
class CaptionedFile(models.Model):
caption = models.CharField(max_length=200, verbose_name=_('caption'))
publication = models.FileField(upload_to='media', verbose_name=_('Uploaded File'))
publication = models.FileField(
upload_to='media', verbose_name=_('Uploaded File'))
def __unicode__(self):
def __str__(self):
return self.caption
class Meta:
@ -17,11 +20,13 @@ class CaptionedFile(models.Model):
verbose_name_plural = _('Captioned Files')
@python_2_unicode_compatible
class UncaptionedFile(models.Model):
publication = models.FileField(upload_to='media', verbose_name=_('Uploaded File'))
publication = models.FileField(
upload_to='media', verbose_name=_('Uploaded File'))
def __unicode__(self):
return unicode(self.publication)
def __str__(self):
return self.publication
class Meta:
verbose_name = _('Uncaptioned File')

View file

@ -2,6 +2,7 @@ from django.contrib.auth import get_user_model
from django.core.urlresolvers import reverse
from django.test import TestCase, Client
from django.utils import timezone
from django.utils.encoding import force_text
from ..models import CaptionedFile
@ -12,9 +13,11 @@ fixture_file = path.join(fixture_dir, 'pubtest.txt')
class BaseIntegrationTest(TestCase):
"""
Base TestCase for integration tests.
"""
def setUp(self):
self.client = Client()
self.user = get_user_model()(username='user', is_staff=True,
@ -25,55 +28,77 @@ class BaseIntegrationTest(TestCase):
class AdminIndexTest(BaseIntegrationTest):
def test_view_ok(self):
response = self.client.get(reverse("admin2:dashboard"))
self.assertContains(response, reverse("admin2:files_captionedfile_index"))
self.assertContains(
response, reverse("admin2:files_captionedfile_index"))
class CaptionedFileListTest(BaseIntegrationTest):
def test_view_ok(self):
captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
captioned_file = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
response = self.client.get(reverse("admin2:files_captionedfile_index"))
self.assertContains(response, captioned_file.caption)
def test_actions_displayed(self):
response = self.client.get(reverse("admin2:files_captionedfile_index"))
self.assertInHTML('<a tabindex="-1" href="#" data-name="action" data-value="DeleteSelectedAction">Delete selected items</a>', response.content)
self.assertInHTML(
'<a tabindex="-1" href="#" data-name="action" data-value="DeleteSelectedAction">Delete selected items</a>', force_text(response.content))
def test_delete_selected_captioned_file(self):
captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
params = {'action': 'DeleteSelectedAction', 'selected_model_pk': str(captioned_file.pk)}
response = self.client.post(reverse("admin2:files_captionedfile_index"), params)
self.assertInHTML('<p>Are you sure you want to delete the selected Captioned File? The following item will be deleted:</p>', response.content)
captioned_file = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
params = {'action': 'DeleteSelectedAction',
'selected_model_pk': str(captioned_file.pk)}
response = self.client.post(
reverse("admin2:files_captionedfile_index"), params)
self.assertInHTML(
'<p>Are you sure you want to delete the selected Captioned File? The following item will be deleted:</p>', force_text(response.content))
def test_delete_selected_captioned_file_confirmation(self):
captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
params = {'action': 'DeleteSelectedAction', 'selected_model_pk': str(captioned_file.pk), 'confirmed': 'yes'}
response = self.client.post(reverse("admin2:files_captionedfile_index"), params)
self.assertRedirects(response, reverse("admin2:files_captionedfile_index"))
captioned_file = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
params = {'action': 'DeleteSelectedAction', 'selected_model_pk': str(
captioned_file.pk), 'confirmed': 'yes'}
response = self.client.post(
reverse("admin2:files_captionedfile_index"), params)
self.assertRedirects(
response, reverse("admin2:files_captionedfile_index"))
def test_delete_selected_captioned_file_none_selected(self):
CaptionedFile.objects.create(caption="some file", publication=fixture_file)
CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
params = {'action': 'DeleteSelectedAction'}
response = self.client.post(reverse("admin2:files_captionedfile_index"), params, follow=True)
self.assertContains(response, "Items must be selected in order to perform actions on them. No items have been changed.")
response = self.client.post(
reverse("admin2:files_captionedfile_index"), params, follow=True)
self.assertContains(
response, "Items must be selected in order to perform actions on them. No items have been changed.")
class CaptionedFileDetailViewTest(BaseIntegrationTest):
def test_view_ok(self):
captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
response = self.client.get(reverse("admin2:files_captionedfile_detail", args=(captioned_file.pk, )))
captioned_file = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
response = self.client.get(
reverse("admin2:files_captionedfile_detail", args=(captioned_file.pk, )))
self.assertContains(response, captioned_file.caption)
class CaptionedFileCreateViewTest(BaseIntegrationTest):
def test_view_ok(self):
response = self.client.get(reverse("admin2:files_captionedfile_create"))
self.assertIn('enctype="multipart/form-data"', response.content)
response = self.client.get(
reverse("admin2:files_captionedfile_create"))
self.assertIn(
'enctype="multipart/form-data"', force_text(response.content))
self.assertEqual(response.status_code, 200)
def test_create_captioned_file(self):
with open(fixture_file, 'r') as fp:
with open(fixture_file, 'rb') as fp:
params = {
"caption": "some file",
"publication": fp,
@ -81,15 +106,17 @@ class CaptionedFileCreateViewTest(BaseIntegrationTest):
response = self.client.post(reverse("admin2:files_captionedfile_create"),
params,
follow=True)
self.assertTrue(CaptionedFile.objects.filter(caption="some file").exists())
self.assertRedirects(response, reverse("admin2:files_captionedfile_index"))
self.assertTrue(
CaptionedFile.objects.filter(caption="some file").exists())
self.assertRedirects(
response, reverse("admin2:files_captionedfile_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.
"""
with open(fixture_file, 'r') as fp:
with open(fixture_file, 'rb') as fp:
params = {
"caption": "some file",
"publication": fp,
@ -97,15 +124,17 @@ class CaptionedFileCreateViewTest(BaseIntegrationTest):
}
response = self.client.post(reverse("admin2:files_captionedfile_create"),
params)
self.assertTrue(CaptionedFile.objects.filter(caption="some file").exists())
self.assertRedirects(response, reverse("admin2:files_captionedfile_create"))
self.assertTrue(
CaptionedFile.objects.filter(caption="some file").exists())
self.assertRedirects(
response, reverse("admin2:files_captionedfile_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.
"""
with open(fixture_file, 'r') as fp:
with open(fixture_file, 'rb') as fp:
params = {
"caption": "some file",
"publication": fp,
@ -119,27 +148,36 @@ class CaptionedFileCreateViewTest(BaseIntegrationTest):
class CaptionedFileDeleteViewTest(BaseIntegrationTest):
def test_view_ok(self):
captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
captioned_file = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
response = self.client.get(reverse("admin2:files_captionedfile_delete",
args=(captioned_file.pk, )))
self.assertContains(response, captioned_file.caption)
def test_delete_captioned_file(self):
captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
captioned_file = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
response = self.client.post(reverse("admin2:files_captionedfile_delete",
args=(captioned_file.pk, )))
self.assertRedirects(response, reverse("admin2:files_captionedfile_index"))
self.assertFalse(CaptionedFile.objects.filter(pk=captioned_file.pk).exists())
self.assertRedirects(
response, reverse("admin2:files_captionedfile_index"))
self.assertFalse(
CaptionedFile.objects.filter(pk=captioned_file.pk).exists())
class FileDeleteActionTest(BaseIntegrationTest):
"""
Tests the behaviour of the 'Delete selected items' action.
"""
def test_confirmation_page(self):
cf1 = captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
cf2 = captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
cf1 = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
cf2 = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
params = {
'action': 'DeleteSelectedAction',
'selected_model_pk': [cf1.pk, cf2.pk]
@ -150,8 +188,10 @@ class FileDeleteActionTest(BaseIntegrationTest):
self.assertContains(response, cf2.caption)
def test_results_page(self):
cf1 = captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
cf2 = captioned_file = CaptionedFile.objects.create(caption="some file", publication=fixture_file)
cf1 = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
cf2 = CaptionedFile.objects.create(
caption="some file", publication=fixture_file)
params = {
'action': 'DeleteSelectedAction',
'selected_model_pk': [cf1.pk, cf2.pk],

View file

@ -3,16 +3,18 @@ from __future__ import division, absolute_import, unicode_literals
import datetime
from django.utils.encoding import python_2_unicode_compatible
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
@python_2_unicode_compatible
class Poll(models.Model):
question = models.CharField(max_length=200, verbose_name=_('question'))
pub_date = models.DateTimeField(verbose_name=_('date published'))
def __unicode__(self):
def __str__(self):
return self.question
def was_published_recently(self):
@ -26,12 +28,14 @@ class Poll(models.Model):
verbose_name_plural = _('polls')
@python_2_unicode_compatible
class Choice(models.Model):
poll = models.ForeignKey(Poll, verbose_name=_('poll'))
choice_text = models.CharField(max_length=200, verbose_name=_('choice text'))
choice_text = models.CharField(
max_length=200, verbose_name=_('choice text'))
votes = models.IntegerField(default=0, verbose_name=_('votes'))
def __unicode__(self):
def __str__(self):
return self.choice_text
class Meta:

View file

@ -2,14 +2,17 @@ from django.contrib.auth import get_user_model
from django.core.urlresolvers import reverse
from django.test import TestCase, Client
from django.utils import timezone
from django.utils.encoding import force_text
from ..models import Poll
class BaseIntegrationTest(TestCase):
"""
Base TestCase for integration tests.
"""
def setUp(self):
self.client = Client()
self.user = get_user_model()(username='user', is_staff=True,
@ -20,48 +23,63 @@ class BaseIntegrationTest(TestCase):
class AdminIndexTest(BaseIntegrationTest):
def test_view_ok(self):
response = self.client.get(reverse("admin2:dashboard"))
self.assertContains(response, reverse("admin2:polls_poll_index"))
class PollListTest(BaseIntegrationTest):
def test_view_ok(self):
poll = Poll.objects.create(question="some question", pub_date=timezone.now())
poll = Poll.objects.create(
question="some question", pub_date=timezone.now())
response = self.client.get(reverse("admin2:polls_poll_index"))
self.assertContains(response, poll.question)
def test_actions_displayed(self):
response = self.client.get(reverse("admin2:polls_poll_index"))
self.assertInHTML('<a tabindex="-1" href="#" data-name="action" data-value="DeleteSelectedAction">Delete selected items</a>', response.content)
self.assertInHTML(
'<a tabindex="-1" href="#" data-name="action" data-value="DeleteSelectedAction">Delete selected items</a>', force_text(response.content))
def test_delete_selected_poll(self):
poll = Poll.objects.create(question="some question", pub_date=timezone.now())
params = {'action': 'DeleteSelectedAction', 'selected_model_pk': str(poll.pk)}
poll = Poll.objects.create(
question="some question", pub_date=timezone.now())
params = {'action': 'DeleteSelectedAction',
'selected_model_pk': str(poll.pk)}
response = self.client.post(reverse("admin2:polls_poll_index"), params)
self.assertInHTML('<p>Are you sure you want to delete the selected poll? The following item will be deleted:</p>', response.content)
self.assertInHTML(
'<p>Are you sure you want to delete the selected poll? The following item will be deleted:</p>', force_text(response.content))
def test_delete_selected_poll_confirmation(self):
poll = Poll.objects.create(question="some question", pub_date=timezone.now())
params = {'action': 'DeleteSelectedAction', 'selected_model_pk': str(poll.pk), 'confirmed': 'yes'}
poll = Poll.objects.create(
question="some question", pub_date=timezone.now())
params = {'action': 'DeleteSelectedAction',
'selected_model_pk': str(poll.pk), 'confirmed': 'yes'}
response = self.client.post(reverse("admin2:polls_poll_index"), params)
self.assertRedirects(response, reverse("admin2:polls_poll_index"))
def test_delete_selected_poll_none_selected(self):
Poll.objects.create(question="some question", pub_date=timezone.now())
params = {'action': 'DeleteSelectedAction'}
response = self.client.post(reverse("admin2:polls_poll_index"), params, follow=True)
self.assertContains(response, "Items must be selected in order to perform actions on them. No items have been changed.")
response = self.client.post(
reverse("admin2:polls_poll_index"), params, follow=True)
self.assertContains(
response, "Items must be selected in order to perform actions on them. No items have been changed.")
class PollDetailViewTest(BaseIntegrationTest):
def test_view_ok(self):
poll = Poll.objects.create(question="some question", pub_date=timezone.now())
response = self.client.get(reverse("admin2:polls_poll_detail", args=(poll.pk, )))
poll = Poll.objects.create(
question="some question", pub_date=timezone.now())
response = self.client.get(
reverse("admin2:polls_poll_detail", args=(poll.pk, )))
self.assertContains(response, poll.question)
class PollCreateViewTest(BaseIntegrationTest):
def test_view_ok(self):
response = self.client.get(reverse("admin2:polls_poll_create"))
self.assertEqual(response.status_code, 200)
@ -119,14 +137,17 @@ class PollCreateViewTest(BaseIntegrationTest):
class PollDeleteViewTest(BaseIntegrationTest):
def test_view_ok(self):
poll = Poll.objects.create(question="some question", pub_date=timezone.now())
poll = Poll.objects.create(
question="some question", pub_date=timezone.now())
response = self.client.get(reverse("admin2:polls_poll_delete",
args=(poll.pk, )))
self.assertContains(response, poll.question)
def test_delete_poll(self):
poll = Poll.objects.create(question="some question", pub_date=timezone.now())
poll = Poll.objects.create(
question="some question", pub_date=timezone.now())
response = self.client.post(reverse("admin2:polls_poll_delete",
args=(poll.pk, )))
self.assertRedirects(response, reverse("admin2:polls_poll_index"))
@ -134,12 +155,16 @@ class PollDeleteViewTest(BaseIntegrationTest):
class PollDeleteActionTest(BaseIntegrationTest):
"""
Tests the behaviour of the 'Delete selected items' action.
"""
def test_confirmation_page(self):
p1 = Poll.objects.create(question="some question", pub_date=timezone.now())
p2 = Poll.objects.create(question="some question", pub_date=timezone.now())
p1 = Poll.objects.create(
question="some question", pub_date=timezone.now())
p2 = Poll.objects.create(
question="some question", pub_date=timezone.now())
params = {
'action': 'DeleteSelectedAction',
'selected_model_pk': [p1.pk, p2.pk]
@ -150,8 +175,10 @@ class PollDeleteActionTest(BaseIntegrationTest):
self.assertContains(response, p2.question)
def test_results_page(self):
p1 = Poll.objects.create(question="some question", pub_date=timezone.now())
p2 = Poll.objects.create(question="some question", pub_date=timezone.now())
p1 = Poll.objects.create(
question="some question", pub_date=timezone.now())
p2 = Poll.objects.create(
question="some question", pub_date=timezone.now())
params = {
'action': 'DeleteSelectedAction',
'selected_model_pk': [p1.pk, p2.pk],