From c4c66ba7809cf805c211be9e4e9859ef4310c7c6 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 30 Jun 2014 10:41:10 +0100 Subject: [PATCH 1/4] Added check to page create view to make sure the selected class is a descendant of Page --- wagtail/wagtailadmin/tests/test_pages_views.py | 1 - wagtail/wagtailadmin/views/pages.py | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/wagtail/wagtailadmin/tests/test_pages_views.py b/wagtail/wagtailadmin/tests/test_pages_views.py index 65a614538..aa73e907d 100644 --- a/wagtail/wagtailadmin/tests/test_pages_views.py +++ b/wagtail/wagtailadmin/tests/test_pages_views.py @@ -245,7 +245,6 @@ class TestPageCreation(TestCase, WagtailTestUtils): response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', 100000))) self.assertEqual(response.status_code, 404) - @unittest.expectedFailure # FIXME: Crashes! def test_create_nonpagetype(self): response = self.client.get(reverse('wagtailadmin_pages_create', args=('wagtailimages', 'image', self.root_page.id))) self.assertEqual(response.status_code, 404) diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index 0d738d0c2..f6490a224 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -115,12 +115,17 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_ except ContentType.DoesNotExist: raise Http404 + # Get class + page_class = content_type.model_class() + + # Make sure the class is a descendant of Page + if not issubclass(page_class, Page): + raise Http404 + # page must be in the list of allowed subpage types for this parent ID if content_type not in parent_page.clean_subpage_types(): raise PermissionDenied - page_class = content_type.model_class() - page = page_class(owner=request.user) edit_handler_class = get_page_edit_handler(page_class) form_class = edit_handler_class.get_form_class(page_class) From 865459e5eb5055a0959bab43227b5c00fbb8e9fe Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 30 Jun 2014 14:16:46 +0100 Subject: [PATCH 2/4] Added page_published signal --- .../wagtailadmin/tests/test_pages_views.py | 26 +++++++++++++++++++ wagtail/wagtailadmin/views/pages.py | 3 +++ wagtail/wagtailcore/signals.py | 4 +++ 3 files changed, 33 insertions(+) create mode 100644 wagtail/wagtailcore/signals.py diff --git a/wagtail/wagtailadmin/tests/test_pages_views.py b/wagtail/wagtailadmin/tests/test_pages_views.py index aa73e907d..963a048b2 100644 --- a/wagtail/wagtailadmin/tests/test_pages_views.py +++ b/wagtail/wagtailadmin/tests/test_pages_views.py @@ -7,6 +7,7 @@ from django.core.paginator import Paginator from wagtail.tests.models import SimplePage, EventPage, StandardIndex, StandardChild, BusinessIndex, BusinessChild, BusinessSubIndex from wagtail.tests.utils import unittest, WagtailTestUtils from wagtail.wagtailcore.models import Page, PageRevision +from wagtail.wagtailcore.signals import page_published from wagtail.wagtailusers.models import UserProfile @@ -170,6 +171,15 @@ class TestPageCreation(TestCase, WagtailTestUtils): self.assertFalse(page.live) def test_create_simplepage_post_publish(self): + # Connect a mock signal handler to page_published signal + signal_fired = [False] + signal_page = [None] + def page_published_handler(sender, page, **kwargs): + signal_fired[0] = True + signal_page[0] = page + page_published.connect(page_published_handler) + + # Post post_data = { 'title': "New page!", 'content': "Some content", @@ -187,6 +197,10 @@ class TestPageCreation(TestCase, WagtailTestUtils): self.assertIsInstance(page, SimplePage) self.assertTrue(page.live) + # Check that the page_published signal was fired + self.assertTrue(signal_fired[0]) + self.assertEqual(signal_page[0], page) + def test_create_simplepage_post_submit(self): # Create a moderator user for testing email moderator = User.objects.create_superuser('moderator', 'moderator@email.com', 'password') @@ -327,6 +341,14 @@ class TestPageEdit(TestCase, WagtailTestUtils): self.assertTrue(child_page_new.has_unpublished_changes) def test_page_edit_post_publish(self): + # Connect a mock signal handler to page_published signal + signal_fired = [False] + signal_page = [None] + def page_published_handler(sender, page, **kwargs): + signal_fired[0] = True + signal_page[0] = page + page_published.connect(page_published_handler) + # Tests publish from edit page post_data = { 'title': "I've been edited!", @@ -343,6 +365,10 @@ class TestPageEdit(TestCase, WagtailTestUtils): child_page_new = SimplePage.objects.get(id=self.child_page.id) self.assertEqual(child_page_new.title, post_data['title']) + # Check that the page_published signal was fired + self.assertTrue(signal_fired[0]) + self.assertEqual(signal_page[0], child_page_new) + # The page shouldn't have "has_unpublished_changes" flag set self.assertFalse(child_page_new.has_unpublished_changes) diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index f6490a224..d49864f44 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -13,6 +13,7 @@ from wagtail.wagtailadmin.forms import SearchForm from wagtail.wagtailadmin import tasks, hooks, signals from wagtail.wagtailcore.models import Page, PageRevision +from wagtail.wagtailcore.signals import page_published @permission_required('wagtailadmin.access_admin') @@ -158,6 +159,7 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_ page.save_revision(user=request.user, submitted_for_moderation=is_submitting) if is_publishing: + page_published.send(sender=page_class, page=page) messages.success(request, _("Page '{0}' published.").format(page.title)) elif is_submitting: messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title)) @@ -238,6 +240,7 @@ def edit(request, page_id): page.save_revision(user=request.user, submitted_for_moderation=is_submitting) if is_publishing: + page_published.send(sender=page.__class__, page=page) messages.success(request, _("Page '{0}' published.").format(page.title)) elif is_submitting: messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title)) diff --git a/wagtail/wagtailcore/signals.py b/wagtail/wagtailcore/signals.py new file mode 100644 index 000000000..38a0809c8 --- /dev/null +++ b/wagtail/wagtailcore/signals.py @@ -0,0 +1,4 @@ +from django.dispatch import Signal + + +page_published = Signal(providing_args=['page']) From de229914f00d9e21209e475a0b5542deeb82bf24 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 30 Jun 2014 14:22:55 +0100 Subject: [PATCH 3/4] Fire page_published signal on moderation approval --- wagtail/wagtailadmin/tests/test_pages_views.py | 15 +++++++++++++++ wagtail/wagtailadmin/views/pages.py | 1 + 2 files changed, 16 insertions(+) diff --git a/wagtail/wagtailadmin/tests/test_pages_views.py b/wagtail/wagtailadmin/tests/test_pages_views.py index 963a048b2..1bab3b137 100644 --- a/wagtail/wagtailadmin/tests/test_pages_views.py +++ b/wagtail/wagtailadmin/tests/test_pages_views.py @@ -200,6 +200,7 @@ class TestPageCreation(TestCase, WagtailTestUtils): # Check that the page_published signal was fired self.assertTrue(signal_fired[0]) self.assertEqual(signal_page[0], page) + self.assertEqual(signal_page[0], signal_page[0].specific) def test_create_simplepage_post_submit(self): # Create a moderator user for testing email @@ -368,6 +369,7 @@ class TestPageEdit(TestCase, WagtailTestUtils): # Check that the page_published signal was fired self.assertTrue(signal_fired[0]) self.assertEqual(signal_page[0], child_page_new) + self.assertEqual(signal_page[0], signal_page[0].specific) # The page shouldn't have "has_unpublished_changes" flag set self.assertFalse(child_page_new.has_unpublished_changes) @@ -667,6 +669,14 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils): """ This posts to the approve moderation view and checks that the page was approved """ + # Connect a mock signal handler to page_published signal + signal_fired = [False] + signal_page = [None] + def page_published_handler(sender, page, **kwargs): + signal_fired[0] = True + signal_page[0] = page + page_published.connect(page_published_handler) + # Post response = self.client.post(reverse('wagtailadmin_pages_approve_moderation', args=(self.revision.id, )), { 'foo': "Must post something or the view won't see this as a POST request", @@ -678,6 +688,11 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils): # Page must be live self.assertTrue(Page.objects.get(id=self.page.id).live) + # Check that the page_published signal was fired + self.assertTrue(signal_fired[0]) + self.assertEqual(signal_page[0], self.page) + self.assertEqual(signal_page[0], signal_page[0].specific) + def test_approve_moderation_view_bad_revision_id(self): """ This tests that the approve moderation view handles invalid revision ids correctly diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index d49864f44..f829df9c5 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -609,6 +609,7 @@ def approve_moderation(request, revision_id): if request.POST: revision.publish() + page_published.send(sender=revision.page.__class__, page=revision.page.specific) messages.success(request, _("Page '{0}' published.").format(revision.page.title)) tasks.send_notification.delay(revision.id, 'approved', request.user.id) From 02daf67daf33ee1ff706b396f92d06b676217f6f Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 30 Jun 2014 14:32:18 +0100 Subject: [PATCH 4/4] Renamed 'page' argument of page_published signal to 'instance' This is to give more consistancy with djangos built in signals --- wagtail/wagtailadmin/tests/test_pages_views.py | 12 ++++++------ wagtail/wagtailadmin/views/pages.py | 6 +++--- wagtail/wagtailcore/signals.py | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/wagtail/wagtailadmin/tests/test_pages_views.py b/wagtail/wagtailadmin/tests/test_pages_views.py index 1bab3b137..a26feee9c 100644 --- a/wagtail/wagtailadmin/tests/test_pages_views.py +++ b/wagtail/wagtailadmin/tests/test_pages_views.py @@ -174,9 +174,9 @@ class TestPageCreation(TestCase, WagtailTestUtils): # Connect a mock signal handler to page_published signal signal_fired = [False] signal_page = [None] - def page_published_handler(sender, page, **kwargs): + def page_published_handler(sender, instance, **kwargs): signal_fired[0] = True - signal_page[0] = page + signal_page[0] = instance page_published.connect(page_published_handler) # Post @@ -345,9 +345,9 @@ class TestPageEdit(TestCase, WagtailTestUtils): # Connect a mock signal handler to page_published signal signal_fired = [False] signal_page = [None] - def page_published_handler(sender, page, **kwargs): + def page_published_handler(sender, instance, **kwargs): signal_fired[0] = True - signal_page[0] = page + signal_page[0] = instance page_published.connect(page_published_handler) # Tests publish from edit page @@ -672,9 +672,9 @@ class TestApproveRejectModeration(TestCase, WagtailTestUtils): # Connect a mock signal handler to page_published signal signal_fired = [False] signal_page = [None] - def page_published_handler(sender, page, **kwargs): + def page_published_handler(sender, instance, **kwargs): signal_fired[0] = True - signal_page[0] = page + signal_page[0] = instance page_published.connect(page_published_handler) # Post diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index f829df9c5..3f41bbc2b 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -159,7 +159,7 @@ def create(request, content_type_app_name, content_type_model_name, parent_page_ page.save_revision(user=request.user, submitted_for_moderation=is_submitting) if is_publishing: - page_published.send(sender=page_class, page=page) + page_published.send(sender=page_class, instance=page) messages.success(request, _("Page '{0}' published.").format(page.title)) elif is_submitting: messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title)) @@ -240,7 +240,7 @@ def edit(request, page_id): page.save_revision(user=request.user, submitted_for_moderation=is_submitting) if is_publishing: - page_published.send(sender=page.__class__, page=page) + page_published.send(sender=page.__class__, instance=page) messages.success(request, _("Page '{0}' published.").format(page.title)) elif is_submitting: messages.success(request, _("Page '{0}' submitted for moderation.").format(page.title)) @@ -609,7 +609,7 @@ def approve_moderation(request, revision_id): if request.POST: revision.publish() - page_published.send(sender=revision.page.__class__, page=revision.page.specific) + page_published.send(sender=revision.page.__class__, instance=revision.page.specific) messages.success(request, _("Page '{0}' published.").format(revision.page.title)) tasks.send_notification.delay(revision.id, 'approved', request.user.id) diff --git a/wagtail/wagtailcore/signals.py b/wagtail/wagtailcore/signals.py index 38a0809c8..2508759c6 100644 --- a/wagtail/wagtailcore/signals.py +++ b/wagtail/wagtailcore/signals.py @@ -1,4 +1,4 @@ from django.dispatch import Signal -page_published = Signal(providing_args=['page']) +page_published = Signal(providing_args=['instance'])