コード例 #1
0
class TestPageDelete(TestCase, WagtailTestUtils):
    def setUp(self):
        # Find root page
        self.root_page = Page.objects.get(id=2)

        # Add child page
        self.child_page = SimplePage(
            title="Hello world!", slug="hello-world", content="hello"
        )
        self.root_page.add_child(instance=self.child_page)

        # Add a page with child pages of its own
        self.child_index = StandardIndex(title="Hello index", slug="hello-index")
        self.root_page.add_child(instance=self.child_index)
        self.grandchild_page = StandardChild(title="Hello Kitty", slug="hello-kitty")
        self.child_index.add_child(instance=self.grandchild_page)

        # Login
        self.user = self.login()

    def test_page_delete(self):
        response = self.client.get(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
        )
        self.assertEqual(response.status_code, 200)
        # deletion should not actually happen on GET
        self.assertTrue(SimplePage.objects.filter(id=self.child_page.id).exists())

    @override_settings(WAGTAILADMIN_UNSAFE_PAGE_DELETION_LIMIT=10)
    def test_confirm_delete_scenario_1(self):
        # If the number of pages to be deleted are less than
        # WAGTAILADMIN_UNSAFE_PAGE_DELETION_LIMIT then don't need
        # for confirmation
        child_1 = SimplePage(title="child 1", slug="child-1", content="hello")
        self.child_page.add_child(instance=child_1)
        child_2 = SimplePage(title="child 2", slug="child-2", content="hello")
        self.child_page.add_child(instance=child_2)
        response = self.client.get(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
        )
        self.assertEqual(response.status_code, 200)
        self.assertNotContains(response, '<input type="text" name="confirm_site_name"')
        # deletion should not actually happen on GET
        self.assertTrue(SimplePage.objects.filter(id=self.child_page.id).exists())

        # And admin should be able to delete page without any confirmation
        response = self.client.post(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
        )
        # Check that page is deleted
        self.assertFalse(SimplePage.objects.filter(id=self.child_page.id).exists())

    @override_settings(WAGTAILADMIN_UNSAFE_PAGE_DELETION_LIMIT=3)
    @override_settings(WAGTAIL_SITE_NAME="mysite")
    def test_confirm_delete_scenario_2(self):
        # If the number of pages to be deleted are greater than or equal to
        # WAGTAILADMIN_UNSAFE_PAGE_DELETION_LIMIT then show input box
        # to input wagtail_site_name.
        child_1 = SimplePage(title="child 1", slug="child-1", content="hello")
        self.child_page.add_child(instance=child_1)
        child_2 = SimplePage(title="child 2", slug="child-2", content="hello")
        self.child_page.add_child(instance=child_2)
        response = self.client.get(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
        )
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "This action will delete total <b>3</b> pages.")
        self.assertContains(response, "Please type <b>mysite</b> to confirm.")
        self.assertContains(response, '<input type="text" name="confirm_site_name"')
        # deletion should not actually happen on GET
        self.assertTrue(SimplePage.objects.filter(id=self.child_page.id).exists())

    @override_settings(WAGTAILADMIN_UNSAFE_PAGE_DELETION_LIMIT=3)
    @override_settings(WAGTAIL_SITE_NAME="mysite")
    def test_confirm_delete_scenario_3(self):
        # If admin entered the incorrect site name and submit
        # the form, then site should not be deleted and same
        # form should be displayed again.
        child_1 = SimplePage(title="child 1", slug="child-1", content="hello")
        self.child_page.add_child(instance=child_1)
        child_2 = SimplePage(title="child 2", slug="child-2", content="hello")
        self.child_page.add_child(instance=child_2)
        response = self.client.post(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,)),
            data={"confirm_site_name": "random"},
        )
        self.assertEqual(response.status_code, 200)
        # One error messages should be returned
        messages = [m.message for m in response.context["messages"]]
        self.assertEqual(len(messages), 1)
        self.assertContains(response, "This action will delete total <b>3</b> pages.")
        self.assertContains(response, "Please type <b>mysite</b> to confirm.")
        self.assertContains(response, '<input type="text" name="confirm_site_name"')
        # Site should not be deleted
        self.assertTrue(SimplePage.objects.filter(id=self.child_page.id).exists())

    @override_settings(WAGTAILADMIN_UNSAFE_PAGE_DELETION_LIMIT=3)
    @override_settings(WAGTAIL_SITE_NAME="mysite")
    def test_confirm_delete_scenario_4(self):
        # If admin entered the correct site name and submit the form
        # then the site should be deleted
        child_1 = SimplePage(title="child 1", slug="child-1", content="hello")
        self.child_page.add_child(instance=child_1)
        child_2 = SimplePage(title="child 2", slug="child-2", content="hello")
        self.child_page.add_child(instance=child_2)
        response = self.client.post(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,)),
            data={"confirm_site_name": "mysite"},
        )
        # Should be redirected to explorer page
        self.assertRedirects(
            response, reverse("wagtailadmin_explore", args=(self.root_page.id,))
        )
        # Check that the page is deleted
        self.assertFalse(SimplePage.objects.filter(id=self.child_page.id).exists())
        # Check that the subpage is also deleted
        self.assertFalse(SimplePage.objects.filter(id=child_1.id).exists())
        self.assertFalse(SimplePage.objects.filter(id=child_2.id).exists())

    def test_page_delete_specific_admin_title(self):
        response = self.client.get(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
        )
        self.assertEqual(response.status_code, 200)

        # The admin_display_title specific to ChildPage is shown on the delete confirmation page.
        self.assertContains(response, self.child_page.get_admin_display_title())

    def test_page_delete_bad_permissions(self):
        # Remove privileges from user
        self.user.is_superuser = False
        self.user.user_permissions.add(
            Permission.objects.get(
                content_type__app_label="wagtailadmin", codename="access_admin"
            )
        )
        self.user.save()

        # Get delete page
        response = self.client.get(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
        )

        # Check that the user received a 302 redirect response
        self.assertEqual(response.status_code, 302)

        # Check that the deletion has not happened
        self.assertTrue(SimplePage.objects.filter(id=self.child_page.id).exists())

    def test_page_delete_post(self):
        # Connect a mock signal handler to page_unpublished signal
        mock_handler = mock.MagicMock()
        page_unpublished.connect(mock_handler)

        # Post
        response = self.client.post(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
        )

        # Should be redirected to explorer page
        self.assertRedirects(
            response, reverse("wagtailadmin_explore", args=(self.root_page.id,))
        )

        # treebeard should report no consistency problems with the tree
        self.assertFalse(
            any(Page.find_problems()), "treebeard found consistency problems"
        )

        # Check that the page is gone
        self.assertEqual(
            Page.objects.filter(
                path__startswith=self.root_page.path, slug="hello-world"
            ).count(),
            0,
        )

        # Check that the page_unpublished signal was fired
        self.assertEqual(mock_handler.call_count, 1)
        mock_call = mock_handler.mock_calls[0][2]

        self.assertEqual(mock_call["sender"], self.child_page.specific_class)
        self.assertEqual(mock_call["instance"], self.child_page)
        self.assertIsInstance(mock_call["instance"], self.child_page.specific_class)

    def test_page_delete_notlive_post(self):
        # Same as above, but this makes sure the page_unpublished signal is not fired
        # when if the page is not live when it is deleted

        # Unpublish the page
        self.child_page.live = False
        self.child_page.save()

        # Connect a mock signal handler to page_unpublished signal
        mock_handler = mock.MagicMock()
        page_unpublished.connect(mock_handler)

        # Post
        response = self.client.post(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
        )

        # Should be redirected to explorer page
        self.assertRedirects(
            response, reverse("wagtailadmin_explore", args=(self.root_page.id,))
        )

        # treebeard should report no consistency problems with the tree
        self.assertFalse(
            any(Page.find_problems()), "treebeard found consistency problems"
        )

        # Check that the page is gone
        self.assertEqual(
            Page.objects.filter(
                path__startswith=self.root_page.path, slug="hello-world"
            ).count(),
            0,
        )

        # Check that the page_unpublished signal was not fired
        self.assertEqual(mock_handler.call_count, 0)

    def test_subpage_deletion(self):
        # Connect mock signal handlers to page_unpublished, pre_delete and post_delete signals
        unpublish_signals_received = []
        pre_delete_signals_received = []
        post_delete_signals_received = []

        def page_unpublished_handler(sender, instance, **kwargs):
            unpublish_signals_received.append((sender, instance.id))

        def pre_delete_handler(sender, instance, **kwargs):
            pre_delete_signals_received.append((sender, instance.id))

        def post_delete_handler(sender, instance, **kwargs):
            post_delete_signals_received.append((sender, instance.id))

        page_unpublished.connect(page_unpublished_handler)
        pre_delete.connect(pre_delete_handler)
        post_delete.connect(post_delete_handler)

        # Post
        response = self.client.post(
            reverse("wagtailadmin_pages:delete", args=(self.child_index.id,))
        )

        # Should be redirected to explorer page
        self.assertRedirects(
            response, reverse("wagtailadmin_explore", args=(self.root_page.id,))
        )

        # treebeard should report no consistency problems with the tree
        self.assertFalse(
            any(Page.find_problems()), "treebeard found consistency problems"
        )

        # Check that the page is gone
        self.assertFalse(StandardIndex.objects.filter(id=self.child_index.id).exists())
        self.assertFalse(Page.objects.filter(id=self.child_index.id).exists())

        # Check that the subpage is also gone
        self.assertFalse(
            StandardChild.objects.filter(id=self.grandchild_page.id).exists()
        )
        self.assertFalse(Page.objects.filter(id=self.grandchild_page.id).exists())

        # Check that the signals were fired for both pages
        self.assertIn((StandardIndex, self.child_index.id), unpublish_signals_received)
        self.assertIn(
            (StandardChild, self.grandchild_page.id), unpublish_signals_received
        )

        self.assertIn((StandardIndex, self.child_index.id), pre_delete_signals_received)
        self.assertIn(
            (StandardChild, self.grandchild_page.id), pre_delete_signals_received
        )

        self.assertIn(
            (StandardIndex, self.child_index.id), post_delete_signals_received
        )
        self.assertIn(
            (StandardChild, self.grandchild_page.id), post_delete_signals_received
        )

    def test_before_delete_page_hook(self):
        def hook_func(request, page):
            self.assertIsInstance(request, HttpRequest)
            self.assertEqual(page.id, self.child_page.id)

            return HttpResponse("Overridden!")

        with self.register_hook("before_delete_page", hook_func):
            response = self.client.get(
                reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
            )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content, b"Overridden!")

    def test_before_delete_page_hook_post(self):
        def hook_func(request, page):
            self.assertIsInstance(request, HttpRequest)
            self.assertEqual(page.id, self.child_page.id)

            return HttpResponse("Overridden!")

        with self.register_hook("before_delete_page", hook_func):
            response = self.client.post(
                reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
            )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content, b"Overridden!")

        # page should not be deleted
        self.assertTrue(Page.objects.filter(id=self.child_page.id).exists())

    def test_after_delete_page_hook(self):
        def hook_func(request, page):
            self.assertIsInstance(request, HttpRequest)
            self.assertEqual(page.id, self.child_page.id)

            return HttpResponse("Overridden!")

        with self.register_hook("after_delete_page", hook_func):
            response = self.client.post(
                reverse("wagtailadmin_pages:delete", args=(self.child_page.id,))
            )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content, b"Overridden!")

        # page should be deleted
        self.assertFalse(Page.objects.filter(id=self.child_page.id).exists())
コード例 #2
0
ファイル: test_page_locking.py プロジェクト: tnir/wagtail
class TestLocking(TestCase, WagtailTestUtils):
    def setUp(self):
        # Find root page
        self.root_page = Page.objects.get(id=2)

        # Login
        self.user = self.login()

        # Create a page and submit it for moderation
        self.child_page = SimplePage(
            title="Hello world!",
            slug="hello-world",
            content="hello",
            live=False,
        )
        self.root_page.add_child(instance=self.child_page)

    def test_lock_post(self):
        response = self.client.post(
            reverse("wagtailadmin_pages:lock", args=(self.child_page.id, )))

        # Check response
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # Check that the page is locked
        page = Page.objects.get(id=self.child_page.id)
        self.assertTrue(page.locked)
        self.assertEqual(page.locked_by, self.user)
        self.assertIsNotNone(page.locked_at)

    def test_lock_get(self):
        response = self.client.get(
            reverse("wagtailadmin_pages:lock", args=(self.child_page.id, )))

        # Check response
        self.assertEqual(response.status_code, 405)

        # Check that the page is still unlocked
        page = Page.objects.get(id=self.child_page.id)
        self.assertFalse(page.locked)
        self.assertIsNone(page.locked_by)
        self.assertIsNone(page.locked_at)

    def test_lock_post_already_locked(self):
        # Lock the page
        self.child_page.locked = True
        self.child_page.locked_by = self.user
        self.child_page.locked_at = timezone.now()
        self.child_page.save()

        response = self.client.post(
            reverse("wagtailadmin_pages:lock", args=(self.child_page.id, )))

        # Check response
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # Check that the page is still locked
        page = Page.objects.get(id=self.child_page.id)
        self.assertTrue(page.locked)
        self.assertEqual(page.locked_by, self.user)
        self.assertIsNotNone(page.locked_at)

    def test_lock_post_with_good_redirect(self):
        response = self.client.post(
            reverse("wagtailadmin_pages:lock", args=(self.child_page.id, )),
            {
                "next":
                reverse("wagtailadmin_pages:edit", args=(self.child_page.id, ))
            },
        )

        # Check response
        self.assertRedirects(
            response,
            reverse("wagtailadmin_pages:edit", args=(self.child_page.id, )))

        # Check that the page is locked
        page = Page.objects.get(id=self.child_page.id)
        self.assertTrue(page.locked)
        self.assertEqual(page.locked_by, self.user)
        self.assertIsNotNone(page.locked_at)

    def test_lock_post_with_bad_redirect(self):
        response = self.client.post(
            reverse("wagtailadmin_pages:lock", args=(self.child_page.id, )),
            {"next": "http://www.google.co.uk"},
        )

        # Check response
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # Check that the page is locked
        page = Page.objects.get(id=self.child_page.id)
        self.assertTrue(page.locked)
        self.assertEqual(page.locked_by, self.user)
        self.assertIsNotNone(page.locked_at)

    def test_lock_post_bad_page(self):
        response = self.client.post(
            reverse("wagtailadmin_pages:lock", args=(9999, )))

        # Check response
        self.assertEqual(response.status_code, 404)

        # Check that the page is still unlocked
        page = Page.objects.get(id=self.child_page.id)
        self.assertFalse(page.locked)
        self.assertIsNone(page.locked_by)
        self.assertIsNone(page.locked_at)

    def test_lock_post_bad_permissions(self):
        # Remove privileges from user
        self.user.is_superuser = False
        self.user.user_permissions.add(
            Permission.objects.get(content_type__app_label="wagtailadmin",
                                   codename="access_admin"))
        self.user.save()

        response = self.client.post(
            reverse("wagtailadmin_pages:lock", args=(self.child_page.id, )))

        # Check response
        self.assertEqual(response.status_code, 302)

        # Check that the page is still unlocked
        page = Page.objects.get(id=self.child_page.id)
        self.assertFalse(page.locked)
        self.assertIsNone(page.locked_by)
        self.assertIsNone(page.locked_at)

    def test_locked_pages_dashboard_panel(self):
        self.child_page.locked = True
        self.child_page.locked_by = self.user
        self.child_page.locked_at = timezone.now()
        self.child_page.save()
        response = self.client.get(reverse("wagtailadmin_home"))
        self.assertContains(response, "Your locked pages")
        # check that LockUnlockAction is present and passes a valid csrf token
        self.assertRegex(
            response.content.decode("utf-8"),
            r"LockUnlockAction\(\'\w+\'\, \'\/admin\/'\)",
        )

    def test_unlock_post(self):
        # Lock the page
        self.child_page.locked = True
        self.child_page.locked_by = self.user
        self.child_page.locked_at = timezone.now()
        self.child_page.save()

        response = self.client.post(
            reverse("wagtailadmin_pages:unlock", args=(self.child_page.id, )))

        # Check response
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # Check that the page is unlocked
        page = Page.objects.get(id=self.child_page.id)
        self.assertFalse(page.locked)
        self.assertIsNone(page.locked_by)
        self.assertIsNone(page.locked_at)

    def test_unlock_get(self):
        # Lock the page
        self.child_page.locked = True
        self.child_page.locked_by = self.user
        self.child_page.locked_at = timezone.now()
        self.child_page.save()

        response = self.client.get(
            reverse("wagtailadmin_pages:unlock", args=(self.child_page.id, )))

        # Check response
        self.assertEqual(response.status_code, 405)

        # Check that the page is still locked
        page = Page.objects.get(id=self.child_page.id)
        self.assertTrue(page.locked)
        self.assertEqual(page.locked_by, self.user)
        self.assertIsNotNone(page.locked_at)

    def test_unlock_post_already_unlocked(self):
        response = self.client.post(
            reverse("wagtailadmin_pages:unlock", args=(self.child_page.id, )))

        # Check response
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # Check that the page is still unlocked
        page = Page.objects.get(id=self.child_page.id)
        self.assertFalse(page.locked)
        self.assertIsNone(page.locked_by)
        self.assertIsNone(page.locked_at)

    def test_unlock_post_with_good_redirect(self):
        # Lock the page
        self.child_page.locked = True
        self.child_page.locked_by = self.user
        self.child_page.locked_at = timezone.now()
        self.child_page.save()

        response = self.client.post(
            reverse("wagtailadmin_pages:unlock", args=(self.child_page.id, )),
            {
                "next":
                reverse("wagtailadmin_pages:edit", args=(self.child_page.id, ))
            },
        )

        # Check response
        self.assertRedirects(
            response,
            reverse("wagtailadmin_pages:edit", args=(self.child_page.id, )))

        # Check that the page is unlocked
        page = Page.objects.get(id=self.child_page.id)
        self.assertFalse(page.locked)
        self.assertIsNone(page.locked_by)
        self.assertIsNone(page.locked_at)

    def test_unlock_post_with_bad_redirect(self):
        # Lock the page
        self.child_page.locked = True
        self.child_page.locked_by = self.user
        self.child_page.locked_at = timezone.now()
        self.child_page.save()

        response = self.client.post(
            reverse("wagtailadmin_pages:unlock", args=(self.child_page.id, )),
            {"next": "http://www.google.co.uk"},
        )

        # Check response
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # Check that the page is unlocked
        page = Page.objects.get(id=self.child_page.id)
        self.assertFalse(page.locked)
        self.assertIsNone(page.locked_by)
        self.assertIsNone(page.locked_at)

    def test_unlock_post_bad_page(self):
        # Lock the page
        self.child_page.locked = True
        self.child_page.locked_by = self.user
        self.child_page.locked_at = timezone.now()
        self.child_page.save()

        response = self.client.post(
            reverse("wagtailadmin_pages:unlock", args=(9999, )))

        # Check response
        self.assertEqual(response.status_code, 404)

        # Check that the page is still locked
        page = Page.objects.get(id=self.child_page.id)
        self.assertTrue(page.locked)
        self.assertEqual(page.locked_by, self.user)
        self.assertIsNotNone(page.locked_at)

    def test_unlock_post_bad_permissions(self):
        # Remove privileges from user
        self.user.is_superuser = False
        self.user.groups.add(Group.objects.get(name="Editors"))
        self.user.save()

        # Lock the page
        self.child_page.locked = True
        self.child_page.locked_at = timezone.now()
        self.child_page.save()

        response = self.client.post(
            reverse("wagtailadmin_pages:unlock", args=(self.child_page.id, )))

        # Check response
        self.assertEqual(response.status_code, 302)

        # Check that the page is still locked
        page = Page.objects.get(id=self.child_page.id)
        self.assertTrue(page.locked)
        self.assertIsNotNone(page.locked_at)

    def test_unlock_post_own_page_with_bad_permissions(self):
        # Unlike the previous test, the user can unlock pages that they have locked

        # Remove privileges from user
        self.user.is_superuser = False
        self.user.groups.add(Group.objects.get(name="Editors"))
        self.user.save()

        # Lock the page
        self.child_page.locked = True
        self.child_page.locked_by = self.user
        self.child_page.locked_at = timezone.now()
        self.child_page.save()

        response = self.client.post(
            reverse("wagtailadmin_pages:unlock", args=(self.child_page.id, )),
            {
                "next":
                reverse("wagtailadmin_pages:edit", args=(self.child_page.id, ))
            },
        )

        # Check response
        self.assertRedirects(
            response,
            reverse("wagtailadmin_pages:edit", args=(self.child_page.id, )))

        # Check that the page is still locked
        page = Page.objects.get(id=self.child_page.id)
        self.assertFalse(page.locked)
        self.assertIsNone(page.locked_by)
        self.assertIsNone(page.locked_at)
コード例 #3
0
ファイル: test_signals.py プロジェクト: tnir/wagtail
class TestPageSlugChangedSignal(TestCase, WagtailTestUtils):
    """
    Tests for the `wagtail.signals.page_slug_changed` signal
    """

    def setUp(self):
        # Find root page
        site = Site.objects.select_related("root_page").get(is_default_site=True)
        root_page = site.root_page

        # Create two sections
        self.section_a = SimplePage(
            title="Section A", slug="section-a", content="hello"
        )
        root_page.add_child(instance=self.section_a)

        self.section_b = SimplePage(
            title="Section B", slug="section-b", content="hello"
        )
        root_page.add_child(instance=self.section_b)

        # Add test page to section A
        self.test_page = SimplePage(
            title="Hello world! A", slug="hello-world-a", content="hello"
        )
        self.section_a.add_child(instance=self.test_page)

    def test_signal_emitted_on_slug_change(self):
        # Connect a mock signal handler to the signal
        handler = mock.MagicMock()
        page_slug_changed.connect(handler)

        old_page = SimplePage.objects.get(id=self.test_page.id)

        try:
            self.test_page.slug = "updated"
            self.test_page.save()
            # TODO: When Django 3.1< support is dropped, wrap save in
            # self.captureOnCommitCallbacks and remove this code
            for _, func in connection.run_on_commit:
                func()
        finally:
            # Disconnect mock handler to prevent cross-test pollution
            page_slug_changed.disconnect(handler)

        # Check the signal was fired
        self.assertEqual(handler.call_count, 1)
        self.assertTrue(
            handler.called_with(
                sender=SimplePage,
                instance=self.test_page,
                instance_before=old_page,
            )
        )

    def test_signal_not_emitted_on_title_change(self):
        # Connect a mock signal handler to the signal
        handler = mock.MagicMock()
        page_slug_changed.connect(handler)

        try:
            self.test_page.title = "Goodnight Moon!"
            self.test_page.save()
            # NOTE: Even though we're not expecting anything to happen here,
            # we need to invoke the callbacks in run_on_commit the same way
            # the same way we do in ``test_signal_emitted_on_slug_change``,
            # otherwise this test wouldn't prove anything.
            for _, func in connection.run_on_commit:
                func()
        finally:
            # Disconnect mock handler to prevent cross-test pollution
            page_slug_changed.disconnect(handler)

        # Check the signal was NOT fired
        self.assertEqual(handler.call_count, 0)

    def test_signal_not_emitted_on_page_move(self):
        # Connect a mock signal handler to the signal
        handler = mock.MagicMock()
        page_slug_changed.connect(handler)

        try:
            self.test_page.move(self.section_b, pos="last-child")
            # NOTE: Even though we're not expecting anything to happen here,
            # we need to invoke the callbacks in run_on_commit the same way
            # the same way we do in ``test_signal_emitted_on_slug_change``,
            # otherwise this test wouldn't prove anything.
            for _, func in connection.run_on_commit:
                func()
        finally:
            # Disconnect mock handler to prevent cross-test pollution
            page_slug_changed.disconnect(handler)

        # Check the signal was NOT fired
        self.assertEqual(handler.call_count, 0)
コード例 #4
0
ファイル: test_delete_page.py プロジェクト: tomkins/wagtail
class TestPageDelete(TestCase, WagtailTestUtils):
    def setUp(self):
        # Find root page
        self.root_page = Page.objects.get(id=2)

        # Add child page
        self.child_page = SimplePage(title="Hello world!",
                                     slug="hello-world",
                                     content="hello")
        self.root_page.add_child(instance=self.child_page)

        # Add a page with child pages of its own
        self.child_index = StandardIndex(title="Hello index",
                                         slug="hello-index")
        self.root_page.add_child(instance=self.child_index)
        self.grandchild_page = StandardChild(title="Hello Kitty",
                                             slug="hello-kitty")
        self.child_index.add_child(instance=self.grandchild_page)

        # Login
        self.user = self.login()

    def test_page_delete(self):
        response = self.client.get(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id, )))
        self.assertEqual(response.status_code, 200)
        # deletion should not actually happen on GET
        self.assertTrue(
            SimplePage.objects.filter(id=self.child_page.id).exists())

    def test_page_delete_specific_admin_title(self):
        response = self.client.get(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id, )))
        self.assertEqual(response.status_code, 200)

        # The admin_display_title specific to ChildPage is shown on the delete confirmation page.
        self.assertContains(response,
                            self.child_page.get_admin_display_title())

    def test_page_delete_bad_permissions(self):
        # Remove privileges from user
        self.user.is_superuser = False
        self.user.user_permissions.add(
            Permission.objects.get(content_type__app_label="wagtailadmin",
                                   codename="access_admin"))
        self.user.save()

        # Get delete page
        response = self.client.get(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id, )))

        # Check that the user received a 302 redirect response
        self.assertEqual(response.status_code, 302)

        # Check that the deletion has not happened
        self.assertTrue(
            SimplePage.objects.filter(id=self.child_page.id).exists())

    def test_page_delete_post(self):
        # Connect a mock signal handler to page_unpublished signal
        mock_handler = mock.MagicMock()
        page_unpublished.connect(mock_handler)

        # Post
        response = self.client.post(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id, )))

        # Should be redirected to explorer page
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # treebeard should report no consistency problems with the tree
        self.assertFalse(any(Page.find_problems()),
                         "treebeard found consistency problems")

        # Check that the page is gone
        self.assertEqual(
            Page.objects.filter(path__startswith=self.root_page.path,
                                slug="hello-world").count(),
            0,
        )

        # Check that the page_unpublished signal was fired
        self.assertEqual(mock_handler.call_count, 1)
        mock_call = mock_handler.mock_calls[0][2]

        self.assertEqual(mock_call["sender"], self.child_page.specific_class)
        self.assertEqual(mock_call["instance"], self.child_page)
        self.assertIsInstance(mock_call["instance"],
                              self.child_page.specific_class)

    def test_page_delete_notlive_post(self):
        # Same as above, but this makes sure the page_unpublished signal is not fired
        # when if the page is not live when it is deleted

        # Unpublish the page
        self.child_page.live = False
        self.child_page.save()

        # Connect a mock signal handler to page_unpublished signal
        mock_handler = mock.MagicMock()
        page_unpublished.connect(mock_handler)

        # Post
        response = self.client.post(
            reverse("wagtailadmin_pages:delete", args=(self.child_page.id, )))

        # Should be redirected to explorer page
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # treebeard should report no consistency problems with the tree
        self.assertFalse(any(Page.find_problems()),
                         "treebeard found consistency problems")

        # Check that the page is gone
        self.assertEqual(
            Page.objects.filter(path__startswith=self.root_page.path,
                                slug="hello-world").count(),
            0,
        )

        # Check that the page_unpublished signal was not fired
        self.assertEqual(mock_handler.call_count, 0)

    def test_subpage_deletion(self):
        # Connect mock signal handlers to page_unpublished, pre_delete and post_delete signals
        unpublish_signals_received = []
        pre_delete_signals_received = []
        post_delete_signals_received = []

        def page_unpublished_handler(sender, instance, **kwargs):
            unpublish_signals_received.append((sender, instance.id))

        def pre_delete_handler(sender, instance, **kwargs):
            pre_delete_signals_received.append((sender, instance.id))

        def post_delete_handler(sender, instance, **kwargs):
            post_delete_signals_received.append((sender, instance.id))

        page_unpublished.connect(page_unpublished_handler)
        pre_delete.connect(pre_delete_handler)
        post_delete.connect(post_delete_handler)

        # Post
        response = self.client.post(
            reverse("wagtailadmin_pages:delete", args=(self.child_index.id, )))

        # Should be redirected to explorer page
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # treebeard should report no consistency problems with the tree
        self.assertFalse(any(Page.find_problems()),
                         "treebeard found consistency problems")

        # Check that the page is gone
        self.assertFalse(
            StandardIndex.objects.filter(id=self.child_index.id).exists())
        self.assertFalse(Page.objects.filter(id=self.child_index.id).exists())

        # Check that the subpage is also gone
        self.assertFalse(
            StandardChild.objects.filter(id=self.grandchild_page.id).exists())
        self.assertFalse(
            Page.objects.filter(id=self.grandchild_page.id).exists())

        # Check that the signals were fired for both pages
        self.assertIn((StandardIndex, self.child_index.id),
                      unpublish_signals_received)
        self.assertIn((StandardChild, self.grandchild_page.id),
                      unpublish_signals_received)

        self.assertIn((StandardIndex, self.child_index.id),
                      pre_delete_signals_received)
        self.assertIn((StandardChild, self.grandchild_page.id),
                      pre_delete_signals_received)

        self.assertIn((StandardIndex, self.child_index.id),
                      post_delete_signals_received)
        self.assertIn((StandardChild, self.grandchild_page.id),
                      post_delete_signals_received)

    def test_before_delete_page_hook(self):
        def hook_func(request, page):
            self.assertIsInstance(request, HttpRequest)
            self.assertEqual(page.id, self.child_page.id)

            return HttpResponse("Overridden!")

        with self.register_hook("before_delete_page", hook_func):
            response = self.client.get(
                reverse("wagtailadmin_pages:delete",
                        args=(self.child_page.id, )))

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content, b"Overridden!")

    def test_before_delete_page_hook_post(self):
        def hook_func(request, page):
            self.assertIsInstance(request, HttpRequest)
            self.assertEqual(page.id, self.child_page.id)

            return HttpResponse("Overridden!")

        with self.register_hook("before_delete_page", hook_func):
            response = self.client.post(
                reverse("wagtailadmin_pages:delete",
                        args=(self.child_page.id, )))

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content, b"Overridden!")

        # page should not be deleted
        self.assertTrue(Page.objects.filter(id=self.child_page.id).exists())

    def test_after_delete_page_hook(self):
        def hook_func(request, page):
            self.assertIsInstance(request, HttpRequest)
            self.assertEqual(page.id, self.child_page.id)

            return HttpResponse("Overridden!")

        with self.register_hook("after_delete_page", hook_func):
            response = self.client.post(
                reverse("wagtailadmin_pages:delete",
                        args=(self.child_page.id, )))

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content, b"Overridden!")

        # page should be deleted
        self.assertFalse(Page.objects.filter(id=self.child_page.id).exists())