class TestPageQueryInSite(TestCase):
    fixtures = ['test.json']

    def setUp(self):
        self.site_2_page = SimplePage(
            title="Site 2 page",
            slug="site_2_page",
            content="Hello",
        )
        Page.get_first_root_node().add_child(instance=self.site_2_page)
        self.site_2_subpage = SimplePage(
            title="Site 2 subpage",
            slug="site_2_subpage",
            content="Hello again",
        )
        self.site_2_page.add_child(instance=self.site_2_subpage)

        self.site_2 = Site.objects.create(
            hostname='example.com',
            port=8080,
            root_page=Page.objects.get(pk=self.site_2_page.pk),
            is_default_site=False
        )
        self.about_us_page = SimplePage.objects.get(url_path='/home/about-us/')

    def test_in_site(self):
        site_2_pages = SimplePage.objects.in_site(self.site_2)

        self.assertIn(self.site_2_page, site_2_pages)
        self.assertIn(self.site_2_subpage, site_2_pages)
        self.assertNotIn(self.about_us_page, site_2_pages)
Beispiel #2
0
class TestPageQueryInSite(TestCase):
    fixtures = ['test.json']

    def setUp(self):
        self.site_2_page = SimplePage(
            title="Site 2 page",
            slug="site_2_page",
            content="Hello",
        )
        Page.get_first_root_node().add_child(instance=self.site_2_page)
        self.site_2_subpage = SimplePage(
            title="Site 2 subpage",
            slug="site_2_subpage",
            content="Hello again",
        )
        self.site_2_page.add_child(instance=self.site_2_subpage)

        self.site_2 = Site.objects.create(
            hostname='example.com',
            port=8080,
            root_page=Page.objects.get(pk=self.site_2_page.pk),
            is_default_site=False)
        self.about_us_page = SimplePage.objects.get(url_path='/home/about-us/')

    def test_in_site(self):
        site_2_pages = SimplePage.objects.in_site(self.site_2)

        self.assertIn(self.site_2_page, site_2_pages)
        self.assertIn(self.site_2_subpage, site_2_pages)
        self.assertNotIn(self.about_us_page, site_2_pages)
Beispiel #3
0
    def test_get_workflow_from_closest_ancestor(self):
        # test that using Page.get_workflow() tries to get the workflow from itself, then the closest ancestor, and does
        # not get Workflows from further up the page tree first
        workflow_1 = Workflow.objects.create(name='test_workflow_1')
        workflow_2 = Workflow.objects.create(name='test_workflow_2')
        homepage = Page.objects.get(url_path='/home/')
        WorkflowPage.objects.create(page=homepage, workflow=workflow_1)
        hello_page = SimplePage(title="Hello world",
                                slug='hello-world',
                                content="hello")
        homepage.add_child(instance=hello_page)
        WorkflowPage.objects.create(page=hello_page, workflow=workflow_2)
        goodbye_page = SimplePage(title="Goodbye world",
                                  slug='goodbye-world',
                                  content="goodbye")
        hello_page.add_child(instance=goodbye_page)
        self.assertEqual(hello_page.get_workflow(), workflow_2)
        self.assertEqual(goodbye_page.get_workflow(), workflow_2)

        # Check the .all_pages() method
        self.assertFalse(
            workflow_1.all_pages().filter(id=hello_page.id).exists())
        self.assertFalse(
            workflow_1.all_pages().filter(id=goodbye_page.id).exists())
        self.assertTrue(
            workflow_2.all_pages().filter(id=hello_page.id).exists())
        self.assertTrue(
            workflow_2.all_pages().filter(id=goodbye_page.id).exists())
Beispiel #4
0
class TestBulkMove(TestCase, WagtailTestUtils):
    fixtures = ['test.json']

    def setUp(self):
        # Find root page
        self.root_page = Page.objects.get(id=2)

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

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

        self.section_c = SimplePage(title="Section C",
                                    slug="section-c",
                                    content="hello")
        self.root_page.add_child(instance=self.section_c)

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

        # Add test page B into section C
        self.test_page_b = SimplePage(title="Hello world!",
                                      slug="hello-world-b",
                                      content="hello")
        self.section_c.add_child(instance=self.test_page_b)

        # Add test page B_1 into section C
        self.test_page_b_1 = SimplePage(title="Hello world!",
                                        slug="hello-world-b-1",
                                        content="hello")
        self.section_c.add_child(instance=self.test_page_b_1)

        # Add test page A_1 into section C having same slug as test page A
        self.test_page_a_1 = SimplePage(title="Hello world!",
                                        slug="hello-world-a",
                                        content="hello")
        self.section_c.add_child(instance=self.test_page_a_1)

        # Add unpublished page to the root with a child page
        self.unpublished_page = SimplePage(title="Unpublished",
                                           slug="unpublished",
                                           content="hello")
        sub_page = SimplePage(title="Sub Page",
                              slug="sub-page",
                              content="child")
        self.root_page.add_child(instance=self.unpublished_page)
        self.unpublished_page.add_child(instance=sub_page)

        # unpublish pages last (used to validate the edit only permission)
        self.unpublished_page.unpublish()
        sub_page.unpublish()

        self.pages_to_be_moved = [self.test_page_b, self.test_page_b_1]

        self.url = reverse(
            'wagtail_bulk_action', args=(
                'wagtailcore',
                'page',
                'move',
            )) + f'?id={self.test_page_b.id}&id={self.test_page_b_1.id}'

        # Login
        self.user = self.login()

    def test_bulk_move(self):
        response = self.client.get(self.url)
        self.assertEqual(response.status_code, 200)

        html = response.content.decode()

        self.assertInHTML('<p>Are you sure you want to move these pages?</p>',
                          html)

        for child_page in self.pages_to_be_moved:
            self.assertInHTML(
                '<li><a href="{edit_page_url}" target="_blank" rel="noopener noreferrer">{page_title}</a></li>'
                .format(edit_page_url=reverse('wagtailadmin_pages:edit',
                                              args=[child_page.id]),
                        page_title=child_page.title), html)

    def test_bulk_move_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 move page
        response = self.client.get(self.url)

        self.assertEqual(response.status_code, 200)

        html = response.content.decode()

        self.assertInHTML(
            "<p>You don't have permission to move these pages</p>", html)

        for child_page in self.pages_to_be_moved:
            self.assertInHTML(
                '<li>{page_title}</li>'.format(page_title=child_page.title),
                html)

        self.assertTagInHTML(
            '''<form action="{}" method="POST"></form>'''.format(self.url),
            html,
            count=0)

    def test_user_without_bulk_delete_permission_can_move(self):
        # to verify that a user without bulk delete permission is able to move a page with a child page

        self.client.logout()
        user = get_user_model().objects.get(email='*****@*****.**')
        self.login(user)

        # ensure the bulk_delete is not applicable to this user
        can_bulk_delete = self.test_page_b.permissions_for_user(
            user).can_delete()
        self.assertFalse(can_bulk_delete)

        response = self.client.get(
            reverse('wagtail_bulk_action',
                    args=(
                        'wagtailcore',
                        'page',
                        'move',
                    )) + f'?id={self.unpublished_page.id}')

        self.assertEqual(response.status_code, 200)

    def test_bulk_move_destination_not_allowed(self):
        page = BusinessChild(title="Section no child", slug="section-no-child")
        self.root_page.add_child(instance=page)

        response = self.client.post(self.url, {'chooser': page.id})

        html = response.content.decode()

        self.assertInHTML(
            '<p>The following pages cannot be moved to {}</p>'.format(
                page.title), html)

        for child_page in self.pages_to_be_moved:
            self.assertInHTML(
                '<li><a href="{edit_page_url}" target="_blank" rel="noopener noreferrer">{page_title}</a></li>'
                .format(edit_page_url=reverse('wagtailadmin_pages:edit',
                                              args=[child_page.id]),
                        page_title=child_page.title), html)

    def test_bulk_move_slug_already_taken(self):
        temp_page_1 = SimplePage(title="Hello world!",
                                 slug="hello-world-b",
                                 content="hello")
        temp_page_2 = SimplePage(title="Hello world!",
                                 slug="hello-world-b-1",
                                 content="hello")
        self.section_b.add_child(instance=temp_page_1)
        self.section_b.add_child(instance=temp_page_2)

        response = self.client.post(self.url, {'chooser': self.section_b.id})

        html = response.content.decode()

        self.assertInHTML(
            '<p>The following pages cannot be moved due to duplicate slugs</p>',
            html)

        for child_page in self.pages_to_be_moved:
            self.assertInHTML(
                '<li><a href="{edit_page_url}" target="_blank" rel="noopener noreferrer">{page_title}</a></li>'
                .format(edit_page_url=reverse('wagtailadmin_pages:edit',
                                              args=[child_page.id]),
                        page_title=child_page.title), html)

    def test_bulk_move_triggers_signals(self):
        # Connect a mock signal handler to pre_page_move and post_page_move signals
        pre_moved_handler = mock.MagicMock()
        post_moved_handler = mock.MagicMock()

        pre_page_move.connect(pre_moved_handler)
        post_page_move.connect(post_moved_handler)

        # Post to view confirm move page
        try:
            self.client.post(self.url, {'chooser': self.section_b.id})
        finally:
            # Disconnect mock handler to prevent cross-test pollution
            pre_page_move.disconnect(pre_moved_handler)
            post_page_move.disconnect(post_moved_handler)

        # Check that the pre_page_move signals were fired
        self.assertTrue(pre_moved_handler.mock_calls[0].called_with(
            sender=self.test_page_b.specific_class,
            instance=self.test_page_b,
            parent_page_before=self.section_c,
            parent_page_after=self.section_b,
            url_path_before='/home/section-c/hello-world-b/',
            url_path_after='/home/section-b/hello-world-b/',
        ))
        self.assertTrue(pre_moved_handler.mock_calls[1].called_with(
            sender=self.test_page_b_1.specific_class,
            instance=self.test_page_b_1,
            parent_page_before=self.section_c,
            parent_page_after=self.section_b,
            url_path_before='/home/section-c/hello-world-b-1/',
            url_path_after='/home/section-b/hello-world-b-1/',
        ))

        # Check that the post_page_move signals were fired
        self.assertTrue(post_moved_handler.mock_calls[0].called_with(
            sender=self.test_page_b.specific_class,
            instance=self.test_page_b,
            parent_page_before=self.section_c,
            parent_page_after=self.section_b,
            url_path_before='/home/section-c/hello-world-b/',
            url_path_after='/home/section-b/hello-world-b/',
        ))
        self.assertTrue(post_moved_handler.mock_calls[1].called_with(
            sender=self.test_page_b_1.specific_class,
            instance=self.test_page_b_1,
            parent_page_before=self.section_c,
            parent_page_after=self.section_b,
            url_path_before='/home/section-c/hello-world-b-1/',
            url_path_after='/home/section-b/hello-world-b-1/',
        ))

    def test_before_bulk_move_hook(self):
        def hook_func(request, action_type, pages, action_class_instance):
            self.assertEqual(action_type, 'move')
            self.assertIsInstance(request, HttpRequest)
            self.assertIsInstance(action_class_instance, PageBulkAction)
            for i, page in enumerate(pages):
                self.assertEqual(page.id, self.pages_to_be_moved[i].id)

            return HttpResponse("Overridden!")

        with self.register_hook('before_bulk_action', hook_func):
            response = self.client.post(self.url,
                                        {'chooser': self.section_b.id})

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

        self.assertEqual(
            Page.objects.get(id=self.test_page_b.id).get_parent().id,
            self.section_c.id)
        self.assertEqual(
            Page.objects.get(id=self.test_page_b_1.id).get_parent().id,
            self.section_c.id)

    def test_after_bulk_move_hook(self):
        def hook_func(request, action_type, pages, action_class_instance):
            self.assertEqual(action_type, 'move')
            self.assertIsInstance(request, HttpRequest)
            self.assertIsInstance(action_class_instance, PageBulkAction)
            for i, page in enumerate(pages):
                self.assertEqual(page.id, self.pages_to_be_moved[i].id)

            return HttpResponse("Overridden!")

        with self.register_hook('after_bulk_action', hook_func):
            response = self.client.post(self.url,
                                        {'chooser': self.section_b.id})

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

        # pages should be moved
        self.assertEqual(
            Page.objects.get(id=self.test_page_b.id).get_parent().id,
            self.section_b.id)
        self.assertEqual(
            Page.objects.get(id=self.test_page_b_1.id).get_parent().id,
            self.section_b.id)
Beispiel #5
0
class TestChooserBrowseChild(TestCase, WagtailTestUtils):
    def setUp(self):
        self.root_page = Page.objects.get(id=2)

        # Add child page
        self.child_page = SimplePage(title="foobarbaz", content="hello")
        self.root_page.add_child(instance=self.child_page)

        self.login()

    def get(self, params={}):
        return self.client.get(reverse('wagtailadmin_choose_page_child',
                                       args=(self.root_page.id,)), params)

    def get_invalid(self, params={}):
        return self.client.get(reverse('wagtailadmin_choose_page_child',
                                       args=(9999999,)), params)

    def test_simple(self):
        response = self.get()
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

    def test_get_invalid(self):
        self.assertEqual(self.get_invalid().status_code, 404)

    def test_with_page_type(self):
        # Add a page that is not a SimplePage
        event_page = EventPage(
            title="event",
            location='the moon', audience='public',
            cost='free', date_from='2001-01-01',
        )
        self.root_page.add_child(instance=event_page)

        # Add a page with a child page
        event_index_page = EventIndex(
            title="events",
        )
        self.root_page.add_child(instance=event_index_page)
        event_index_page.add_child(instance=EventPage(
            title="other event",
            location='the moon', audience='public',
            cost='free', date_from='2001-01-01',
        ))

        # Send request
        response = self.get({'page_type': 'tests.simplepage'})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')
        self.assertEqual(response.context['page_type_string'], 'tests.simplepage')

        pages = {
            page.id: page
            for page in response.context['pages'].object_list
        }

        # Child page is a simple page directly underneath root
        # so should appear in the list
        self.assertIn(self.child_page.id, pages)
        self.assertTrue(pages[self.child_page.id].can_choose)
        self.assertFalse(pages[self.child_page.id].can_descend)

        # Event page is not a simple page and is not descendable either
        # so should not appear in the list
        self.assertNotIn(event_page.id, pages)

        # Event index page is not a simple page but has a child and is therefore descendable
        # so should appear in the list
        self.assertIn(event_index_page.id, pages)
        self.assertFalse(pages[event_index_page.id].can_choose)
        self.assertTrue(pages[event_index_page.id].can_descend)

    def test_with_url_extended_page_type(self):
        # Add a page that overrides the url path
        single_event_page = SingleEventPage(
            title="foo",
            location='the moon', audience='public',
            cost='free', date_from='2001-01-01',
        )
        self.root_page.add_child(instance=single_event_page)

        # Send request
        response = self.get()
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

        page_urls = [
            page.url
            for page in response.context['pages']
        ]

        self.assertIn('/foo/pointless-suffix/', page_urls)

    def test_with_blank_page_type(self):
        # a blank page_type parameter should be equivalent to an absent parameter
        # (or an explicit page_type of wagtailcore.page)
        response = self.get({'page_type': ''})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

    def test_with_multiple_page_types(self):
        # Add a page that is not a SimplePage
        event_page = EventPage(
            title="event",
            location='the moon', audience='public',
            cost='free', date_from='2001-01-01',
        )
        self.root_page.add_child(instance=event_page)

        # Send request
        response = self.get({'page_type': 'tests.simplepage,tests.eventpage'})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')
        self.assertEqual(response.context['page_type_string'], 'tests.simplepage,tests.eventpage')

        pages = {
            page.id: page
            for page in response.context['pages'].object_list
        }

        # Simple page in results, as before
        self.assertIn(self.child_page.id, pages)
        self.assertTrue(pages[self.child_page.id].can_choose)

        # Event page should now also be choosable
        self.assertIn(event_page.id, pages)
        self.assertTrue(pages[self.child_page.id].can_choose)

    def test_with_unknown_page_type(self):
        response = self.get({'page_type': 'foo.bar'})
        self.assertEqual(response.status_code, 404)

    def test_with_bad_page_type(self):
        response = self.get({'page_type': 'wagtailcore.site'})
        self.assertEqual(response.status_code, 404)

    def test_with_invalid_page_type(self):
        response = self.get({'page_type': 'foo'})
        self.assertEqual(response.status_code, 404)

    def test_with_admin_display_title(self):
        # Check the display of the child page title when it's a child
        response = self.get({'page_type': 'wagtailcore.Page'})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

        html = response.json().get('html')
        self.assertInHTML("foobarbaz (simple page)", html)

        # The data-title attribute should not use the custom admin display title,
        # because JS code that uses that attribute (e.g. the rich text editor)
        # should use the real page title.
        self.assertIn('data-title="foobarbaz"', html)

    def test_parent_with_admin_display_title(self):
        # Add another child under child_page so it renders a chooser list
        leaf_page = SimplePage(title="quux", content="goodbye")
        self.child_page.add_child(instance=leaf_page)

        # Use the child page as the chooser parent
        response = self.client.get(
            reverse('wagtailadmin_choose_page_child', args=(self.child_page.id,)),
            params={'page_type': 'wagtailcore.Page'}
        )
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

        self.assertInHTML("foobarbaz (simple page)", response.json().get('html'))
        self.assertInHTML("quux (simple page)", response.json().get('html'))

    def test_admin_display_title_breadcrumb(self):
        # Add another child under child_page so we get breadcrumbs
        leaf_page = SimplePage(title="quux", content="goodbye")
        self.child_page.add_child(instance=leaf_page)

        # Use the leaf page as the chooser parent, so child is in the breadcrumbs
        response = self.client.get(
            reverse('wagtailadmin_choose_page_child', args=(leaf_page.id,))
        )
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

        # Look for a link element in the breadcrumbs with the admin title
        self.assertTagInHTML(
            '<li><a href="/admin/choose-page/{page_id}/?" class="navigate-pages">{page_title}</a></li>'.format(
                page_id=self.child_page.id,
                page_title="foobarbaz (simple page)",
            ),
            response.json().get('html')
        )

    def setup_pagination_test_data(self):
        # Create lots of pages
        for i in range(100):
            new_page = SimplePage(
                title="foobarbaz",
                slug="foobarbaz-%d" % i,
                content="hello",
            )
            self.root_page.add_child(instance=new_page)

    def test_pagination_basic(self):
        self.setup_pagination_test_data()

        response = self.get()
        self.assertEqual(response.context['pages'].paginator.num_pages, 5)
        self.assertEqual(response.context['pages'].number, 1)

    def test_pagination_another_page(self):
        self.setup_pagination_test_data()

        response = self.get({'p': 2})
        self.assertEqual(response.context['pages'].number, 2)

    def test_pagination_invalid_page(self):
        self.setup_pagination_test_data()

        response = self.get({'p': 'foo'})
        self.assertEqual(response.context['pages'].number, 1)

    def test_pagination_out_of_range_page(self):
        self.setup_pagination_test_data()

        response = self.get({'p': 100})
        self.assertEqual(response.context['pages'].number, 5)
Beispiel #6
0
class TestChooserBrowseChild(TestCase, WagtailTestUtils):
    def setUp(self):
        self.root_page = Page.objects.get(id=2)

        # Add child page
        self.child_page = SimplePage(title="foobarbaz", content="hello")
        self.root_page.add_child(instance=self.child_page)

        self.login()

    def get(self, params={}):
        return self.client.get(reverse('wagtailadmin_choose_page_child',
                                       args=(self.root_page.id,)), params)

    def get_invalid(self, params={}):
        return self.client.get(reverse('wagtailadmin_choose_page_child',
                                       args=(9999999,)), params)

    def test_simple(self):
        response = self.get()
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

    def test_get_invalid(self):
        self.assertEqual(self.get_invalid().status_code, 404)

    def test_with_page_type(self):
        # Add a page that is not a SimplePage
        event_page = EventPage(
            title="event",
            location='the moon', audience='public',
            cost='free', date_from='2001-01-01',
        )
        self.root_page.add_child(instance=event_page)

        # Add a page with a child page
        event_index_page = EventIndex(
            title="events",
        )
        self.root_page.add_child(instance=event_index_page)
        event_index_page.add_child(instance=EventPage(
            title="other event",
            location='the moon', audience='public',
            cost='free', date_from='2001-01-01',
        ))

        # Send request
        response = self.get({'page_type': 'tests.simplepage'})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')
        self.assertEqual(response.context['page_type_string'], 'tests.simplepage')

        pages = {
            page.id: page
            for page in response.context['pages'].object_list
        }

        # Child page is a simple page directly underneath root
        # so should appear in the list
        self.assertIn(self.child_page.id, pages)
        self.assertTrue(pages[self.child_page.id].can_choose)
        self.assertFalse(pages[self.child_page.id].can_descend)

        # Event page is not a simple page and is not descendable either
        # so should not appear in the list
        self.assertNotIn(event_page.id, pages)

        # Event index page is not a simple page but has a child and is therefore descendable
        # so should appear in the list
        self.assertIn(event_index_page.id, pages)
        self.assertFalse(pages[event_index_page.id].can_choose)
        self.assertTrue(pages[event_index_page.id].can_descend)

    def test_with_url_extended_page_type(self):
        # Add a page that overrides the url path
        single_event_page = SingleEventPage(
            title="foo",
            location='the moon', audience='public',
            cost='free', date_from='2001-01-01',
        )
        self.root_page.add_child(instance=single_event_page)

        # Send request
        response = self.get()
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

        page_urls = [
            page.url
            for page in response.context['pages']
        ]

        self.assertIn('/foo/pointless-suffix/', page_urls)

    def test_with_blank_page_type(self):
        # a blank page_type parameter should be equivalent to an absent parameter
        # (or an explicit page_type of wagtailcore.page)
        response = self.get({'page_type': ''})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

    def test_with_multiple_page_types(self):
        # Add a page that is not a SimplePage
        event_page = EventPage(
            title="event",
            location='the moon', audience='public',
            cost='free', date_from='2001-01-01',
        )
        self.root_page.add_child(instance=event_page)

        # Send request
        response = self.get({'page_type': 'tests.simplepage,tests.eventpage'})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')
        self.assertEqual(response.context['page_type_string'], 'tests.simplepage,tests.eventpage')

        pages = {
            page.id: page
            for page in response.context['pages'].object_list
        }

        # Simple page in results, as before
        self.assertIn(self.child_page.id, pages)
        self.assertTrue(pages[self.child_page.id].can_choose)

        # Event page should now also be choosable
        self.assertIn(event_page.id, pages)
        self.assertTrue(pages[self.child_page.id].can_choose)

    def test_with_unknown_page_type(self):
        response = self.get({'page_type': 'foo.bar'})
        self.assertEqual(response.status_code, 404)

    def test_with_bad_page_type(self):
        response = self.get({'page_type': 'wagtailcore.site'})
        self.assertEqual(response.status_code, 404)

    def test_with_invalid_page_type(self):
        response = self.get({'page_type': 'foo'})
        self.assertEqual(response.status_code, 404)

    def test_with_admin_display_title(self):
        # Check the display of the child page title when it's a child
        response = self.get({'page_type': 'wagtailcore.Page'})
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

        self.assertInHTML("foobarbaz (simple page)", response.json().get('html'))

    def test_parent_with_admin_display_title(self):
        # Add another child under child_page so it renders a chooser list
        leaf_page = SimplePage(title="quux", content="goodbye")
        self.child_page.add_child(instance=leaf_page)

        # Use the child page as the chooser parent
        response = self.client.get(
            reverse('wagtailadmin_choose_page_child', args=(self.child_page.id,)),
            params={'page_type': 'wagtailcore.Page'}
        )
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

        self.assertInHTML("foobarbaz (simple page)", response.json().get('html'))
        self.assertInHTML("quux (simple page)", response.json().get('html'))

    def test_admin_display_title_breadcrumb(self):
        # Add another child under child_page so we get breadcrumbs
        leaf_page = SimplePage(title="quux", content="goodbye")
        self.child_page.add_child(instance=leaf_page)

        # Use the leaf page as the chooser parent, so child is in the breadcrumbs
        response = self.client.get(
            reverse('wagtailadmin_choose_page_child', args=(leaf_page.id,))
        )
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/chooser/browse.html')

        # Look for a link element in the breadcrumbs with the admin title
        self.assertTagInHTML(
            '<li><a href="/admin/choose-page/{page_id}/?" class="navigate-pages">{page_title}</a></li>'.format(
                page_id=self.child_page.id,
                page_title="foobarbaz (simple page)",
            ),
            response.json().get('html')
        )

    def setup_pagination_test_data(self):
        # Create lots of pages
        for i in range(100):
            new_page = SimplePage(
                title="foobarbaz",
                slug="foobarbaz-%d" % i,
                content="hello",
            )
            self.root_page.add_child(instance=new_page)

    def test_pagination_basic(self):
        self.setup_pagination_test_data()

        response = self.get()
        self.assertEqual(response.context['pages'].paginator.num_pages, 5)
        self.assertEqual(response.context['pages'].number, 1)

    def test_pagination_another_page(self):
        self.setup_pagination_test_data()

        response = self.get({'p': 2})
        self.assertEqual(response.context['pages'].number, 2)

    def test_pagination_invalid_page(self):
        self.setup_pagination_test_data()

        response = self.get({'p': 'foo'})
        self.assertEqual(response.context['pages'].number, 1)

    def test_pagination_out_of_range_page(self):
        self.setup_pagination_test_data()

        response = self.get({'p': 100})
        self.assertEqual(response.context['pages'].number, 5)
class TestPageMove(TestCase, WagtailTestUtils):
    def setUp(self):
        # Find root page
        self.root_page = Page.objects.get(id=2)

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

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

        self.section_c = SimplePage(title="Section C",
                                    slug="section-c",
                                    content="hello")
        self.root_page.add_child(instance=self.section_c)

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

        # Add test page B into section C
        self.test_page_b = SimplePage(title="Hello world!",
                                      slug="hello-world",
                                      content="hello")
        self.section_c.add_child(instance=self.test_page_b)

        # Login
        self.user = self.login()

    def test_page_move(self):
        response = self.client.get(
            reverse('wagtailadmin_pages:move', args=(self.test_page_a.id, )))
        self.assertEqual(response.status_code, 200)

    def test_page_move_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 move page
        response = self.client.get(
            reverse('wagtailadmin_pages:move', args=(self.test_page_a.id, )))

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

    def test_page_move_confirm(self):
        response = self.client.get(
            reverse('wagtailadmin_pages:move_confirm',
                    args=(self.test_page_a.id, self.section_b.id)))
        self.assertEqual(response.status_code, 200)

        response = self.client.get(
            reverse('wagtailadmin_pages:move_confirm',
                    args=(self.test_page_b.id, self.section_a.id)))
        # Duplicate slugs triggers a redirect with an error message.
        self.assertEqual(response.status_code, 302)

        response = self.client.get(reverse('wagtailadmin_home'))
        messages = list(response.context['messages'])
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0].level, message_constants.ERROR)
        # Slug should be in error message.
        self.assertIn("{}".format(self.test_page_b.slug), messages[0].message)

    def test_page_set_page_position(self):
        response = self.client.get(
            reverse('wagtailadmin_pages:set_page_position',
                    args=(self.test_page_a.id, )))
        self.assertEqual(response.status_code, 200)

    def test_before_move_page_hook(self):
        def hook_func(request, page, destination):
            self.assertIsInstance(request, HttpRequest)
            self.assertIsInstance(page.specific, SimplePage)
            self.assertIsInstance(destination.specific, SimplePage)

            return HttpResponse("Overridden!")

        with self.register_hook('before_move_page', hook_func):
            response = self.client.get(
                reverse('wagtailadmin_pages:move_confirm',
                        args=(self.test_page_a.id, self.section_b.id)))

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

    def test_before_move_page_hook_post(self):
        def hook_func(request, page, destination):
            self.assertIsInstance(request, HttpRequest)
            self.assertIsInstance(page.specific, SimplePage)
            self.assertIsInstance(destination.specific, SimplePage)

            return HttpResponse("Overridden!")

        with self.register_hook('before_move_page', hook_func):
            response = self.client.post(
                reverse('wagtailadmin_pages:move_confirm',
                        args=(self.test_page_a.id, self.section_b.id)))

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

        # page should not be moved
        self.assertEqual(
            Page.objects.get(id=self.test_page_a.id).get_parent().id,
            self.section_a.id)

    def test_after_move_page_hook(self):
        def hook_func(request, page):
            self.assertIsInstance(request, HttpRequest)
            self.assertIsInstance(page.specific, SimplePage)

            return HttpResponse("Overridden!")

        with self.register_hook('after_move_page', hook_func):
            response = self.client.post(
                reverse('wagtailadmin_pages:move_confirm',
                        args=(self.test_page_a.id, self.section_b.id)))

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

        # page should be moved
        self.assertEqual(
            Page.objects.get(id=self.test_page_a.id).get_parent().id,
            self.section_b.id)
Beispiel #8
0
class TestPageMove(TestCase, WagtailTestUtils):
    fixtures = ['test.json']

    def setUp(self):
        # Find root page
        self.root_page = Page.objects.get(id=2)

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

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

        self.section_c = SimplePage(title="Section C",
                                    slug="section-c",
                                    content="hello")
        self.root_page.add_child(instance=self.section_c)

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

        # Add test page B into section C
        self.test_page_b = SimplePage(title="Hello world!",
                                      slug="hello-world",
                                      content="hello")
        self.section_c.add_child(instance=self.test_page_b)

        # Add unpublished page to the root with a child page
        self.unpublished_page = SimplePage(title="Unpublished",
                                           slug="unpublished",
                                           content="hello")
        sub_page = SimplePage(title="Sub Page",
                              slug="sub-page",
                              content="child")
        self.root_page.add_child(instance=self.unpublished_page)
        self.unpublished_page.add_child(instance=sub_page)

        # unpublish pages last (used to validate the edit only permission)
        self.unpublished_page.unpublish()
        sub_page.unpublish()

        # Login
        self.user = self.login()

    def test_page_move(self):
        response = self.client.get(
            reverse('wagtailadmin_pages:move', args=(self.test_page_a.id, )))
        self.assertEqual(response.status_code, 200)

    def test_page_move_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 move page
        response = self.client.get(
            reverse('wagtailadmin_pages:move', args=(self.test_page_a.id, )))

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

    def test_user_without_bulk_delete_permission_can_move(self):
        # to verify that a user without bulk delete permission is able to move a page with a child page

        self.client.logout()
        user = get_user_model().objects.get(email='*****@*****.**')
        self.login(user)

        # ensure the bulk_delete is not applicable to this user
        can_bulk_delete = self.test_page_b.permissions_for_user(
            user).can_delete()
        self.assertFalse(can_bulk_delete)

        response = self.client.get(
            reverse('wagtailadmin_pages:move',
                    args=(self.unpublished_page.id, )))

        self.assertEqual(response.status_code, 200)

    def test_page_move_confirm(self):
        response = self.client.get(
            reverse('wagtailadmin_pages:move_confirm',
                    args=(self.test_page_a.id, self.section_b.id)))
        self.assertEqual(response.status_code, 200)

        response = self.client.get(
            reverse('wagtailadmin_pages:move_confirm',
                    args=(self.test_page_b.id, self.section_a.id)))
        # Duplicate slugs triggers a redirect with an error message.
        self.assertEqual(response.status_code, 302)

        response = self.client.get(reverse('wagtailadmin_home'))
        messages = list(response.context['messages'])
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0].level, message_constants.ERROR)
        # Slug should be in error message.
        self.assertIn("{}".format(self.test_page_b.slug), messages[0].message)

    def test_move_triggers_signals(self):
        # Connect a mock signal handler to pre_page_move and post_page_move signals
        pre_moved_handler = mock.MagicMock()
        post_moved_handler = mock.MagicMock()

        pre_page_move.connect(pre_moved_handler)
        post_page_move.connect(post_moved_handler)

        # Post to view to move page
        try:
            self.client.post(
                reverse('wagtailadmin_pages:move_confirm',
                        args=(self.test_page_a.id, self.section_b.id)))
        finally:
            # Disconnect mock handler to prevent cross-test pollution
            pre_page_move.disconnect(pre_moved_handler)
            post_page_move.disconnect(post_moved_handler)

        # Check that the pre_page_move signal was fired
        self.assertEqual(pre_moved_handler.call_count, 1)
        self.assertTrue(
            pre_moved_handler.called_with(
                sender=self.test_page_a.specific_class,
                instance=self.test_page_a,
                parent_page_before=self.section_a,
                parent_page_after=self.section_b,
                url_path_before='/home/section-a/hello-world/',
                url_path_after='/home/section-b/hello-world/',
            ))

        # Check that the post_page_move signal was fired
        self.assertEqual(post_moved_handler.call_count, 1)
        self.assertTrue(
            post_moved_handler.called_with(
                sender=self.test_page_a.specific_class,
                instance=self.test_page_a,
                parent_page_before=self.section_a,
                parent_page_after=self.section_b,
                url_path_before='/home/section-a/hello-world/',
                url_path_after='/home/section-b/hello-world/',
            ))

    def test_page_set_page_position(self):
        response = self.client.get(
            reverse('wagtailadmin_pages:set_page_position',
                    args=(self.test_page_a.id, )))
        self.assertEqual(response.status_code, 200)

    def test_before_move_page_hook(self):
        def hook_func(request, page, destination):
            self.assertIsInstance(request, HttpRequest)
            self.assertIsInstance(page.specific, SimplePage)
            self.assertIsInstance(destination.specific, SimplePage)

            return HttpResponse("Overridden!")

        with self.register_hook('before_move_page', hook_func):
            response = self.client.get(
                reverse('wagtailadmin_pages:move_confirm',
                        args=(self.test_page_a.id, self.section_b.id)))

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

    def test_before_move_page_hook_post(self):
        def hook_func(request, page, destination):
            self.assertIsInstance(request, HttpRequest)
            self.assertIsInstance(page.specific, SimplePage)
            self.assertIsInstance(destination.specific, SimplePage)

            return HttpResponse("Overridden!")

        with self.register_hook('before_move_page', hook_func):
            response = self.client.post(
                reverse('wagtailadmin_pages:move_confirm',
                        args=(self.test_page_a.id, self.section_b.id)))

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

        # page should not be moved
        self.assertEqual(
            Page.objects.get(id=self.test_page_a.id).get_parent().id,
            self.section_a.id)

    def test_after_move_page_hook(self):
        def hook_func(request, page):
            self.assertIsInstance(request, HttpRequest)
            self.assertIsInstance(page.specific, SimplePage)

            return HttpResponse("Overridden!")

        with self.register_hook('after_move_page', hook_func):
            response = self.client.post(
                reverse('wagtailadmin_pages:move_confirm',
                        args=(self.test_page_a.id, self.section_b.id)))

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

        # page should be moved
        self.assertEqual(
            Page.objects.get(id=self.test_page_a.id).get_parent().id,
            self.section_b.id)
Beispiel #9
0
class TestPageSlugChangedSignal(TestCase, WagtailTestUtils):
    """
    Tests for the `wagtail.core.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)