From 65ba8873d277b9cb88ef4f3afa06abb283305820 Mon Sep 17 00:00:00 2001 From: jordij Date: Thu, 7 Apr 2016 16:13:23 +1200 Subject: [PATCH] Recursive unpublish for descendant pages --- .../wagtailadmin/pages/confirm_unpublish.html | 24 ++++- .../wagtailadmin/tests/test_pages_views.py | 93 +++++++++++++++++++ wagtail/wagtailadmin/views/pages.py | 11 +++ 3 files changed, 126 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/confirm_unpublish.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/confirm_unpublish.html index 84a9afd7e0..c19d44c03e 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/confirm_unpublish.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/confirm_unpublish.html @@ -10,8 +10,28 @@
{% csrf_token %} - - {% trans "No, don't unpublish" %} +
{% endblock %} diff --git a/wagtail/wagtailadmin/tests/test_pages_views.py b/wagtail/wagtailadmin/tests/test_pages_views.py index adab11f350..b0b965cf3e 100644 --- a/wagtail/wagtailadmin/tests/test_pages_views.py +++ b/wagtail/wagtailadmin/tests/test_pages_views.py @@ -2139,6 +2139,99 @@ class TestPageUnpublish(TestCase, WagtailTestUtils): self.assertEqual(mock_call['instance'], self.page) self.assertIsInstance(mock_call['instance'], self.page.specific_class) + def test_unpublish_descendants_view(self): + """ + This tests that the unpublish view responds with an unpublish confirm page that does not contain the form field 'include_descendants' + """ + # Get unpublish page + response = self.client.get(reverse('wagtailadmin_pages:unpublish', args=(self.page.id, ))) + + # Check that the user recieved an unpublish confirm page + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailadmin/pages/confirm_unpublish.html') + # Check the form does not contain the checkbox field include_descendants + self.assertNotContains(response, '') + + +class TestPageUnpublishIncludingDescendants(TestCase, WagtailTestUtils): + def setUp(self): + self.user = self.login() + # Find root page + self.root_page = Page.objects.get(id=2) + + # Create a page to unpublish + self.test_page = self.root_page.add_child(instance=SimplePage( + title="Hello world!", + slug='hello-world', + content="hello", + live=True, + has_unpublished_changes=False, + )) + + # Create a couple of child pages + self.test_child_page = self.test_page.add_child(instance=SimplePage( + title="Child page", + slug='child-page', + content="hello", + live=True, + has_unpublished_changes=True, + )) + + self.test_another_child_page = self.test_page.add_child(instance=SimplePage( + title="Another Child page", + slug='another-child-page', + content="hello", + live=True, + has_unpublished_changes=True, + )) + + def test_unpublish_descendants_view(self): + """ + This tests that the unpublish view responds with an unpublish confirm page that contains the form field 'include_descendants' + """ + # Get unpublish page + response = self.client.get(reverse('wagtailadmin_pages:unpublish', args=(self.test_page.id, ))) + + # Check that the user recieved an unpublish confirm page + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailadmin/pages/confirm_unpublish.html') + # Check the form contains the checkbox field include_descendants + self.assertContains(response, '') + + def test_unpublish_include_children_view_post(self): + """ + This posts to the unpublish view and checks that the page and its descendants were unpublished + """ + # Post to the unpublish page + response = self.client.post(reverse('wagtailadmin_pages:unpublish', args=(self.test_page.id, )), {'include_descendants': 'on'}) + + # Should be redirected to explorer page + self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) + + # Check that the page was unpublished + self.assertFalse(SimplePage.objects.get(id=self.test_page.id).live) + + # Check that the descendant pages were unpiblished as well + self.assertFalse(SimplePage.objects.get(id=self.test_child_page.id).live) + self.assertFalse(SimplePage.objects.get(id=self.test_another_child_page.id).live) + + def test_unpublish_not_include_children_view_post(self): + """ + This posts to the unpublish view and checks that the page was unpublished but its descendants were not + """ + # Post to the unpublish page + response = self.client.post(reverse('wagtailadmin_pages:unpublish', args=(self.test_page.id, )), {}) + + # Should be redirected to explorer page + self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) + + # Check that the page was unpublished + self.assertFalse(SimplePage.objects.get(id=self.test_page.id).live) + + # Check that the descendant pages were not unpublished + self.assertTrue(SimplePage.objects.get(id=self.test_child_page.id).live) + self.assertTrue(SimplePage.objects.get(id=self.test_another_child_page.id).live) + class TestApproveRejectModeration(TestCase, WagtailTestUtils): def setUp(self): diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index abf0faeea8..d0e3134df3 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -647,8 +647,18 @@ def unpublish(request, page_id): next_url = get_valid_next_url_from_request(request) if request.method == 'POST': + include_descendants = request.POST.get("include_descendants", False) + page.unpublish() + if include_descendants == 'on': + live_descendant_pages = page.get_descendants().live().specific() + for live_descendant_page in live_descendant_pages: + if not live_descendant_page.permissions_for_user(request.user).can_unpublish(): + raise PermissionDenied + for live_descendant_page in live_descendant_pages: + live_descendant_page.unpublish() + messages.success(request, _("Page '{0}' unpublished.").format(page.title), buttons=[ messages.button(reverse('wagtailadmin_pages:edit', args=(page.id,)), _('Edit')) ]) @@ -660,6 +670,7 @@ def unpublish(request, page_id): return render(request, 'wagtailadmin/pages/confirm_unpublish.html', { 'page': page, 'next': next_url, + 'live_descendant_count': page.get_descendants().live().count(), })