Exemplo n.º 1
0
    def to_python(self, value):
        if value is None or value == '':
            return StreamValue(self.stream_block, [])
        elif isinstance(value, StreamValue):
            return value
        elif isinstance(value, str):
            try:
                unpacked_value = json.loads(value)
            except ValueError:
                # value is not valid JSON; most likely, this field was previously a
                # rich text field before being migrated to StreamField, and the data
                # was left intact in the migration. Return an empty stream instead
                # (but keep the raw text available as an attribute, so that it can be
                # used to migrate that data to StreamField)
                return StreamValue(self.stream_block, [], raw_text=value)

            if unpacked_value is None:
                # we get here if value is the literal string 'null'. This should probably
                # never happen if the rest of the (de)serialization code is working properly,
                # but better to handle it just in case...
                return StreamValue(self.stream_block, [])

            return self.stream_block.to_python(unpacked_value)
        else:
            # See if it looks like the standard non-smart representation of a
            # StreamField value: a list of (block_name, value) tuples
            try:
                [None for (x, y) in value]
            except (TypeError, ValueError):
                # Give up trying to make sense of the value
                raise TypeError(
                    "Cannot handle %r (type %r) as a value of StreamField" %
                    (value, type(value)))

            # Test succeeded, so return as a StreamValue-ified version of that value
            return StreamValue(self.stream_block, value)
    def test_resource_list_show_thumbnails_false(self):
        """ Resource List doesn't show thumbs when show_thumbnails is False"""
        no_thumbnails_page = BrowsePage(
            title='No Thumbnails Page',
            slug='no-thumbnails',
        )
        no_thumbnails_page.content = StreamValue(
            no_thumbnails_page.content.stream_block,
            [atomic.snippet_list_show_thumbnails_false], True)
        publish_page(child=no_thumbnails_page)

        self.create_resource()

        response = self.client.get('/no-thumbnails/')
        self.assertNotContains(response, 'o-resource-list_list-thumbnail')
Exemplo n.º 3
0
    def test_resource_list_set_col_width(self):
        """ Resource List Assets column width is fixed when set"""
        assets_width_page = BrowsePage(
            title='Assets Width Test Page',
            slug='assets-width',
        )
        assets_width_page.content = StreamValue(
            assets_width_page.content.stream_block,
            [atomic.snippet_list_actions_column_width_40], True)
        publish_page(child=assets_width_page)

        self.create_resource()

        response = self.client.get('/assets-width/')
        self.assertContains(response, 'u-w40pct"')
    def test_resource_list_show_thumbnails_true(self):
        """ Resource List shows thumbnails when show_thumbnails is True"""
        thumbnails_page = BrowsePage(
            title='Thumbnails Page',
            slug='thumbnails',
        )
        thumbnails_page.content = StreamValue(
            thumbnails_page.content.stream_block,
            [atomic.snippet_list_show_thumbnails_true], True)
        publish_page(child=thumbnails_page)

        self.create_resource()

        response = self.client.get('/thumbnails/')
        self.assertContains(response, 'o-resource-list_list-thumbnail')
 def test_quote(self):
     """Quote value correctly displays on a Learn Page"""
     learn_page = LearnPage(
         title='Learn',
         slug='learn'
     )
     learn_page.content = StreamValue(
         learn_page.content.stream_block,
         [atomic.full_width_text],
         True
     )
     publish_page(child=learn_page)
     response = self.client.get('/learn/')
     self.assertContains(response, 'this is a quote')
     self.assertContains(response, 'a citation')
 def setUp(self):
     super(TestActivityIndexPageSearch, self).setUp()
     self.ROOT_PAGE = HomePage.objects.get(slug='cfgov')
     self.ROOT_PAGE.save_revision().publish()
     self.site = Site.objects.get(is_default_site=True)
     self.factory = RequestFactory()
     self.search_page = ActivityIndexPage(live=True,
                                          path='search',
                                          depth='1',
                                          title='Search for activities',
                                          slug='search')
     self.search_page.header = StreamValue(
         self.search_page.header.stream_block, [atomic.text_introduction],
         True)  # noqa: E501
     publish_page(child=self.search_page)
 def test_content_with_anchor(self):
     """Content with anchor value correctly displays on a Learn Page"""
     learn_page = LearnPage(
         title='Learn',
         slug='learn'
     )
     learn_page.content = StreamValue(
         learn_page.content.stream_block,
         [atomic.full_width_text],
         True
     )
     publish_page(child=learn_page)
     response = self.client.get('/learn/')
     self.assertContains(response, 'full width text block')
     self.assertContains(response, 'this is an anchor link')
Exemplo n.º 8
0
    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())
Exemplo n.º 9
0
def add_feedback_form(slug, cls):
    feedback_form = {
        'type': 'feedback',
        'value': []
    }
    page = cls(
        title=slug,
        slug=slug,
    )
    page.content = StreamValue(
        page.content.stream_block,
        [feedback_form],
        True,
    )
    publish_page(page)
Exemplo n.º 10
0
    def setUp(self):
        self.request = mock.MagicMock()
        self.limit = 10
        self.sublanding_page = SublandingPage(title='title')

        helpers.publish_page(child=self.sublanding_page)
        self.post1 = BrowseFilterablePage(title='post 1')
        self.post2 = BrowseFilterablePage(title='post 2')
        # the content of this post has both a full_width_text
        # and a filter_controls
        self.post1.content = StreamValue(
            self.post1.content.stream_block,
            [atomic.full_width_text, atomic.filter_controls], True)
        # this one only has a filter_controls
        self.post2.content = StreamValue(self.post1.content.stream_block,
                                         [atomic.filter_controls], True)

        helpers.save_new_page(self.post1, self.sublanding_page)
        helpers.save_new_page(self.post2, self.sublanding_page)

        # manually set the publication date of the posts to ensure consistent
        # order of retrieval in test situations, otherwise the `date_published`
        # can vary due to commit order

        self.child1_of_post1 = AbstractFilterPage(title='child 1 of post 1',
                                                  date_published=dt.date(
                                                      2016, 9, 1))
        self.child2_of_post1 = AbstractFilterPage(title='child 2 of post 1',
                                                  date_published=dt.date(
                                                      2016, 9, 2))
        self.child1_of_post2 = AbstractFilterPage(title='child 1 of post 2',
                                                  date_published=dt.date(
                                                      2016, 9, 3))
        helpers.save_new_page(self.child1_of_post1, self.post1)
        helpers.save_new_page(self.child2_of_post1, self.post1)
        helpers.save_new_page(self.child1_of_post2, self.post2)
    def test_resource_list(self):
        """ Resource List renders thumbnails when show_thumbnails is True"""
        browse_page = BrowsePage(
            title='Browse Page',
            slug='browse',
        )
        browse_page.content = StreamValue(
            browse_page.content.stream_block,
            [atomic.snippet_list_show_thumbnails_false], True)
        publish_page(child=browse_page)

        self.create_resource()

        response = self.client.get('/browse/')
        self.assertContains(response, 'Test Resource List')
        self.assertContains(response, 'Test Resource')
 def test_notification(self):
     """Notification correctly displays on a Sublanding Page"""
     sublanding_page = SublandingPage(
         title='Sublanding Page',
         slug='sublanding',
     )
     sublanding_page.content = StreamValue(
         sublanding_page.content.stream_block,
         [atomic.notification],
         True
     )
     publish_page(child=sublanding_page)
     response = self.client.get('/sublanding/')
     self.assertContains(response, 'this is a notification message')
     self.assertContains(response, 'this is a notification explanation')
     self.assertContains(response, 'this is a notification link')
Exemplo n.º 13
0
def add_filterable_page(slug, cls):
    filterable_page = cls(
        title=slug,
        slug=slug,
    )
    filterable_page.content = StreamValue(
        filterable_page.content.stream_block,
        [atomic.filter_controls],
        True
    )
    publish_page(filterable_page)
    add_children(
        parent=filterable_page,
        num=11,
        slug=slug,
    )
Exemplo n.º 14
0
 def test_tableblock(self):
     """Table correctly displays on a Learn Page"""
     learn_page = LearnPage(
             title='Learn Page',
             slug='learn',
     )
     learn_page.content = StreamValue(
         learn_page.content.stream_block,
         [atomic.table_block],
         True
     )
     publish_page(child=learn_page)
     response = django_client.get('/learn/')
     self.assertContains(response, 'Header One')
     self.assertContains(response, 'Row 1-1')
     self.assertContains(response, 'Row 2-1')
Exemplo n.º 15
0
    def test_that_deleting_recommended_articles_should_not_raise_any_errors(
            self):
        articles = [self._create_blog_article_page() for _ in range(3)]
        articles_block = StreamBlock([("page", PageChooserBlock())])
        recommended_articles = StreamValue(articles_block,
                                           [("page", article)
                                            for article in articles])
        main_article = self._create_blog_article_page(
            recommended_articles=recommended_articles)

        for article in articles:
            article.delete()
        main_article.refresh_from_db()

        self.assertEqual(BlogArticlePage.objects.all().count(), 1)
        self.assertEqual(len(main_article.recommended_articles), 0)
Exemplo n.º 16
0
def set_stream_data(page_or_revision, field_name, stream_data, commit=True):
    """ Set the stream field data for a given field name on a page or a
    revision. If commit is True (default) save() is called on the
    page_or_revision object. """
    if is_page(page_or_revision):
        field = getattr(page_or_revision, field_name)
        stream_block = field.stream_block
        stream_value = StreamValue(stream_block, stream_data, is_lazy=True)
        setattr(page_or_revision, field_name, stream_value)
    else:
        revision_content = json.loads(page_or_revision.content_json)
        revision_content[field_name] = json.dumps(stream_data)
        page_or_revision.content_json = json.dumps(revision_content)

    if commit:
        page_or_revision.save()
Exemplo n.º 17
0
def migrate_work_body_to_streamfield(apps, schema_editor):
    WorkPage = apps.get_model('work.WorkPage')
    stream_block = WorkPage._meta.get_field('streamfield').stream_block

    # Update model
    for work_page in WorkPage.objects.exclude(body='').exclude(
            body='<p></p>').exclude(body='<p><br/></p>'):
        # Add body as first block so it appears in the same place on the template
        work_page.streamfield = StreamValue(stream_block, [
            ('paragraph', RichText(
                work_page.body), str(uuid3(UUID_NAMESPACE, work_page.body))),
        ] + [(child.block_type, child.value, child.id)
             for child in work_page.streamfield])

        work_page.save()

    # Update revisions
    PageRevision = apps.get_model('wagtailcore.PageRevision')
    ContentType = apps.get_model('contenttypes.ContentType')
    work_page_content_type = ContentType.objects.get(app_label='work',
                                                     model='workpage')

    for revision in PageRevision.objects.filter(
            page__content_type=work_page_content_type):
        content = json.loads(revision.content_json)

        if content['body'] and content['body'] not in [
                '<p></p>', '<p><br/></p>'
        ]:
            streamfield_json = content.get('streamfield', '')

            if streamfield_json:
                streamfield = json.loads(streamfield_json)
            else:
                streamfield = []

            streamfield.insert(
                0, {
                    "type": "paragraph",
                    "value": content['body'],
                    "id": str(uuid3(UUID_NAMESPACE, content['body'])),
                })

            content['streamfield'] = json.dumps(streamfield)

            revision.content_json = json.dumps(content)
            revision.save()
Exemplo n.º 18
0
 def setUp(self):
     self._set_default_blog_index_page_as_new_root_page_child()
     self.blog_index_page = self._get_newest_blog_index_page()
     header_block = StreamBlock([(ArticleBodyBlockNames.HEADER.value,
                                  CharBlock())])
     body = StreamValue(
         header_block,
         [
             (ArticleBodyBlockNames.HEADER.value, "Header 1"),
             (ArticleBodyBlockNames.HEADER.value, "Header 2"),
             (ArticleBodyBlockNames.HEADER.value, "Header 3"),
         ],
     )
     self.blog_article_page = self._create_blog_article_page(
         blog_index_page=self.blog_index_page,
         body=body,
         table_of_contents=True)
    def test_update_streamfields(self):
        # Streamfields are special in that they contain content that needs to be synchronised as well as
        # translatable content.

        # Copy page for translation, this will have a blank streamfield
        translated = self.page.copy_for_translation(self.dest_locale)

        # Set streamfield value on original
        self.page.test_streamfield = StreamValue(
            TestPage.test_streamfield.field.stream_block,
            [{
                "id": "id",
                "type": "test_charblock",
                "value": "This is some test content",
            }],
            is_lazy=True,
        )

        # Save the page
        revision = self.page.save_revision()
        revision.publish()
        self.page.refresh_from_db()
        source_with_streamfield, created = TranslationSource.update_or_create_from_instance(
            self.page)

        # Create a translation for the new context
        StringTranslation.objects.create(
            translation_of=self.string,
            locale=self.dest_locale,
            context=TranslationContext.objects.get(
                object_id=self.page.translation_key,
                path="test_streamfield.id"),
            data="Ceci est du contenu de test",
        )

        new_page, created = source_with_streamfield.create_or_update_translation(
            self.dest_locale)

        self.assertFalse(created)
        self.assertEqual(new_page, translated)

        # Check the block was copied into translation
        self.assertEqual(new_page.test_streamfield[0].id, "id")
        self.assertEqual(new_page.test_streamfield[0].value,
                         "Ceci est du contenu de test")
Exemplo n.º 20
0
 def setUp(self):
     super().setUp()
     # Create Blog
     self.blog_page = BlogPageFactory(body=[
         ("heading", "Test heading 1"),
         ("paragraph", RichText("This is a paragraph.")),
         ("heading", "Test heading 2"),
         ("image", wagtail_factories.ImageFactory()),
         ("decimal", decimal.Decimal(1.2)),
         ("date", datetime.date.today()),
         ("datetime", datetime.datetime.now()),
         (
             "gallery",
             {
                 "title":
                 "Gallery title",
                 "images":
                 StreamValue(
                     stream_block=ImageGalleryImages(),
                     stream_data=[
                         (
                             "image",
                             {
                                 "image":
                                 wagtail_factories.ImageChooserBlockFactory(
                                 )
                             },
                         ),
                         (
                             "image",
                             {
                                 "image":
                                 wagtail_factories.ImageChooserBlockFactory(
                                 )
                             },
                         ),
                     ],
                 ),
             },
         ),
         ("objectives", ["Read all of article!"]),
         ("video", {
             "youtube_link": EmbedValue("https://youtube.com/")
         }),
     ])
Exemplo n.º 21
0
 def _create_blog_article_page(
     self,
     blog_index_page=None,
     title="Simple Article Title",
     page_title="Simple Article Title",
     date=datetime.now(),
     body=None,
     author=None,
     read_time=7,
     table_of_contents=False,
     recommended_articles=None,
     views=0,
     cover_photo=None,
     article_photo=None,
     is_main_article=False,
 ):
     if body is None:
         block = StreamBlock([(ArticleBodyBlockNames.MARKDOWN.value,
                               MarkdownBlock())])
         body = StreamValue(
             block,
             [(ArticleBodyBlockNames.MARKDOWN.value, "Hello, World")])
     if author is None:
         author = BossFactory()
     blog_article_page = BlogArticlePage(
         title=title,
         page_title=page_title,
         date=date,
         body=body,
         author=author,
         read_time=read_time,
         table_of_contents=table_of_contents,
         recommended_articles=recommended_articles,
         views=views,
         cover_photo=cover_photo,
         article_photo=article_photo,
         is_main_article=is_main_article,
     )
     if blog_index_page is None:
         blog_index_page = self._get_newest_blog_index_page()
     blog_index_page.add_child(instance=blog_article_page)
     blog_article_page.save()
     return blog_article_page
Exemplo n.º 22
0
    def test_export_script_assemble_output(self):
        answer = Answer(id=1234)
        answer.save()
        page = AnswerPage(
            slug="mock-question1-en-1234", title="Mock question1"
        )
        page.answer_base = answer
        page.question = "Mock question1"
        page.answer_content = StreamValue(
            page.answer_content.stream_block,
            [{"type": "text", "value": {"content": "Mock answer"}}],
            True,
        )
        helpers.publish_page(page)

        output = assemble_output()[0]
        self.assertEqual(output.get("ASK_ID"), 1234)
        self.assertEqual(output.get("URL"), "/mock-question1-en-1234/")
        self.assertEqual(output.get("Question"), "Mock question1")
Exemplo n.º 23
0
    def test_cache_gets_called_when_visiting_filterable_page(self):
        # Create a filterable page
        page = BrowseFilterablePage(title='test browse filterable page',
                                    slug='test-browse-filterable-page')
        page.content = StreamValue(page.content.stream_block,
                                   [atomic.filter_controls], True)
        publish_page(page)

        # Add a child to that filterable page so that there are results
        # with a post preview
        child_page = BlogPage(title='test blog page', slug='test-blog-page')
        page.add_child(instance=child_page)

        cache = caches['post_preview']
        with patch.object(cache, 'add') as add_to_cache:
            # Navigate to the filterable page so that `post-preview.html` loads
            self.client.get('/test-browse-filterable-page/')

            self.assertTrue(add_to_cache.called)
Exemplo n.º 24
0
    def test_that_article_intro_should_take_multiple_paragraphs_under_account(
            self):
        paragraph_1 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam laoreet venenatis enim, non luctus nisi finibus ut."
        paragraph_2 = "Mauris porta eleifend massa, nec maximus lacus luctus a. Aenean libero felis, placerat non malesuada a, maximus id erat."
        paragraph_3 = "Nulla ut purus elementum, auctor orci eget, facilisis est. Nullam aliquet volutpat massa, vel bibendum libero venenatis ut. Integer ac sapien et urna sollicitudin."
        expected_string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam laoreet venenatis enim, non luctus nisi finibus ut. Mauris porta eleifend massa, nec maximus lacus luctus a. Aenean libero felis, placerat non malesuada a, maximus id erat. Nulla ut"

        body_block = StreamBlock([(ArticleBodyBlockNames.PARAGRAPH.value,
                                   RichTextBlock())])
        body = StreamValue(
            body_block,
            [
                (ArticleBodyBlockNames.PARAGRAPH.value, RichText(paragraph_1)),
                (ArticleBodyBlockNames.PARAGRAPH.value, RichText(paragraph_2)),
                (ArticleBodyBlockNames.PARAGRAPH.value, RichText(paragraph_3)),
            ],
        )
        blog_article = self._create_blog_article_page(body=body)

        self.assertEqual(blog_article.intro, expected_string + INTRO_ELLIPSIS)
 def test_sidebar_contact_info(self):
     """Sidebar contact info correctly displays on a Landing Page"""
     landing_page = LandingPage(
         title='Landing Page',
         slug='landing',
     )
     contact = self.get_contact()
     landing_page.sidefoot = StreamValue(
         landing_page.sidefoot.stream_block,
         [atomic.sidebar_contact(contact.id)], True)
     publish_page(child=landing_page)
     response = django_client.get('/landing/')
     self.assertContains(response, '*****@*****.**')
     self.assertContains(response, '(515) 123-4567')
     self.assertContains(response, 'Ext. 1234')
     self.assertContains(response, '123 abc street')
     self.assertContains(response, 'this is a heading')
     self.assertContains(response, 'this is a body')
     self.assertContains(
         response, 'Contact Information')  # This is specific to sidebar
 def test_main_contact_info(self):
     """Main contact info correctly displays on a Sublanding Page"""
     sublanding_page = SublandingPage(
         title='Sublanding Page',
         slug='sublanding',
     )
     contact = self.get_contact()
     sublanding_page.content = StreamValue(
         sublanding_page.content.stream_block,
         [atomic.main_contact_info(contact.id)], True)
     publish_page(child=sublanding_page)
     response = django_client.get('/sublanding/')
     self.assertContains(response, '*****@*****.**')
     self.assertContains(response, '(515) 123-4567')
     self.assertContains(response, 'Ext. 1234')
     self.assertContains(response, '123 abc street')
     self.assertContains(response, 'this is a heading')
     self.assertContains(response, 'this is a body')
     self.assertNotContains(response,
                            'Contact Information')  # Only shown on sidebar
Exemplo n.º 27
0
    def test_export_script_assemble_output(self):
        answer = Answer(id=1234)
        answer.save()
        page = AnswerPage(slug='mock-question1-en-1234',
                          title='Mock question1')
        page.answer_base = answer
        page.question = 'Mock question1'
        page.answer_content = StreamValue(page.answer_content.stream_block,
                                          [{
                                              'type': 'text',
                                              'value': {
                                                  'content': 'Mock answer'
                                              }
                                          }], True)
        helpers.publish_page(page)

        output = assemble_output()[0]
        self.assertEqual(output.get('ASK_ID'), 1234)
        self.assertEqual(output.get('URL'), '/mock-question1-en-1234/')
        self.assertEqual(output.get('Question'), 'Mock question1')
Exemplo n.º 28
0
 def setUp(self):
     super().setUp()
     # Create Blog
     self.blog_page = BlogPageFactory(body=[
         ("heading", "Test heading 1"),
         ("paragraph", RichText("This is a paragraph.")),
         ("heading", "Test heading 2"),
         ("image", wagtail_factories.ImageFactory()),
         ("decimal", decimal.Decimal(1.2)),
         ("date", datetime.date.today()),
         ("datetime", datetime.datetime.now()),
         (
             "gallery",
             {
                 "title":
                 "Gallery title",
                 "images":
                 StreamValue(
                     stream_block=ImageGalleryImages(),
                     stream_data=[
                         (
                             "image",
                             {
                                 "image":
                                 wagtail_factories.ImageChooserBlockFactory(
                                 )
                             },
                         ),
                         (
                             "image",
                             {
                                 "image":
                                 wagtail_factories.ImageChooserBlockFactory(
                                 )
                             },
                         ),
                     ],
                 ),
             },
         ),
     ])
    def test_chart_block(self):
        """ Chart Block correctly renders fields on a Browse Page"""
        browse_page = BrowsePage(
            title='Browse Page',
            slug='browse',
        )

        # Adds a AUT market to a browse page
        browse_page.content = StreamValue(browse_page.content.stream_block,
                                          [atomic.chart_block], True)
        publish_page(child=browse_page)

        response = self.client.get('/browse/')
        self.assertContains(response, 'Volume of credit cards originated')
        self.assertContains(response, 'foo/bar.csv')
        self.assertContains(response, 'Data not final.')
        self.assertContains(
            response,
            'The most recent data available in this visualization are for April 2016'
        )
        self.assertContains(response, 'January 2018')
Exemplo n.º 30
0
def test_clear_live_post_content_streamchild(blog_page_factory):
    live_posts = json.dumps([
        {
            "type": "live_post",
            "id": "some-id",
            "value": {
                "message_id": "some-id",
                "created": "2021-01-01T12:00:00",
                "modified": "2021-01-01T12:00:00",
                "show": True,
                "content": [],
            },
        },
    ])
    page = blog_page_factory(channel_id="some-id", live_posts=live_posts)
    live_post = page.get_live_post_by_index(live_post_index=0)
    text_block = construct_text_block(text="Some text")

    add_block_to_live_post(TEXT, text_block, live_post)
    clear_live_post_content(live_post)

    assert isinstance(live_post, StreamValue.StreamChild)
    assert live_post.value["content"] == StreamValue(ContentBlock(), [])