Пример #1
0
    def test_page_copy_post_new_parent(self):
        post_data = {
            "new_title": "Hello world 2",
            "new_slug": "hello-world-2",
            "new_parent_page": str(self.test_child_page.id),
            "copy_subpages": False,
            "publish_copies": False,
            "alias": False,
        }
        response = self.client.post(
            reverse("wagtailadmin_pages:copy", args=(self.test_page.id, )),
            post_data)

        # Check that the user was redirected to the new parents explore page
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.test_child_page.id, )))

        # Check that the page was copied to the correct place
        self.assertTrue(
            Page.objects.filter(slug="hello-world-2").first().get_parent(),
            msg=self.test_child_page,
        )

        # treebeard should report no consistency problems with the tree
        self.assertFalse(any(Page.find_problems()),
                         msg="treebeard found consistency problems")
Пример #2
0
    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)
Пример #3
0
    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)
Пример #4
0
    def test_page_copy_no_publish_permission_post_copy_subpages_publish_copies(self):
        # This tests that unprivileged users cannot publish copied pages even if they hack their browser

        # Turn user into an editor who can add pages but not publish them
        self.user.is_superuser = False
        self.user.groups.add(
            Group.objects.get(name="Editors"),
        )
        self.user.save()

        # Post
        post_data = {
            "new_title": "Hello world 2",
            "new_slug": "hello-world-2",
            "new_parent_page": str(self.root_page.id),
            "copy_subpages": True,
            "publish_copies": True,
            "alias": False,
        }
        response = self.client.post(
            reverse("wagtailadmin_pages:copy", args=(self.test_page.id,)), post_data
        )

        # Check that the user was redirected to the parents explore page
        self.assertRedirects(
            response, reverse("wagtailadmin_explore", args=(self.root_page.id,))
        )

        # Get copy
        page_copy = self.root_page.get_children().filter(slug="hello-world-2").first()

        # Check that the copy exists
        self.assertIsNotNone(page_copy)

        # Check that the copy is not live
        self.assertFalse(page_copy.live)

        # Check that the owner of the page is set correctly
        self.assertEqual(page_copy.owner, self.user)

        # Check that the children were copied
        self.assertEqual(page_copy.get_children().count(), 2)

        # Check the the child pages
        # Neither of them should be live
        child_copy = page_copy.get_children().filter(slug="child-page").first()
        self.assertIsNotNone(child_copy)
        self.assertFalse(child_copy.live)

        unpublished_child_copy = (
            page_copy.get_children().filter(slug="unpublished-child-page").first()
        )
        self.assertIsNotNone(unpublished_child_copy)
        self.assertFalse(unpublished_child_copy.live)

        # treebeard should report no consistency problems with the tree
        self.assertFalse(
            any(Page.find_problems()), msg="treebeard found consistency problems"
        )
Пример #5
0
    def test_bulk_delete_notlive_post(self):
        # Same as above, but this makes sure the page_unpublished signal is not fired
        # for the page that is not live when it is deleted

        # Unpublish the first child page
        page_to_be_unpublished = self.pages_to_be_deleted[0]
        page_to_be_unpublished.unpublish(user=self.user)

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

        # Post
        response = self.client.post(self.url)

        # Should be redirected to explorer page
        self.assertEqual(response.status_code, 302)

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

        # Check that the child pages to be deleted are gone
        for child_page in self.pages_to_be_deleted:
            self.assertFalse(
                SimplePage.objects.filter(id=child_page.id).exists())

        # Check that the child pages not to be deleted remain
        for child_page in self.pages_not_to_be_deleted:
            self.assertTrue(
                SimplePage.objects.filter(id=child_page.id).exists())

        # Check that the page_unpublished signal was not fired
        num_descendants = sum(
            len(v) for v in self.grandchildren_pages.values())
        self.assertEqual(mock_handler.call_count,
                         len(self.pages_to_be_deleted) + num_descendants - 1)

        # check that only signals for other pages are fired
        i = 0
        for child_page in self.pages_to_be_deleted:
            if child_page.id != page_to_be_unpublished.id:
                mock_call = mock_handler.mock_calls[i][2]
                i += 1
                self.assertEqual(mock_call["sender"],
                                 child_page.specific_class)
                self.assertEqual(mock_call["instance"], child_page)
                self.assertIsInstance(mock_call["instance"],
                                      child_page.specific_class)
            for grandchildren_page in self.grandchildren_pages.get(
                    child_page, []):
                mock_call = mock_handler.mock_calls[i][2]
                i += 1
                self.assertEqual(mock_call["sender"],
                                 grandchildren_page.specific_class)
                self.assertEqual(mock_call["instance"], grandchildren_page)
                self.assertIsInstance(mock_call["instance"],
                                      grandchildren_page.specific_class)
Пример #6
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)
Пример #7
0
    def test_page_copy_alias_post_copy_subpages(self):
        post_data = {
            "new_title": "Hello world 2",
            "new_slug": "hello-world-2",
            "new_parent_page": str(self.root_page.id),
            "copy_subpages": True,
            "publish_copies": False,
            "alias": True,
        }
        response = self.client.post(
            reverse("wagtailadmin_pages:copy", args=(self.test_page.id,)), post_data
        )

        # Check that the user was redirected to the parents explore page
        self.assertRedirects(
            response, reverse("wagtailadmin_explore", args=(self.root_page.id,))
        )

        # Get copy
        page_copy = self.root_page.get_children().get(slug="hello-world-2")

        # Check the copy is an alias of the original
        self.assertEqual(page_copy.alias_of, self.test_page.page_ptr)

        # Check that the copy is live
        # Note: publish_copies is ignored. Alias pages always keep the same state as their original
        self.assertTrue(page_copy.live)
        self.assertFalse(page_copy.has_unpublished_changes)

        # Check that the owner of the page is set correctly
        self.assertEqual(page_copy.owner, self.user)

        # Check that the children were copied
        self.assertEqual(page_copy.get_children().count(), 2)

        # Check the the child pages
        # Neither of them should be live
        child_copy = page_copy.get_children().filter(slug="child-page").first()
        self.assertIsNotNone(child_copy)
        self.assertEqual(child_copy.alias_of, self.test_child_page.page_ptr)
        self.assertTrue(child_copy.live)
        self.assertFalse(child_copy.has_unpublished_changes)

        unpublished_child_copy = (
            page_copy.get_children().filter(slug="unpublished-child-page").first()
        )
        self.assertIsNotNone(unpublished_child_copy)
        self.assertEqual(
            unpublished_child_copy.alias_of, self.test_unpublished_child_page.page_ptr
        )
        self.assertFalse(unpublished_child_copy.live)
        self.assertTrue(unpublished_child_copy.has_unpublished_changes)

        # treebeard should report no consistency problems with the tree
        self.assertFalse(
            any(Page.find_problems()), msg="treebeard found consistency problems"
        )
Пример #8
0
    def test_bulk_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(self.url)

        # Should be redirected to explorer page
        self.assertEqual(response.status_code, 302)

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

        # Check that the child pages to be deleted are gone
        for child_page in self.pages_to_be_deleted:
            self.assertFalse(
                SimplePage.objects.filter(id=child_page.id).exists())

        # Check that the child pages not to be deleted remain
        for child_page in self.pages_not_to_be_deleted:
            self.assertTrue(
                SimplePage.objects.filter(id=child_page.id).exists())

        # Check that the page_unpublished signal was fired for all pages
        num_descendants = sum(
            len(i) for i in self.grandchildren_pages.values())
        self.assertEqual(mock_handler.call_count,
                         len(self.pages_to_be_deleted) + num_descendants)

        i = 0
        for child_page in self.pages_to_be_deleted:
            mock_call = mock_handler.mock_calls[i][2]
            i += 1
            self.assertEqual(mock_call["sender"], child_page.specific_class)
            self.assertEqual(mock_call["instance"], child_page)
            self.assertIsInstance(mock_call["instance"],
                                  child_page.specific_class)
            for grandchildren_page in self.grandchildren_pages.get(
                    child_page, []):
                mock_call = mock_handler.mock_calls[i][2]
                i += 1
                self.assertEqual(mock_call["sender"],
                                 grandchildren_page.specific_class)
                self.assertEqual(mock_call["instance"], grandchildren_page)
                self.assertIsInstance(mock_call["instance"],
                                      grandchildren_page.specific_class)
Пример #9
0
    def test_page_copy_post(self):
        post_data = {
            "new_title": "Hello world 2",
            "new_slug": "hello-world-2",
            "new_parent_page": str(self.root_page.id),
            "copy_subpages": False,
            "publish_copies": False,
            "alias": False,
        }
        response = self.client.post(
            reverse("wagtailadmin_pages:copy", args=(self.test_page.id, )),
            post_data)

        # Check that the user was redirected to the parents explore page
        self.assertRedirects(
            response,
            reverse("wagtailadmin_explore", args=(self.root_page.id, )))

        # Get copy
        page_copy = self.root_page.get_children().filter(
            slug="hello-world-2").first()

        # Check that the copy exists
        self.assertIsNotNone(page_copy)

        # Check that the copy is not live
        self.assertFalse(page_copy.live)
        self.assertTrue(page_copy.has_unpublished_changes)

        # Check that the owner of the page is set correctly
        self.assertEqual(page_copy.owner, self.user)

        # Check that the children were not copied
        self.assertEqual(page_copy.get_children().count(), 0)

        # treebeard should report no consistency problems with the tree
        self.assertFalse(any(Page.find_problems()),
                         msg="treebeard found consistency problems")
Пример #10
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(self.url)

        # Should be redirected to explorer page
        self.assertEqual(response.status_code, 302)

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

        # Check that the child pages to be deleted are gone
        for child_page in self.pages_to_be_deleted:
            self.assertFalse(
                SimplePage.objects.filter(id=child_page.id).exists())

        # Check that the child pages not to be deleted remain
        for child_page in self.pages_not_to_be_deleted:
            self.assertTrue(
                SimplePage.objects.filter(id=child_page.id).exists())

        # Check that the subpages are also gone
        for grandchild_pages in self.grandchildren_pages.values():
            for grandchild_page in grandchild_pages:
                self.assertFalse(
                    SimplePage.objects.filter(id=grandchild_page.id).exists())

        # Check that the signals were fired for all child and grandchild pages
        for child_page, grandchild_pages in self.grandchildren_pages.items():
            self.assertIn((SimplePage, child_page.id),
                          unpublish_signals_received)
            self.assertIn((SimplePage, child_page.id),
                          pre_delete_signals_received)
            self.assertIn((SimplePage, child_page.id),
                          post_delete_signals_received)
            for grandchild_page in grandchild_pages:
                self.assertIn((SimplePage, grandchild_page.id),
                              unpublish_signals_received)
                self.assertIn((SimplePage, grandchild_page.id),
                              pre_delete_signals_received)
                self.assertIn((SimplePage, grandchild_page.id),
                              post_delete_signals_received)

        self.assertEqual(response.status_code, 302)