Repository URL to install this package:
|
Version:
2.4.1rc1 ▾
|
import json
from django.test import TestCase
from wagtail.admin.tests.test_contentstate import content_state_equal
from wagtail.core.models import PAGE_MODEL_CLASSES, Page, Site
from wagtail.tests.testapp.models import (
BusinessChild, BusinessIndex, BusinessNowherePage, BusinessSubIndex, EventIndex, EventPage,
SectionedRichTextPage, SimplePage, StreamPage)
from wagtail.tests.utils import WagtailPageTests, WagtailTestUtils
from wagtail.tests.utils.form_data import inline_formset, nested_form_data, rich_text, streamfield
class TestAssertTagInHTML(WagtailTestUtils, TestCase):
def test_assert_tag_in_html(self):
haystack = """<ul>
<li class="normal">hugh</li>
<li class="normal">pugh</li>
<li class="really important" lang="en"><em>barney</em> mcgrew</li>
</ul>"""
self.assertTagInHTML('<li lang="en" class="important really">', haystack)
self.assertTagInHTML('<li class="normal">', haystack, count=2)
with self.assertRaises(AssertionError):
self.assertTagInHTML('<div lang="en" class="important really">', haystack)
with self.assertRaises(AssertionError):
self.assertTagInHTML('<li lang="en" class="important really">', haystack, count=2)
with self.assertRaises(AssertionError):
self.assertTagInHTML('<li lang="en" class="important">', haystack)
with self.assertRaises(AssertionError):
self.assertTagInHTML('<li lang="en" class="important really" data-extra="boom">', haystack)
def test_assert_tag_in_html_with_extra_attrs(self):
haystack = """<ul>
<li class="normal">hugh</li>
<li class="normal">pugh</li>
<li class="really important" lang="en"><em>barney</em> mcgrew</li>
</ul>"""
self.assertTagInHTML('<li class="important really">', haystack, allow_extra_attrs=True)
self.assertTagInHTML('<li>', haystack, count=3, allow_extra_attrs=True)
with self.assertRaises(AssertionError):
self.assertTagInHTML('<li class="normal" lang="en">', haystack, allow_extra_attrs=True)
with self.assertRaises(AssertionError):
self.assertTagInHTML('<li class="important really">', haystack, count=2, allow_extra_attrs=True)
def test_assert_tag_in_template_script(self):
haystack = """<html>
<script type="text/template">
<p class="really important">first template block</p>
</script>
<script type="text/template">
<p class="really important">second template block</p>
</script>
<p class="normal">not in a script tag</p>
</html>"""
self.assertTagInTemplateScript('<p class="important really">', haystack)
self.assertTagInTemplateScript('<p class="important really">', haystack, count=2)
with self.assertRaises(AssertionError):
self.assertTagInTemplateScript('<p class="normal">', haystack)
class TestWagtailPageTests(WagtailPageTests):
def setUp(self):
super().setUp()
site = Site.objects.get(is_default_site=True)
self.root = site.root_page.specific
def test_assert_can_create_at(self):
# It should be possible to create an EventPage under an EventIndex,
self.assertCanCreateAt(EventIndex, EventPage)
self.assertCanCreateAt(Page, EventIndex)
# It should not be possible to create a SimplePage under a BusinessChild
self.assertCanNotCreateAt(SimplePage, BusinessChild)
# This should raise, as it *is not* possible
with self.assertRaises(AssertionError):
self.assertCanCreateAt(SimplePage, BusinessChild)
# This should raise, as it *is* possible
with self.assertRaises(AssertionError):
self.assertCanNotCreateAt(EventIndex, EventPage)
def test_assert_can_create(self):
self.assertFalse(EventIndex.objects.exists())
self.assertCanCreate(self.root, EventIndex, {
'title': 'Event Index',
'intro': '''{"entityMap": {},"blocks": [
{"inlineStyleRanges": [], "text": "Event intro", "depth": 0, "type": "unstyled", "key": "00000", "entityRanges": []}
]}'''
})
self.assertTrue(EventIndex.objects.exists())
self.assertCanCreate(self.root, StreamPage, {
'title': 'Flierp',
'body-0-type': 'text',
'body-0-value': 'Dit is onze mooie text',
'body-0-order': '0',
'body-0-deleted': '',
'body-1-type': 'rich_text',
'body-1-value': '''{"entityMap": {},"blocks": [
{"inlineStyleRanges": [], "text": "Dit is onze mooie text in een ferrari", "depth": 0, "type": "unstyled", "key": "00000", "entityRanges": []}
]}''',
'body-1-order': '1',
'body-1-deleted': '',
'body-2-type': 'product',
'body-2-value-name': 'pegs',
'body-2-value-price': 'a pound',
'body-2-order': '2',
'body-2-deleted': '',
'body-count': '3'
})
self.assertCanCreate(self.root, SectionedRichTextPage, {
'title': 'Fight Club',
'sections-TOTAL_FORMS': '2',
'sections-INITIAL_FORMS': '0',
'sections-MIN_NUM_FORMS': '0',
'sections-MAX_NUM_FORMS': '1000',
'sections-0-body': '''{"entityMap": {},"blocks": [
{"inlineStyleRanges": [], "text": "Rule 1: You do not talk about Fight Club", "depth": 0, "type": "unstyled", "key": "00000", "entityRanges": []}
]}''',
'sections-0-ORDER': '0',
'sections-0-DELETE': '',
'sections-1-body': '''{"entityMap": {},"blocks": [
{"inlineStyleRanges": [], "text": "Rule 2: You DO NOT talk about Fight Club", "depth": 0, "type": "unstyled", "key": "00000", "entityRanges": []}
]}''',
'sections-1-ORDER': '0',
'sections-1-DELETE': '',
})
def test_assert_can_create_with_form_helpers(self):
# same as test_assert_can_create, but using the helpers from wagtail.tests.utils.form_data
# as an end-to-end test
self.assertFalse(EventIndex.objects.exists())
self.assertCanCreate(self.root, EventIndex, nested_form_data({
'title': 'Event Index',
'intro': rich_text('<p>Event intro</p>')
}))
self.assertTrue(EventIndex.objects.exists())
self.assertCanCreate(self.root, StreamPage, nested_form_data({
'title': 'Flierp',
'body': streamfield([
('text', 'Dit is onze mooie text'),
('rich_text', rich_text('<p>Dit is onze mooie text in een ferrari</p>')),
('product', {'name': 'pegs', 'price': 'a pound'}),
]),
}))
self.assertCanCreate(self.root, SectionedRichTextPage, nested_form_data({
'title': 'Fight Club',
'sections': inline_formset([
{'body': rich_text('<p>Rule 1: You do not talk about Fight Club</p>')},
{'body': rich_text('<p>Rule 2: You DO NOT talk about Fight Club</p>')},
]),
}))
def test_assert_can_create_subpage_rules(self):
simple_page = SimplePage(title='Simple Page', slug='simple', content="hello")
self.root.add_child(instance=simple_page)
# This should raise an error, as a BusinessChild can not be created under a SimplePage
with self.assertRaisesRegex(AssertionError, r'Can not create a tests.businesschild under a tests.simplepage'):
self.assertCanCreate(simple_page, BusinessChild, {})
def test_assert_can_create_validation_error(self):
# This should raise some validation errors, complaining about missing
# title and slug fields
with self.assertRaisesRegex(AssertionError, r'\bslug:\n[\s\S]*\btitle:\n'):
self.assertCanCreate(self.root, SimplePage, {})
def test_assert_allowed_subpage_types(self):
self.assertAllowedSubpageTypes(BusinessIndex, {BusinessChild, BusinessSubIndex})
self.assertAllowedSubpageTypes(BusinessChild, {})
# The only page types that have rules are the Business pages. As such,
# everything can be created under the Page model except some of the
# Business pages
all_but_business = set(PAGE_MODEL_CLASSES) - {BusinessSubIndex, BusinessChild, BusinessNowherePage}
self.assertAllowedSubpageTypes(Page, all_but_business)
with self.assertRaises(AssertionError):
self.assertAllowedSubpageTypes(BusinessSubIndex, {BusinessSubIndex, BusinessChild})
def test_assert_allowed_parent_page_types(self):
self.assertAllowedParentPageTypes(BusinessChild, {BusinessIndex, BusinessSubIndex})
self.assertAllowedParentPageTypes(BusinessSubIndex, {BusinessIndex})
# The only page types that have rules are the Business pages. As such,
# a BusinessIndex can be created everywhere except under the other
# Business pages.
all_but_business = set(PAGE_MODEL_CLASSES) - {BusinessSubIndex, BusinessChild, BusinessIndex}
self.assertAllowedParentPageTypes(BusinessIndex, all_but_business)
with self.assertRaises(AssertionError):
self.assertAllowedParentPageTypes(BusinessSubIndex, {BusinessSubIndex, BusinessIndex})
class TestFormDataHelpers(TestCase):
def test_nested_form_data(self):
result = nested_form_data({
'foo': 'bar',
'parent': {
'child': 'field',
},
})
self.assertEqual(
result,
{'foo': 'bar', 'parent-child': 'field'}
)
def test_streamfield(self):
result = nested_form_data({'content': streamfield([
('text', 'Hello, world'),
('text', 'Goodbye, world'),
('coffee', {'type': 'latte', 'milk': 'soya'}),
])})
self.assertEqual(
result,
{
'content-count': '3',
'content-0-type': 'text',
'content-0-value': 'Hello, world',
'content-0-order': '0',
'content-0-deleted': '',
'content-1-type': 'text',
'content-1-value': 'Goodbye, world',
'content-1-order': '1',
'content-1-deleted': '',
'content-2-type': 'coffee',
'content-2-value-type': 'latte',
'content-2-value-milk': 'soya',
'content-2-order': '2',
'content-2-deleted': '',
}
)
def test_inline_formset(self):
result = nested_form_data({'lines': inline_formset([
{'text': 'Hello'},
{'text': 'World'},
])})
self.assertEqual(
result,
{
'lines-TOTAL_FORMS': '2',
'lines-INITIAL_FORMS': '0',
'lines-MIN_NUM_FORMS': '0',
'lines-MAX_NUM_FORMS': '1000',
'lines-0-text': 'Hello',
'lines-0-ORDER': '0',
'lines-0-DELETE': '',
'lines-1-text': 'World',
'lines-1-ORDER': '1',
'lines-1-DELETE': '',
}
)
def test_default_rich_text(self):
result = rich_text('<h2>title</h2><p>para</p>')
self.assertTrue(content_state_equal(
json.loads(result),
{
'entityMap': {},
'blocks': [
{'inlineStyleRanges': [], 'text': 'title', 'depth': 0, 'type': 'header-two', 'key': '00000', 'entityRanges': []},
{'inlineStyleRanges': [], 'text': 'para', 'depth': 0, 'type': 'unstyled', 'key': '00000', 'entityRanges': []},
]
}
))
def test_rich_text_with_custom_features(self):
# feature list doesn't allow <h2>, so it should become an unstyled paragraph block
result = rich_text('<h2>title</h2><p>para</p>', features=['p'])
self.assertTrue(content_state_equal(
json.loads(result),
{
'entityMap': {},
'blocks': [
{'inlineStyleRanges': [], 'text': 'title', 'depth': 0, 'type': 'unstyled', 'key': '00000', 'entityRanges': []},
{'inlineStyleRanges': [], 'text': 'para', 'depth': 0, 'type': 'unstyled', 'key': '00000', 'entityRanges': []},
]
}
))
def test_rich_text_with_alternative_editor(self):
result = rich_text('<h2>title</h2><p>para</p>', editor='hallo')
self.assertEqual(result, '<h2>title</h2><p>para</p>')