Beispiel #1
0
    def test_disable_preview_on_revisions_list(self):
        simple_page = SimplePage(title='simple page', content="hello")
        self.root_page.add_child(instance=simple_page)
        simple_page.save_revision(log_action=True)

        # check preview shows up by default
        response = self.client.get(
            reverse('wagtailadmin_pages:history', args=(simple_page.id, )))
        preview_url = reverse('wagtailadmin_pages:revisions_view',
                              args=(simple_page.id,
                                    simple_page.get_latest_revision().id))
        self.assertContains(response, 'Preview')
        self.assertContains(response, preview_url)

        stream_page = StreamPage(title='stream page', body=[('text', 'hello')])
        self.root_page.add_child(instance=stream_page)
        latest_revision = stream_page.save_revision(log_action=True)

        # StreamPage has preview_modes = []
        response = self.client.get(
            reverse('wagtailadmin_pages:history', args=(stream_page.id, )))
        preview_url = reverse('wagtailadmin_pages:revisions_view',
                              args=(stream_page.id, latest_revision.id))
        self.assertNotContains(response, 'Preview')
        self.assertNotContains(response, preview_url)
Beispiel #2
0
class TestRevisionPreviewView(TestCase, WagtailTestUtils):
    def setUp(self):
        # Login.
        self.user = self.login()

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

        # Add child page.
        self.child_page = SimplePage(
            title   = 'Test Page',
            slug    = 'test-page',
        )
        self.root_page.add_child(instance=self.child_page)

        # Create revisions.
        for i in range(20):
            self.child_page.save_revision(
                user                        = self.user,
                submitted_for_moderation    = False,
                approved_go_live_at         = None
            )

    def get_url(self):
        return reverse(
            'wagtailrollbacks:preview_page_version',
            args=(self.child_page.get_latest_revision().id,)
        )

    def get_get_permission_denied(self):
        self.client.logout()

        with self.assertRaises(PermissionDenied):
            self.client.get(self.get_url())

    def test_get(self):
        # Generate the response.
        response = self.client.get(self.get_url())

        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'tests/simple_page.html')
Beispiel #3
0
class TestRevisionPreviewView(TestCase, WagtailTestUtils):
    def setUp(self):
        # Login.
        self.user = self.login()

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

        # Add child page.
        self.child_page = SimplePage(
            title='Test Page',
            slug='test-page',
        )
        self.root_page.add_child(instance=self.child_page)

        # Create revisions.
        for i in range(20):
            self.child_page.save_revision(user=self.user,
                                          submitted_for_moderation=False,
                                          approved_go_live_at=None)

    def get_url(self):
        return reverse('wagtailrollbacks:preview_page_version',
                       args=(self.child_page.get_latest_revision().id, ))

    def get_get_permission_denied(self):
        self.client.logout()

        with self.assertRaises(PermissionDenied):
            self.client.get(self.get_url())

    def test_get(self):
        # Generate the response.
        response = self.client.get(self.get_url())

        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'tests/simple_page.html')
Beispiel #4
0
class TestModerationList(TestCase, WagtailTestUtils):
    """Test moderation list rendered by `wagtailadmin_home` view"""
    def setUp(self):
        # Create a submitter
        submitter = self.create_user(
            username='******',
            email='*****@*****.**',
            password='******',
        )

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

        # Create a page
        self.page = SimplePage(
            title='Wagtail, the powerful CMS for modern websites',
            slug='wagtail',
            content='Fast, elegant, open source',
        )

        self.root_page.add_child(instance=self.page)

        # Submit it for moderation
        self.page.save_revision(user=submitter, submitted_for_moderation=True)

        # Create a revision
        self.revision = self.page.get_latest_revision()

        self.edit_page_url = reverse('wagtailadmin_pages:edit',
                                     args=(self.revision.page.id, ))
        self.preview_page_url = reverse(
            'wagtailadmin_pages:preview_for_moderation',
            args=(self.revision.id, ))

    def login_as_moderator_without_edit(self):
        # Create moderators group without edit permissions
        moderators_group = Group.objects.create(name='Moderators without edit')

        admin_permission = Permission.objects.get(
            content_type__app_label='wagtailadmin', codename='access_admin')

        moderators_group.permissions.add(admin_permission)

        # Create group permissions
        GroupPagePermission.objects.create(
            group=moderators_group,
            page=self.root_page,
            permission_type='publish',
        )

        # Create a moderator without edit permissions
        moderator = self.create_user(username='******',
                                     email='*****@*****.**',
                                     password='******')

        moderator.groups.add(moderators_group)

        self.login(moderator)

    def get(self):
        return self.client.get(reverse('wagtailadmin_home'))

    def test_edit_page(self):
        # Login as moderator
        self.login()

        response = self.get()

        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/home.html')

        # Check response
        self.assertContains(response, self.edit_page_url, count=2)

        # page should contain Approve and Reject forms including a valid CSRF token
        self.assertRegex(
            response.content.decode('utf-8'),
            r'<input type="hidden" name="csrfmiddlewaretoken" value="\w+">')

    def test_preview_for_moderation(self):
        # Login as moderator without edit permissions
        self.login_as_moderator_without_edit()

        response = self.get()

        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/home.html')

        # Check response
        self.assertContains(response, self.preview_page_url, count=2)
        self.assertNotContains(response, self.edit_page_url)
Beispiel #5
0
class TestConfirmPageReversionView(TestCase, WagtailTestUtils):
    def setUp(self):
        # Login.
        self.user = self.login()

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

        # Add child page.
        self.child_page = SimplePage(
            title='Test Page',
            slug='test-page',
        )
        self.root_page.add_child(instance=self.child_page)

        # Create revisions.
        for i in range(20):
            self.child_page.save_revision(user=self.user,
                                          submitted_for_moderation=False,
                                          approved_go_live_at=None)

    def get_url(self):
        return reverse('wagtailrollbacks:confirm_page_reversion',
                       args=(self.child_page.get_latest_revision().id, ))

    def get_get_permission_denied(self):
        self.client.logout()

        with self.assertRaises(PermissionDenied):
            self.client.get(self.get_url())

    def test_page_is_locked(self):
        self.child_page.locked = True
        Page.objects.filter(pk=self.child_page.pk).update(locked=True)

        response = self.client.get(self.get_url())

        self.assertRedirects(
            response,
            reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )))

    def test_get(self):
        response = self.client.get(self.get_url())

        self.assertTemplateUsed(
            response, 'wagtailrollbacks/pages/confirm_reversion.html')

    def test_post_draft(self):
        response = self.client.post(self.get_url(), {'fake': 'data'})

        self.assertRedirects(
            response,
            reverse('wagtailadmin_explore',
                    args=(self.child_page.get_parent().id, )))

    def test_post_publish(self):
        post_data = {'action-publish': True}
        response = self.client.post(self.get_url(), post_data)

        self.assertRedirects(
            response,
            reverse('wagtailadmin_explore',
                    args=(self.child_page.get_parent().id, )))

    def test_post_submit(self):
        post_data = {'action-submit': True}
        response = self.client.post(self.get_url(), post_data)

        self.assertRedirects(
            response,
            reverse('wagtailadmin_explore',
                    args=(self.child_page.get_parent().id, )))
Beispiel #6
0
class TestConfirmPageReversionView(TestCase, WagtailTestUtils):
    def setUp(self):
        # Login.
        self.user = self.login()

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

        # Add child page.
        self.child_page = SimplePage(
            title   = 'Test Page',
            slug    = 'test-page',
        )
        self.root_page.add_child(instance=self.child_page)

        # Create revisions.
        for i in range(20):
            self.child_page.save_revision(
                user                        = self.user,
                submitted_for_moderation    = False,
                approved_go_live_at         = None
            )

    def get_url(self):
        return reverse(
            'wagtailrollbacks:confirm_page_reversion',
            args=(self.child_page.get_latest_revision().id,)
        )

    def get_get_permission_denied(self):
        self.client.logout()

        with self.assertRaises(PermissionDenied):
            self.client.get(self.get_url())

    def test_page_is_locked(self):
        self.child_page.locked = True
        Page.objects.filter(pk=self.child_page.pk).update(locked=True)

        response = self.client.get(self.get_url())

        self.assertRedirects(
            response,
            reverse('wagtailadmin_pages:edit', args=(self.child_page.id,))
        )

    def test_get(self):
        response = self.client.get(self.get_url())

        self.assertTemplateUsed(
            response,
            'wagtailrollbacks/pages/confirm_reversion.html'
        )

    def test_post_draft(self):
        response = self.client.post(self.get_url(), {'fake': 'data'})

        self.assertRedirects(
            response,
            reverse('wagtailadmin_explore', args=(self.child_page.get_parent().id,))
        )

    def test_post_publish(self):
        post_data   = {'action-publish': True}
        response    = self.client.post(self.get_url(), post_data)

        self.assertRedirects(
            response,
            reverse('wagtailadmin_explore', args=(self.child_page.get_parent().id,))
        )

    def test_post_submit(self):
        post_data   = {'action-submit': True}
        response    = self.client.post(self.get_url(), post_data)

        self.assertRedirects(
            response,
            reverse('wagtailadmin_explore', args=(self.child_page.get_parent().id,))
        )
class TestNotificationPreferences(TestCase, WagtailTestUtils):
    def setUp(self):
        # Find root page
        self.root_page = Page.objects.get(id=2)

        # Login
        self.user = self.login()

        # Create two moderator users for testing 'submitted' email
        self.moderator = self.create_superuser('moderator',
                                               '*****@*****.**',
                                               'password')
        self.moderator2 = self.create_superuser('moderator2',
                                                '*****@*****.**',
                                                'password')

        # Create a submitter for testing 'rejected' and 'approved' emails
        self.submitter = self.create_user('submitter', '*****@*****.**',
                                          'password')

        # User profiles for moderator2 and the submitter
        self.moderator2_profile = UserProfile.get_for_user(self.moderator2)
        self.submitter_profile = UserProfile.get_for_user(self.submitter)

        # 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)

        # POST data to edit the page
        self.post_data = {
            'title': "I've been edited!",
            'content': "Some content",
            'slug': 'hello-world',
            'action-submit': "Submit",
        }

    def submit(self):
        return self.client.post(
            reverse('wagtailadmin_pages:edit', args=(self.child_page.id, )),
            self.post_data)

    def silent_submit(self):
        """
        Sets up the child_page as needing moderation, without making a request
        """
        self.child_page.save_revision(user=self.submitter,
                                      submitted_for_moderation=True)
        self.revision = self.child_page.get_latest_revision()

    def approve(self):
        return self.client.post(
            reverse('wagtailadmin_pages:approve_moderation',
                    args=(self.revision.id, )))

    def reject(self):
        return self.client.post(
            reverse('wagtailadmin_pages:reject_moderation',
                    args=(self.revision.id, )))

    def test_vanilla_profile(self):
        # Check that the vanilla profile has rejected notifications on
        self.assertEqual(self.submitter_profile.rejected_notifications, True)

        # Check that the vanilla profile has approved notifications on
        self.assertEqual(self.submitter_profile.approved_notifications, True)

    def test_approved_notifications(self):
        # Set up the page version
        self.silent_submit()
        # Approve
        self.approve()

        # Submitter must receive an approved email
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].to, ['*****@*****.**'])
        self.assertEqual(mail.outbox[0].subject,
                         'The page "Hello world!" has been approved')

    def test_approved_notifications_preferences_respected(self):
        # Submitter doesn't want 'approved' emails
        self.submitter_profile.approved_notifications = False
        self.submitter_profile.save()

        # Set up the page version
        self.silent_submit()
        # Approve
        self.approve()

        # No email to send
        self.assertEqual(len(mail.outbox), 0)

    def test_rejected_notifications(self):
        # Set up the page version
        self.silent_submit()
        # Reject
        self.reject()

        # Submitter must receive a rejected email
        self.assertEqual(len(mail.outbox), 1)
        self.assertEqual(mail.outbox[0].to, ['*****@*****.**'])
        self.assertEqual(mail.outbox[0].subject,
                         'The page "Hello world!" has been rejected')

    def test_rejected_notification_preferences_respected(self):
        # Submitter doesn't want 'rejected' emails
        self.submitter_profile.rejected_notifications = False
        self.submitter_profile.save()

        # Set up the page version
        self.silent_submit()
        # Reject
        self.reject()

        # No email to send
        self.assertEqual(len(mail.outbox), 0)

    @override_settings(WAGTAILADMIN_NOTIFICATION_INCLUDE_SUPERUSERS=False)
    def test_disable_superuser_notification(self):
        # Add one of the superusers to the moderator group
        self.moderator.groups.add(Group.objects.get(name='Moderators'))

        response = self.submit()

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

        # Check that the non-moderator superuser is not being notified
        expected_emails = 1
        self.assertEqual(len(mail.outbox), expected_emails)
        # Use chain as the 'to' field is a list of recipients
        email_to = list(chain.from_iterable([m.to for m in mail.outbox]))
        self.assertIn(self.moderator.email, email_to)
        self.assertNotIn(self.moderator2.email, email_to)

    @mock.patch.object(EmailMultiAlternatives,
                       'send',
                       side_effect=IOError('Server down'))
    def test_email_send_error(self, mock_fn):
        logging.disable(logging.CRITICAL)
        # Approve
        self.silent_submit()
        response = self.approve()
        logging.disable(logging.NOTSET)

        # An email that fails to send should return a message rather than crash the page
        self.assertEqual(response.status_code, 302)
        response = self.client.get(reverse('wagtailadmin_home'))

        # There should be one "approved" message and one "failed to send notifications"
        messages = list(response.context['messages'])
        self.assertEqual(len(messages), 2)
        self.assertEqual(messages[0].level, message_constants.SUCCESS)
        self.assertEqual(messages[1].level, message_constants.ERROR)

    def test_email_headers(self):
        # Submit
        self.submit()

        msg_headers = set(mail.outbox[0].message().items())
        headers = {('Auto-Submitted', 'auto-generated')}
        self.assertTrue(
            headers.issubset(msg_headers),
            msg='Message is missing the Auto-Submitted header.',
        )
class TestApproveRejectModeration(TestCase, WagtailTestUtils):
    def setUp(self):
        self.submitter = self.create_superuser(
            username='******',
            email='*****@*****.**',
            password='******',
        )

        self.user = self.login()

        # Create a page and submit it for moderation
        root_page = Page.objects.get(id=2)
        self.page = SimplePage(
            title="Hello world!",
            slug='hello-world',
            content="hello",
            live=False,
            has_unpublished_changes=True,
        )
        root_page.add_child(instance=self.page)

        self.page.save_revision(user=self.submitter,
                                submitted_for_moderation=True)
        self.revision = self.page.get_latest_revision()

    def test_approve_moderation_view(self):
        """
        This posts to the approve moderation view and checks that the page was approved
        """
        # Connect a mock signal handler to page_published signal
        mock_handler = mock.MagicMock()
        page_published.connect(mock_handler)

        # Post
        response = self.client.post(
            reverse('wagtailadmin_pages:approve_moderation',
                    args=(self.revision.id, )))

        # Check that the user was redirected to the dashboard
        self.assertRedirects(response, reverse('wagtailadmin_home'))

        page = Page.objects.get(id=self.page.id)
        # Page must be live
        self.assertTrue(page.live,
                        "Approving moderation failed to set live=True")
        # Page should now have no unpublished changes
        self.assertFalse(
            page.has_unpublished_changes,
            "Approving moderation failed to set has_unpublished_changes=False")

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

        self.assertEqual(mock_call['sender'], self.page.specific_class)
        self.assertEqual(mock_call['instance'], self.page)
        self.assertIsInstance(mock_call['instance'], self.page.specific_class)

    def test_approve_moderation_when_later_revision_exists(self):
        self.page.title = "Goodbye world!"
        self.page.save_revision(user=self.submitter,
                                submitted_for_moderation=False)

        response = self.client.post(
            reverse('wagtailadmin_pages:approve_moderation',
                    args=(self.revision.id, )))

        # Check that the user was redirected to the dashboard
        self.assertRedirects(response, reverse('wagtailadmin_home'))

        page = Page.objects.get(id=self.page.id)
        # Page must be live
        self.assertTrue(page.live,
                        "Approving moderation failed to set live=True")
        # Page content should be the submitted version, not the published one
        self.assertEqual(page.title, "Hello world!")
        # Page should still have unpublished changes
        self.assertTrue(
            page.has_unpublished_changes,
            "has_unpublished_changes incorrectly cleared on approve_moderation when a later revision exists"
        )

    def test_approve_moderation_view_bad_revision_id(self):
        """
        This tests that the approve moderation view handles invalid revision ids correctly
        """
        # Post
        response = self.client.post(
            reverse('wagtailadmin_pages:approve_moderation', args=(12345, )))

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

    def test_approve_moderation_view_bad_permissions(self):
        """
        This tests that the approve moderation view doesn't allow users without moderation permissions
        """
        # 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()

        # Post
        response = self.client.post(
            reverse('wagtailadmin_pages:approve_moderation',
                    args=(self.revision.id, )))

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

    def test_reject_moderation_view(self):
        """
        This posts to the reject moderation view and checks that the page was rejected
        """
        # Post
        response = self.client.post(
            reverse('wagtailadmin_pages:reject_moderation',
                    args=(self.revision.id, )))

        # Check that the user was redirected to the dashboard
        self.assertRedirects(response, reverse('wagtailadmin_home'))

        # Page must not be live
        self.assertFalse(Page.objects.get(id=self.page.id).live)

        # Revision must no longer be submitted for moderation
        self.assertFalse(
            PageRevision.objects.get(
                id=self.revision.id).submitted_for_moderation)

    def test_reject_moderation_view_bad_revision_id(self):
        """
        This tests that the reject moderation view handles invalid revision ids correctly
        """
        # Post
        response = self.client.post(
            reverse('wagtailadmin_pages:reject_moderation', args=(12345, )))

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

    def test_reject_moderation_view_bad_permissions(self):
        """
        This tests that the reject moderation view doesn't allow users without moderation permissions
        """
        # 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()

        # Post
        response = self.client.post(
            reverse('wagtailadmin_pages:reject_moderation',
                    args=(self.revision.id, )))

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

    def test_preview_for_moderation(self):
        response = self.client.get(
            reverse('wagtailadmin_pages:preview_for_moderation',
                    args=(self.revision.id, )))

        # Check response
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'tests/simple_page.html')
        self.assertContains(response, "Hello world!")
class TestModerationList(TestCase, WagtailTestUtils):
    """Test moderation list rendered by `wagtailadmin_home` view"""

    def setUp(self):
        # Create a submitter
        submitter = get_user_model().objects.create_user(
            username='******',
            email='*****@*****.**',
            password='******',
        )

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

        # Create a page
        self.page = SimplePage(
            title='Wagtail, the powerful CMS for modern websites',
            slug='wagtail',
            content='Fast, elegant, open source',
        )

        self.root_page.add_child(instance=self.page)

        # Submit it for moderation
        self.page.save_revision(user=submitter, submitted_for_moderation=True)

        # Create a revision
        self.revision = self.page.get_latest_revision()

        self.edit_page_url = reverse('wagtailadmin_pages:edit', args=(self.revision.page.id, ))
        self.preview_page_url = reverse('wagtailadmin_pages:preview_for_moderation', args=(self.revision.id, ))

    def login_as_moderator_without_edit(self):
        # Create moderators group without edit permissions
        moderators_group = Group.objects.create(name='Moderators without edit')

        admin_permission = Permission.objects.get(
            content_type__app_label='wagtailadmin',
            codename='access_admin'
        )

        moderators_group.permissions.add(admin_permission)

        # Create group permissions
        GroupPagePermission.objects.create(
            group=moderators_group,
            page=self.root_page,
            permission_type='publish',
        )

        # Create a moderator without edit permissions
        moderator = get_user_model().objects.create_user(
            username='******',
            email='*****@*****.**',
            password='******'
        )

        moderator.groups.add(moderators_group)

        self.login(moderator)

    def get(self):
        return self.client.get(reverse('wagtailadmin_home'))

    def test_edit_page(self):
        # Login as moderator
        self.login()

        response = self.get()

        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/home.html')

        # Check response
        self.assertContains(response, self.edit_page_url, count=2)

    def test_preview_for_moderation(self):
        # Login as moderator without edit permissions
        self.login_as_moderator_without_edit()

        response = self.get()

        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'wagtailadmin/home.html')

        # Check response
        self.assertContains(response, self.preview_page_url, count=2)
        self.assertNotContains(response, self.edit_page_url)