def test_compare_imagechooserblock(self): image_model = get_image_model() test_image_1 = image_model.objects.create( title="Test image 1", file=get_test_image_file(), ) test_image_2 = image_model.objects.create( title="Test image 2", file=get_test_image_file(), ) field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('image', test_image_1, '1'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('image', test_image_2, '1'), ])), ) result = comparison.htmldiff() self.assertIn('<div class="preview-image deletion">', result) self.assertIn('alt="Test image 1"', result) self.assertIn('<div class="preview-image addition">', result) self.assertIn('alt="Test image 2"', result) self.assertIsInstance(result, SafeText) self.assertTrue(comparison.has_changed())
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)
def test_compare_structblock(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('product', { 'name': 'a packet of rolos', 'price': '75p' }, '1'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('product', { 'name': 'a packet of rolos', 'price': '85p' }, '1'), ])), ) expected = """ <div class="comparison__child-object"><dl> <dt>Name</dt> <dd>a packet of rolos</dd> <dt>Price</dt> <dd><span class="deletion">75p</span><span class="addition">85p</span></dd> </dl></div> """ self.assertHTMLEqual(comparison.htmldiff(), expected) self.assertIsInstance(comparison.htmldiff(), SafeString) self.assertTrue(comparison.has_changed())
def test_compare_nested_streamblock_uses_comparison_class(self): field = StreamPage._meta.get_field('body') stream_block = field.stream_block.child_blocks['books'] comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('books', StreamValue(stream_block, [('title', 'The Old Man and the Sea', '10')]), '1'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('books', StreamValue(stream_block, [('author', 'Oscar Wilde', '11')]), '1'), ])), ) expected = """ <div class="comparison__child-object"> <div class="comparison__child-object addition">Oscar Wilde</div>\n <div class="comparison__child-object deletion">The Old Man and the Sea</div> </div> """ self.assertHTMLEqual(comparison.htmldiff(), expected) self.assertIsInstance(comparison.htmldiff(), SafeString) self.assertTrue(comparison.has_changed())
def disable_preview_in_moderation_list(self): stream_page = StreamPage(title='stream page', body=[('text', 'hello')]) self.root_page.add_child(instance=stream_page) latest_revision = stream_page.save_revision(user=self.user, submitted_for_moderation=True) response = self.client.get(reverse('wagtailadmin_home')) preview_url = reverse('wagtailadmin_pages:preview_for_moderation', args=(latest_revision.id,)) self.assertNotContains(response, '<li class="preview">') self.assertNotContains(response, 'data-action="%s"' % preview_url)
def setUp(self): self.root = Page.objects.get(slug='cfgov') self.page = StreamPage(title="Test Page", slug="testpage") save_new_page(self.page, self.root) set_stream_data(self.page, 'body', [ {'type': 'text', 'value': 'some text'} ]) self.revision = self.page.save_revision() self.page.save()
def test_htmldiff_raw_html_escapes_value_on_change(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('raw_html', "Original<i>ish</i> content", '1'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('raw_html', '<script type="text/javascript">doSomethingBad();</script>', '1'), ])), ) self.assertEqual(comparison.htmldiff(), '<div class="comparison__child-object"><span class="deletion">Original<i>ish</i> content</span><span class="addition"><script type="text/javascript">doSomethingBad();</script></span></div>') self.assertIsInstance(comparison.htmldiff(), SafeString)
def test_htmldiff_richtext_strips_tags_on_change(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('rich_text', "I <b>really</b> like Wagtail <3", '1'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('rich_text', 'I <b>really</b> like evil code >_< <script type="text/javascript">doSomethingBad();</script>', '1'), ])), ) self.assertEqual(comparison.htmldiff(), '<div class="comparison__child-object">I really like <span class="deletion">Wagtail <3</span><span class="addition">evil code >_< doSomethingBad();</span></div>') self.assertIsInstance(comparison.htmldiff(), SafeString)
def test_htmldiff_escapes_value_richtext(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('rich_text', "Original content"), ])), StreamPage(body=StreamValue(field.stream_block, [ ('rich_text', '<script type="text/javascript">doSomethingBad();</script>'), ])), ) self.assertEqual(comparison.htmldiff(), '<span class="deletion">Original content</span><span class="addition">doSomethingBad();</span>') self.assertIsInstance(comparison.htmldiff(), SafeText)
def make_stream_page(self, body): stream_page = StreamPage( title='stream page', slug='stream-page', body=body ) return self.homepage.add_child(instance=stream_page)
def test_htmldiff_richtext_strips_tags_on_deletion(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('rich_text', "Original <em>and unchanged</em> content", '1'), ('rich_text', 'I <b>really</b> like evil code >_< <script type="text/javascript">doSomethingBad();</script>', '2'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('rich_text', "Original <em>and unchanged</em> content", '1'), ])), ) self.assertEqual(comparison.htmldiff(), '<div class="comparison__child-object">Original and unchanged content</div>\n<div class="comparison__child-object deletion">I really like evil code >_< doSomethingBad();</div>') self.assertIsInstance(comparison.htmldiff(), SafeString)
def test_htmldiff_escapes_value_on_deletion(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('text', "Original <em>and unchanged</em> content", '1'), ('text', '<script type="text/javascript">doSomethingBad();</script>', '2'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('text', "Original <em>and unchanged</em> content", '1'), ])), ) self.assertEqual(comparison.htmldiff(), '<div class="comparison__child-object">Original <em>and unchanged</em> content</div>\n<div class="comparison__child-object deletion"><script type="text/javascript">doSomethingBad();</script></div>') self.assertIsInstance(comparison.htmldiff(), SafeString)
def test_has_changed_richtext(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('rich_text', "<b>Original</b> content"), ])), StreamPage(body=StreamValue(field.stream_block, [ ('rich_text', "Modified <i>content</i>"), ])), ) self.assertEqual(comparison.htmldiff(), '<span class="deletion">Original</span><span class="addition">Modified</span> content') self.assertIsInstance(comparison.htmldiff(), SafeText) self.assertTrue(comparison.has_changed())
def test_has_changed(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('text', "Original content", '1'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('text', "Modified content", '1'), ])), ) self.assertEqual(comparison.htmldiff(), '<div class="comparison__child-object"><span class="deletion">Original</span><span class="addition">Modified</span> content</div>') self.assertIsInstance(comparison.htmldiff(), SafeText) self.assertTrue(comparison.has_changed())
def _create_streampage(self): stream_page = StreamPage( title="stream page", slug="stream-page", body='[{"type": "text", "value": "foo"}]', ) self.root_page.add_child(instance=stream_page)
def test_disable_preview_on_edit(self): simple_page = SimplePage(title='simple page', content="hello") self.root_page.add_child(instance=simple_page) # preview button is available by default response = self.client.get( reverse('wagtailadmin_pages:edit', args=(simple_page.id, ))) self.assertEqual(response.status_code, 200) preview_url = reverse('wagtailadmin_pages:preview_on_edit', args=(simple_page.id, )) self.assertContains(response, '<li class="preview">') self.assertContains(response, 'data-action="%s"' % preview_url) stream_page = StreamPage(title='stream page', body=[('text', 'hello')]) self.root_page.add_child(instance=stream_page) # StreamPage has preview_modes = [] response = self.client.get( reverse('wagtailadmin_pages:edit', args=(stream_page.id, ))) self.assertEqual(response.status_code, 200) preview_url = reverse('wagtailadmin_pages:preview_on_edit', args=(stream_page.id, )) self.assertNotContains(response, '<li class="preview">') self.assertNotContains(response, 'data-action="%s"' % preview_url)
def test_add_block(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('text', "Content", '1'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('text', "Content", '1'), ('text', "New Content", '2'), ])), ) self.assertEqual(comparison.htmldiff(), '<div class="comparison__child-object">Content</div>\n<div class="comparison__child-object addition">New Content</div>') self.assertIsInstance(comparison.htmldiff(), SafeText) self.assertTrue(comparison.has_changed())
def test_hasnt_changed(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('text', "Content"), ])), StreamPage(body=StreamValue(field.stream_block, [ ('text', "Content"), ])), ) self.assertTrue(comparison.is_field) self.assertFalse(comparison.is_child_relation) self.assertEqual(comparison.field_label(), "Body") self.assertEqual(comparison.htmldiff(), 'Content') self.assertIsInstance(comparison.htmldiff(), SafeText) self.assertFalse(comparison.has_changed())
def test_edit_block(self): field = StreamPage._meta.get_field('body') comparison = self.comparison_class( field, StreamPage(body=StreamValue(field.stream_block, [ ('text', "Content", '1'), ('text', "Content Foo", '2'), ('text', "Content Bar", '3'), ])), StreamPage(body=StreamValue(field.stream_block, [ ('text', "Content", '1'), ('text', "Content Baz", '2'), ('text', "Content Bar", '3'), ])), ) self.assertEqual(comparison.htmldiff(), '<div class="comparison__child-object">Content</div>\n<div class="comparison__child-object">Content <span class="deletion">Foo</span><span class="addition">Baz</span></div>\n<div class="comparison__child-object">Content Bar</div>') self.assertIsInstance(comparison.htmldiff(), SafeText) self.assertTrue(comparison.has_changed())
def setUp(self): self.root_page = Page.objects.get(id=1) # Add a site so the URLs render correctly Site.objects.create(is_default_site=True, root_page=self.root_page) # Create a large piece of body text body = '[' + ','.join( ['{"type": "text", "value": "%s"}' % ('foo' * 2000)] * 100) + ']' # Create 50 simple pages with long content fields for i in range(50): self.root_page.add_child(instance=StreamPage( title="Page {}".format(i + 1), slug=str(i + 1), body=body, )) self.login()
def test_deferred_specific_query(self): # Tests the "defer" keyword argument, which defers all specific fields root = Page.objects.get(url_path='/home/') stream_page = StreamPage( title='stream page', slug='stream-page', body='[{"type": "text", "value": "foo"}]', ) root.add_child(instance=stream_page) with self.assertNumQueries(0): # The query should be lazy. qs = root.get_descendants().specific(defer=True) with self.assertNumQueries(5): # This still performs 5 queries (one for each specific class) # even though we're only pulling in fields from the base Page # model. # TODO: Find a way to make this perform a single query pages = list(qs) self.assertIsInstance(pages, list) self.assertEqual(len(pages), 8) for page in pages: # An instance of the specific page type should be returned, # not wagtailcore.Page. content_type = page.content_type model = content_type.model_class() self.assertIsInstance(page, model) # The page should already be the specific type, so this should not # need another database query. with self.assertNumQueries(0): self.assertIs(page, page.specific) # Unlike before, the content fields should be now deferred. This means # that accessing them will generate a new query. with self.assertNumQueries(2): # <EventPage: Christmas> pages[1].body # <StreamPage: stream page> pages[-1].body
def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) # Add child page self.child_page = SimplePage( title="Hello world!", slug="hello-world", content="hello", ) self.root_page.add_child(instance=self.child_page) # Add stream page (which has empty preview_modes, and so doesn't allow viewing draft) self.stream_page = StreamPage(title="stream page", body=[("text", "hello")]) self.root_page.add_child(instance=self.stream_page) # create user with admin access (but not draft_view access) user = self.create_user(username="******", password="******") user.user_permissions.add( Permission.objects.get(content_type__app_label="wagtailadmin", codename="access_admin"))
def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) # Add child page self.child_page = SimplePage( title="Hello world!", slug="hello-world", content="hello", ) self.root_page.add_child(instance=self.child_page) # Add stream page (which has empty preview_modes, and so doesn't allow viewing draft) self.stream_page = StreamPage(title='stream page', body=[('text', 'hello')]) self.root_page.add_child(instance=self.stream_page) # create user with admin access (but not draft_view access) user = get_user_model().objects.create_user(username='******', email='*****@*****.**', password='******') user.user_permissions.add( Permission.objects.get(content_type__app_label='wagtailadmin', codename='access_admin'))
class MigrationsUtilTestCase(TestCase): def setUp(self): self.root = Page.objects.get(slug='cfgov') self.page = StreamPage(title="Test Page", slug="testpage") save_new_page(self.page, self.root) set_stream_data(self.page, 'body', [{ 'type': 'text', 'value': 'some text' }]) self.revision = self.page.save_revision() self.page.save() def test_is_page_page(self): """ Test that a page is verifably a page """ self.assertTrue(is_page(self.page)) def test_is_page_revision(self): """ Test that a revision is verifiably not a page """ self.assertFalse(is_page(self.revision)) def test_get_stream_data_page(self): """ Test that get_stream_data fetches the stream_data correctly from a page object. """ stream_data = get_stream_data(self.page, 'body') self.assertEqual(stream_data[0]['type'], 'text') self.assertEqual(stream_data[0]['value'], 'some text') def test_get_stream_data_revision(self): """ Test that get_stream_data fetches the stream_data correctly from a revision object. """ stream_data = get_stream_data(self.revision.as_page_object(), 'body') self.assertEqual(stream_data[0]['type'], 'text') self.assertEqual(stream_data[0]['value'], 'some text') def test_set_stream_data_page(self): """ Test that set_stream_data correctly sets stream data for a given page and saves the page. """ new_stream_data = [{'type': 'text', 'value': 'new text'}] set_stream_data(self.page, 'body', new_stream_data) self.assertEqual(self.page.body.stream_data[0]['value'], 'new text') def test_set_stream_data_revision(self): """ Test that set_stream_data correctly sets stream data for a given revision and saves the page. """ new_stream_data = [{'type': 'text', 'value': 'new text'}] set_stream_data(self.revision, 'body', new_stream_data) self.assertEqual( self.revision.as_page_object().body.stream_data[0]['value'], 'new text') def test_set_stream_data_page_without_committing(self): """ Test that set_stream_data correctly sets stream data for a given page and saves the page. """ self.page.save = mock.Mock() new_stream_data = [{'type': 'text', 'value': 'new text'}] set_stream_data(self.page, 'body', new_stream_data, commit=False) self.assertEqual(self.page.save.mock_calls, []) def test_migrate_stream_field_page(self): """ Test that the migrate_stream_field function correctly gets old data, calls the mapper function, and stores new data based on the mapper results. """ # Mock the field mapper migration function. We'll inspect the # call to this and ensure the return value makes it to # set_stream_data. mapper = mock.Mock(return_value='new text') migrate_stream_field(self.page, 'body', 'text', mapper) mapper.assert_called_with(self.page, 'some text') self.assertEqual(self.page.body.stream_data[0]['value'], 'new text') def test_migrate_stream_field_revision(self): """ Test that the migrate_stream_field function correctly gets old data, calls the mapper function, and stores new data based on the mapper results. """ # Mock the field mapper migration function. We'll inspect the # call to this and ensure the return value makes it to # set_stream_data. mapper = mock.Mock(return_value='new text') migrate_stream_field(self.revision, 'body', 'text', mapper) mapper.assert_called_with(self.revision, 'some text') self.assertEqual( self.revision.as_page_object().body.stream_data[0]['value'], 'new text') @mock.patch('v1.util.migrations.set_stream_data') def test_migrate_stream_field_not_migrated(self, mock_set_stream_data): """ Test that the migrate_stream_field function correctly ignores a field that does not have the correct type and shouldn't be migrated. """ mapper = mock.Mock() migrate_stream_field(self.page, 'body', 'other_type', mapper) # The mapper should not be called mapper.assert_not_called() # set_stream_data should not be called mock_set_stream_data.assert_not_called() @mock.patch('v1.util.migrations.migrate_stream_field') def test_migrate_page_types_and_fields(self, mock_migrate_stream_field): """ Test that the migrate_page_types_and_fields function correctly calls the migrate_stream_field function with the appropriate values from the list of page types and fields. """ mapper = mock.Mock() page_types_and_fields = [ ('tests', 'StreamPage', 'body', 'text'), ] migrate_page_types_and_fields(apps, page_types_and_fields, mapper) # Check that migrate_stream_field was correct called with the page mock_migrate_stream_field.assert_any_call(self.page, 'body', 'text', mapper) # Check that the revision lookup happened correctly and that the # revision stream field was correctly migrated. mock_migrate_stream_field.assert_any_call(self.revision, 'body', 'text', mapper)
class MigrationsUtilTestCase(TestCase): def setUp(self): self.root = Page.objects.get(slug='cfgov') self.page = StreamPage(title="Test Page", slug="testpage") save_new_page(self.page, self.root) set_stream_data(self.page, 'body', [ {'type': 'text', 'value': 'some text'} ]) self.revision = self.page.save_revision() self.page.save() def test_is_page_page(self): """ Test that a page is verifably a page """ self.assertTrue(is_page(self.page)) def test_is_page_revision(self): """ Test that a revision is verifiably not a page """ self.assertFalse(is_page(self.revision)) def test_get_stream_data_page(self): """ Test that get_stream_data fetches the stream_data correctly from a page object. """ stream_data = get_stream_data(self.page, 'body') self.assertEqual(stream_data[0]['type'], 'text') self.assertEqual(stream_data[0]['value'], 'some text') def test_get_stream_data_revision(self): """ Test that get_stream_data fetches the stream_data correctly from a revision object. """ stream_data = get_stream_data(self.revision, 'body') self.assertEqual(stream_data[0]['type'], 'text') self.assertEqual(stream_data[0]['value'], 'some text') def test_get_stream_data_revision_no_field(self): """ Test that get an empty list for fields that don't exist on revisions """ stream_data = get_stream_data(self.revision, 'notbody') self.assertEqual(stream_data, []) def test_set_stream_data_page(self): """ Test that set_stream_data correctly sets stream data for a given page and saves the page. """ new_stream_data = [{'type': 'text', 'value': 'new text'}] set_stream_data(self.page, 'body', new_stream_data) self.assertEqual(self.page.body.stream_data[0]['value'], 'new text') def test_set_stream_data_revision(self): """ Test that set_stream_data correctly sets stream data for a given revision and saves the page. """ new_stream_data = [{'type': 'text', 'value': 'new text'}] set_stream_data(self.revision, 'body', new_stream_data) self.assertEqual( self.revision.as_page_object().body.stream_data[0]['value'], 'new text') def test_set_stream_data_page_without_committing(self): """ Test that set_stream_data correctly sets stream data for a given page and saves the page. """ self.page.save = mock.Mock() new_stream_data = [{'type': 'text', 'value': 'new text'}] set_stream_data(self.page, 'body', new_stream_data, commit=False) self.assertEqual(self.page.save.mock_calls, []) def test_migrate_stream_data_recursion(self): mapper = mock.Mock(return_value='new text') stream_data = [ { 'type': 'not-migratory', 'value': [ { 'type': 'migratory', 'value': 'old text', }, ] }, { 'type': 'not-migratory', 'value': [] }, ] result, migrated = migrate_stream_data( self.page, ['not-migratory', 'migratory'], stream_data, mapper ) self.assertTrue(migrated) self.assertEquals(result[0]['value'][0]['value'], 'new text') def test_migrate_stream_data_flat(self): mapper = mock.Mock(return_value='new text') stream_data = [ { 'type': 'not-migratory', 'value': 'old text', }, { 'type': 'migratory', 'value': 'old text', }, ] result, migrated = migrate_stream_data( self.page, ['migratory', ], stream_data, mapper ) self.assertTrue(migrated) self.assertEquals(result[1]['value'], 'new text') def test_migrate_stream_data_empty_block_path(self): mapper = mock.Mock(return_value='new text') result, migrated = migrate_stream_data( self.page, [], {}, mapper ) self.assertFalse(migrated) def test_migrate_stream_field_page(self): """ Test that the migrate_stream_field function correctly gets old data, calls the mapper function, and stores new data based on the mapper results. """ # Mock the field mapper migration function. We'll inspect the # call to this and ensure the return value makes it to # set_stream_data. mapper = mock.Mock(return_value='new text') migrate_stream_field(self.page, 'body', 'text', mapper) mapper.assert_called_with(self.page, 'some text') self.assertEqual(self.page.body.stream_data[0]['value'], 'new text') def test_migrate_stream_field_revision(self): """ Test that the migrate_stream_field function correctly gets old data, calls the mapper function, and stores new data based on the mapper results. """ # Mock the field mapper migration function. We'll inspect the # call to this and ensure the return value makes it to # set_stream_data. mapper = mock.Mock(return_value='new text') migrate_stream_field(self.revision, 'body', 'text', mapper) mapper.assert_called_with(self.revision, 'some text') self.assertEqual( self.revision.as_page_object().body.stream_data[0]['value'], 'new text') @mock.patch('v1.util.migrations.set_stream_data') def test_migrate_stream_field_not_migrated(self, mock_set_stream_data): """ Test that the migrate_stream_field function correctly ignores a field that does not have the correct type and shouldn't be migrated. """ mapper = mock.Mock() migrate_stream_field(self.page, 'body', 'other_type', mapper) # The mapper should not be called mapper.assert_not_called() # set_stream_data should not be called mock_set_stream_data.assert_not_called() @mock.patch('v1.util.migrations.migrate_stream_field') def test_migrate_page_types_and_fields(self, mock_migrate_stream_field): """ Test that the migrate_page_types_and_fields function correctly calls the migrate_stream_field function with the appropriate values from the list of page types and fields. """ mapper = mock.Mock() page_types_and_fields = [ ('tests', 'StreamPage', 'body', 'text'), ] migrate_page_types_and_fields(apps, page_types_and_fields, mapper) # Check that migrate_stream_field was correct called with the page mock_migrate_stream_field.assert_any_call(self.page, 'body', 'text', mapper) # Check that the revision lookup happened correctly and that the # revision stream field was correctly migrated. mock_migrate_stream_field.assert_any_call(self.revision, 'body', 'text', mapper)