def test_create_complex_page_with_m2m(self): simple_page_1 = SimplePage( title='Test Page', int_field=42, ) simple_page_2 = SimplePage( title='Another Test Page', int_field=27, ) home = Page.objects.get(slug='home') home.add_child(instance=simple_page_1) home.add_child(instance=simple_page_2) csv_data = StringIO( 'id,parent,title,m2m\r\n' f',2,Page with M2M,"{simple_page_1.pk},{simple_page_2.pk}"\r\n') successes, errors = import_pages(csv_data, M2MPage) self.assertEqual(successes, ['Created page Page with M2M with id 5']) self.assertEqual(errors, []) page = M2MPage.objects.latest('id') self.assertEqual(page.get_parent().id, home.pk) self.assertEqual(page.title, 'Page with M2M') self.assertIsNone(page.fk) self.assertQuerysetEqual( page.m2m.order_by('id'), ['<SimplePage: Test Page>', '<SimplePage: Another Test Page>']) # page is in draft because live was not specified self.assertIs(page.live, False)
def test_create_error_missing_parent_field(self): csv_data = StringIO('id,title,int_field\r\n' ',Orphan,42\r\n') successes, errors = import_pages(csv_data, SimplePage) self.assertEqual(successes, []) self.assertEqual([repr(e) for e in errors], [ "Error(Errors processing row number 1: {'parent': [ValidationError(['Need a parent when creating a new page'])]})" ])
def test_update_simple_page(self): page = SimplePage( title='Test Page', slug='test-page', seo_title='Not good SEO', search_description='This won\'t change', bool_field=True, char_field='Blag', int_field=42, rich_text_field='<p>Read Understand by Ted Chiang</p>') home = Page.objects.get(slug='home') home.add_child(instance=page) csv_data = StringIO( 'id,title,seo_title,int_field,rich_text_field\r\n' f'3,A New Title,Now THIS is SEO,27,<p>Anything by Ted Chiang really</p>\r\n' ) successes, errors = import_pages(csv_data, SimplePage) self.assertEqual(successes, ['Updated page A New Title with id 3'], f'Errors: {errors}') self.assertEqual(errors, []) page = SimplePage.objects.get(pk=3) # listed fields have been updated self.assertEqual(page.title, 'A New Title') self.assertEqual(page.seo_title, 'Now THIS is SEO') self.assertEqual(page.int_field, 27) self.assertEqual(page.rich_text_field, '<p>Anything by Ted Chiang really</p>') # unlisted fields are not changed self.assertEqual(page.slug, 'test-page') self.assertEqual(page.search_description, 'This won\'t change') self.assertIs(page.bool_field, True) self.assertEqual(page.char_field, 'Blag')
def test_create_error_unrecognized_field(self): csv_data = StringIO('id,title,int_field,wrong_field\r\n' ',Orphan,42,blah\r\n') successes, errors = import_pages(csv_data, SimplePage) self.assertEqual(successes, []) self.assertEqual([repr(e) for e in errors], [ "Error(Error in CSV header: Unknown field(s) (wrong_field) specified for SimplePage)" ])
def test_create_error_type_field_doesnt_match_page_model(self): csv_data = StringIO('id,content_type,parent,title,int_field\r\n' f',tests.m2mpage,2,Wrong type,42\r\n') successes, errors = import_pages(csv_data, SimplePage) self.assertEqual(successes, []) self.assertEqual([repr(e) for e in errors], [ "Error(Errors processing row number 1: {'content_type': [ValidationError(['Expected tests.simplepage, was tests.m2mpage'])]})" ])
def test_create_cannot_set_excluded_fields(self): csv_data = StringIO( 'id,parent,title,content_type,depth,numchild,page_ptr,path,url_path,int_field\r\n' ',2,Test page,42,3,7,2,000100010001,/home/wrong-path,42\r\n') successes, errors = import_pages(csv_data, SimplePage) self.assertEqual(successes, []) self.assertEqual([repr(e) for e in errors], [ "Error(Error in CSV header: Unrecognized fields: ['depth', 'numchild', 'page_ptr', 'path', 'url_path'])" ])
def test_wagtail_model_validation_errors(self): """Test validation errors generated by Page models clean() and full_clean()""" csv_data = StringIO('id,parent,title,slug\r\n' f',1,Another Home,home\r\n') successes, errors = import_pages(csv_data, Page) self.assertEqual(successes, []) self.assertEqual([repr(e) for e in errors], [ "Error(Errors processing row number 1: {'slug': ['This slug is already in use']})" ])
def test_update_wont_move_pages(self): page = Page(title='Test Page', ) home = Page.objects.get(slug='home') home.add_child(instance=page) csv_data = StringIO('id,parent\r\n' f'3,1\r\n') successes, errors = import_pages(csv_data, Page) self.assertEqual(successes, []) self.assertEqual([repr(e) for e in errors], [ "Error(Errors processing row number 1: {'parent': [ValidationError(['Cannot change parent page, moving pages is not yet supported.'])]})" ])
def test_create_simple_page_unicode_text(self): csv_data = StringIO( 'id,parent,title,seo_title,int_field,rich_text_field\r\n' f',2,日本語,漢語,42,<p> </p>\r\n') successes, errors = import_pages(csv_data, SimplePage) self.assertEqual(successes, ['Created page 日本語 with id 3'], f'Errors: {errors}') self.assertEqual(errors, []) page = SimplePage.objects.latest('id') self.assertEqual(page.get_parent().id, 2) self.assertEqual(page.title, '日本語') self.assertEqual(page.seo_title, '漢語') self.assertEqual(page.rich_text_field, '<p> </p>')
def test_create_simple_page_all_fields(self): """Test a CSV with all possible fields. Check that non-editable fields are ignored. """ csv_data = StringIO( 'id,content_type,parent,title,slug,full_url,live,bool_field,char_field,draft_title,expire_at,expired,first_published_at,go_live_at,has_unpublished_changes,int_field,last_published_at,latest_revision_created_at,live_revision,locked,owner,rich_text_field,search_description,seo_title,show_in_menus\r\n' f',tests.simplepage,2,Test page,slug-life,http://wrong_url/,True,False,char,Draft title,2020-12-12 12:12:12,True,2019-01-01 01:01:01,,,42,2019-02-02 02:02:02,2019-03-03 03:03:03,123456,True,1,<p>Rich text</p>,SEO desc,SEO title,True\r\n' ) successes, errors = import_pages(csv_data, SimplePage) self.assertEqual(successes, ['Created page Test page with id 3'], f'Errors: {errors}') self.assertEqual(errors, []) page = SimplePage.objects.latest('id') self.assertEqual(page.get_parent().id, 2) self.assertEqual(page.title, 'Test page') self.assertEqual(page.slug, 'slug-life') self.assertEqual(page.full_url, 'http://wagtailcsvimport.test/home/slug-life/') self.assertIs(page.live, True) self.assertIs(page.bool_field, False) self.assertEqual(page.char_field, 'char') self.assertEqual(page.draft_title, 'Test page') # field was ignored self.assertEqual( page.expire_at, pytz.datetime.datetime(2020, 12, 12, 12, 12, 12, tzinfo=pytz.UTC)) self.assertIs(page.expired, False) self.assertNotEqual( page.first_published_at, pytz.datetime.datetime(2019, 1, 1, 1, 1, 1, tzinfo=pytz.UTC)) # field was ignored self.assertIsNone(page.go_live_at) self.assertIs(page.has_unpublished_changes, False) self.assertEqual(page.int_field, 42) self.assertNotEqual( page.last_published_at, pytz.datetime.datetime(2019, 2, 2, 2, 2, 2, tzinfo=pytz.UTC)) # field was ignored self.assertNotEqual( page.latest_revision_created_at, pytz.datetime.datetime(2019, 3, 3, 3, 3, 3, tzinfo=pytz.UTC)) # field was ignored self.assertNotEqual(page.live_revision_id, 123456) self.assertIs(page.locked, False) self.assertEqual(page.owner_id, 1) self.assertEqual(page.rich_text_field, '<p>Rich text</p>') self.assertEqual(page.search_description, 'SEO desc') self.assertEqual(page.seo_title, 'SEO title') self.assertIs(page.show_in_menus, True)
def test_non_editable_fields_are_silently_ignored(self): page = Page(title='Test Page', locked=False) home = Page.objects.get(slug='home') home.add_child(instance=page) csv_data = StringIO('id,locked\r\n' f'{page.pk},True\r\n') successes, errors = import_pages(csv_data, Page) self.assertEqual(successes, [f'Updated page Test Page with id 3'], f'Errors: {errors}') self.assertEqual(errors, []) page = Page.objects.get(pk=page.pk) # non-editable fields have not been changed self.assertIs(page.locked, False)
def test_update_simple_page_publish(self): page = SimplePage(title='Test Page', slug='test-page', int_field=42, live=False) home = Page.objects.get(slug='home') home.add_child(instance=page) csv_data = StringIO('id,live\r\n' f'3,True\r\n') successes, errors = import_pages(csv_data, SimplePage) self.assertEqual(successes, ['Updated page Test Page with id 3'], f'Errors: {errors}') self.assertEqual(errors, []) page = SimplePage.objects.get(pk=page.pk) # page has been published self.assertIs(page.live, True)
def test_create_complex_page_with_foreign_key(self): simple_page = SimplePage( title='Test Page', int_field=42, ) home = Page.objects.get(slug='home') home.add_child(instance=simple_page) csv_data = StringIO('id,parent,title,fk\r\n' ',2,Page with FK,3\r\n') successes, errors = import_pages(csv_data, M2MPage) self.assertEqual(successes, ['Created page Page with FK with id 4']) self.assertEqual(errors, []) page = M2MPage.objects.latest('id') self.assertEqual(page.get_parent().id, home.pk) self.assertEqual(page.title, 'Page with FK') self.assertEqual(page.fk, simple_page) self.assertQuerysetEqual(page.m2m.all(), []) # page is in draft because live was not specified self.assertIs(page.live, False)
def test_successes_are_committed_even_if_there_are_errors(self): page = Page(title='Existing Page', ) home = Page.objects.get(slug='home') home.add_child(instance=page) csv_data = StringIO('id,parent,title\r\n' '3,2,Updated Existing Page\r\n' ',2,New Page\r\n' ',2,\r\n') successes, errors = import_pages(csv_data, Page) self.assertEqual(successes, [ 'Updated page Updated Existing Page with id 3', 'Created page New Page with id 4' ], f'Errors: {errors}') self.assertEqual([repr(e) for e in errors], [ "Error(Errors processing row number 3: {'title': [ValidationError(['This field is required.'])]})" ]) self.assertQuerysetEqual(Page.objects.order_by('id'), [ '<Page: Root>', '<Page: Home>', '<Page: Updated Existing Page>', '<Page: New Page>' ])
def test_create_simple_page_minimum_required_fields(self): csv_data = StringIO('id,parent,title,int_field\r\n' f',2,A simple page for a simple test,27\r\n') successes, errors = import_pages(csv_data, SimplePage) self.assertEqual( successes, ['Created page A simple page for a simple test with id 3'], f'Errors: {errors}') self.assertEqual(errors, []) page = SimplePage.objects.latest('id') self.assertEqual(page.get_parent().id, 2) self.assertEqual(page.title, 'A simple page for a simple test') self.assertEqual(page.int_field, 27) # missing fields have default values self.assertEqual(page.slug, 'a-simple-page-for-a-simple-test') self.assertEqual(page.seo_title, '') self.assertEqual(page.search_description, '') self.assertIs(page.bool_field, True) self.assertEqual(page.char_field, '') self.assertEqual(page.int_field, 27) self.assertEqual(page.rich_text_field, '') # page is in draft because live was not specified self.assertIs(page.live, False)
def test_update_wont_publish_or_unpublish_if_live_column_is_missing(self): live_page = Page(title='Live Page', live=True) draft_page = Page(title='Draft Page', live=False) home = Page.objects.get(slug='home') home.add_child(instance=live_page) home.add_child(instance=draft_page) csv_data = StringIO('id,title\r\n' f'3,Updated Live Page\r\n' f'4,Updated Draft Page\r\n') successes, errors = import_pages(csv_data, Page) self.assertEqual(successes, [ 'Updated page Updated Live Page with id 3', 'Updated page Updated Draft Page with id 4', ]) self.assertEqual(errors, []) live_page.refresh_from_db() self.assertEqual(live_page.title, 'Updated Live Page') self.assertTrue(live_page.live) draft_page.refresh_from_db() self.assertEqual(draft_page.title, 'Updated Draft Page') self.assertFalse(draft_page.live)
def test_wrong_file_content(self): not_csv_data = BytesIO(b'\x01\x11\x21\x31\x41\x51\x61\x71\x81\x91') successes, errors = import_pages(not_csv_data, Page) self.assertEqual(successes, []) self.assertEqual([repr(e) for e in errors], ["Error(File is not valid CSV)"])