def test_templates_blogpost_detail_author_empty(self):
        """
        The empty message for blogpost author should be present in edition but not in
        published mode if its placeholder is empty.
        """
        blogpost = BlogPostFactory()
        page = blogpost.extended_object
        page.publish("en")

        url = page.get_absolute_url()
        response = self.client.get(url)

        # Published view does not have empty author message
        self.assertEqual(response.status_code, 200)
        self.assertNotContains(
            response,
            ('<span class="blogpost-detail__empty">No author yet</span>'),
            html=True,
        )

        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")
        response = self.client.get(url, {"edit": "true"})

        # Edition view does have empty author message
        self.assertEqual(response.status_code, 200)
        self.assertContains(
            response,
            ('<span class="blogpost-detail__empty">No author yet</span>'),
            html=True,
        )
    def test_templates_blogpost_detail_cms_published_content_opengraph(self):
        """The blogpost logo should be used as opengraph image."""
        blogpost = BlogPostFactory(
            fill_cover={
                "original_filename": "cover.jpg",
                "default_alt_text": "my cover",
            },
            should_publish=True,
        )
        url = blogpost.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        self.assertContains(response,
                            '<meta property="og:type" content="article" />')
        self.assertContains(
            response,
            f'<meta property="og:url" content="http://example.com{url:s}" />')
        pattern = (
            r'<meta property="og:image" content="http://example.com'
            r"/media/filer_public_thumbnails/filer_public/.*cover\.jpg__845x500"
        )
        self.assertIsNotNone(re.search(pattern, str(response.content)))
        self.assertContains(
            response, '<meta property="og:image:width" content="845" />')
        self.assertContains(
            response, '<meta property="og:image:height" content="500" />')
    def test_cms_plugins_blogpost_render_on_draft_page(self):
        """
        The blogpost plugin should render as expected on a draft page.
        """
        staff = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=staff.username, password="******")

        # Create a BlogPost
        blogpost = BlogPostFactory(page_title="public title")
        blogpost_page = blogpost.extended_object

        # Create a page to add the plugin to
        page = create_i18n_page("A page")
        placeholder = page.placeholders.get(slot="maincontent")
        add_plugin(placeholder, BlogPostPlugin, "en",
                   **{"page": blogpost_page})

        url = "{:s}?edit".format(page.get_absolute_url(language="en"))

        # The blogpost plugin should still be visible on the draft page
        response = self.client.get(url)
        self.assertContains(response, "public title")

        # Now modify the blogpost to have a draft different from the public version
        title_obj = blogpost_page.get_title_obj(language="en")
        title_obj.title = "draft title"
        title_obj.save()

        # The draft version of the blogpost plugin should now be visible
        response = self.client.get(url)
        self.assertContains(response, "draft title")
        self.assertNotContains(response, "public title")

        # Publication date block should be absent
        self.assertNotContains(response, "__date")
Exemple #4
0
    def test_templates_blogpost_detail_cms_draft_content(self):
        """
        A staff user should see a draft blogpost including only its published linked objects.
        """
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        category = CategoryFactory()
        published_category = CategoryFactory(should_publish=True)
        author = PersonFactory(
            page_title={"en": "Comte de Saint-Germain"}, should_publish=True
        )

        blogpost = BlogPostFactory(
            page_title="Preums",
            fill_cover=True,
            fill_body=True,
            fill_categories=[category, published_category],
            fill_author=[author],
        )
        page = blogpost.extended_object

        # The page should be visible as draft to the staff user
        url = page.get_absolute_url()
        response = self.client.get(url)

        self.assertContains(
            response, "<title>Preums</title>", html=True, status_code=200
        )
        self.assertContains(
            response, '<h1 class="blogpost-detail__title">Preums</h1>', html=True
        )
        self.assertContains(response, "Comte de Saint-Germain", html=True)
        self.assertContains(
            response,
            (
                '<a class="category-tag" '
                'href="{:s}"><span class="category-tag__title">{:s}</span></a>'
            ).format(
                published_category.extended_object.get_absolute_url(),
                published_category.extended_object.get_title(),
            ),
            html=True,
        )
        self.assertContains(
            response,
            (
                '<a class="category-tag category-tag--draft" '
                'href="{:s}"><span class="category-tag__title">{:s}</span></a>'
            ).format(
                category.extended_object.get_absolute_url(),
                category.extended_object.get_title(),
            ),
            html=True,
        )
        self.assertContains(
            response,
            '<p class="blogpost-detail__pubdate">Not published yet</p>',
            html=True,
        )
    def test_templates_blogpost_detail_open_graph_description_excerpt_max_length(
            self):
        """
        An opengraph description should be cut if it exceeds more than 200 caracters
        """
        blogpost = BlogPostFactory()
        page = blogpost.extended_object
        placeholder_value = (
            "Long description that describes the page with a summary. " * 5)

        # Add an excerpt to the blogpost
        placeholder = blogpost.extended_object.placeholders.get(slot="excerpt")
        add_plugin(
            language="en",
            placeholder=placeholder,
            plugin_type="PlainTextPlugin",
            body=placeholder_value,
        )
        page.publish("en")

        url = blogpost.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        cut = placeholder_value[0:200]
        self.assertContains(
            response,
            f'<meta property="og:description" content="{cut}" />',
        )
Exemple #6
0
    def test_models_person_get_blogposts_public_person_page(self):
        """
        When a person is added on a draft blog post, the blog post should not be visible on
        the public person page until the blog post is published.
        """
        person = PersonFactory(should_publish=True)
        person_page = person.extended_object
        blog_post = BlogPostFactory(page_title="my title", should_publish=True)
        blog_post_page = blog_post.extended_object

        # Add a person to the blog post but don't publish the modification
        placeholder = blog_post_page.placeholders.get(slot="author")
        add_plugin(placeholder, PersonPlugin, "en", page=person_page)

        self.assertEqual(list(person.get_blogposts()), [blog_post])
        self.assertEqual(list(person.public_extension.get_blogposts()), [])

        # Now publish the modification and check that the blog post is displayed
        # on the public person page
        blog_post.extended_object.publish("en")
        self.assertEqual(list(person.public_extension.get_blogposts()),
                         [blog_post.public_extension])

        # If the blog post is unpublished, it should not be displayed on the public
        # page anymore
        blog_post_page.unpublish("en")
        self.assertEqual(list(person.get_blogposts()), [blog_post])
        self.assertEqual(list(person.public_extension.get_blogposts()), [])
    def test_cms_wizards_blogpost_submit_form_slug_duplicate(self):
        """
        Trying to create a blog post with a slug that would lead to a duplicate path should
        raise a validation error.
        """
        # A parent page should pre-exist
        parent_page = create_page(
            "News",
            "richie/single_column.html",
            "en",
            reverse_id=BlogPost.PAGE["reverse_id"],
        )
        # Create an existing page with a known slug
        BlogPostFactory(page_parent=parent_page, page_title="My title")

        # Submit a title that will lead to the same slug
        data = {"title": "my title"}
        user = UserFactory(is_staff=True, is_superuser=True)
        form = BlogPostWizardForm(data=data,
                                  wizard_language="en",
                                  wizard_user=user)

        self.assertFalse(form.is_valid())
        self.assertEqual(form.errors,
                         {"slug": ["This slug is already in use"]})
Exemple #8
0
    def test_cms_plugins_blogpost_cascade_variant(self):
        """
        If the variant is not specified on the blogpost plugin, it should render
        according to variant variable eventually present in the context of its
        container.
        """
        # Create an blogpost
        blogpost = BlogPostFactory(page_title="public title",
                                   should_publish=True)
        blogpost_page = blogpost.extended_object

        # Create a page to add the plugin to
        page = create_i18n_page("A page")
        placeholder = page.placeholders.get(slot="maincontent")

        # Add blogpost plugin with default template
        model_instance = add_plugin(placeholder,
                                    BlogPostPlugin,
                                    "en",
                                    page=blogpost_page)

        # Get generated html
        request = RequestFactory()
        request.current_page = page
        request.path_info = "/en/my-path/"
        request.user = AnonymousUser()
        context = {
            "current_page": page,
            "blogpost_variant": "xxl",
            "request": request
        }
        renderer = ContentRenderer(request=request)
        html = renderer.render_plugin(model_instance, context)

        self.assertIn("blogpost-xxl", html)
    def test_cms_plugins_blogpost_render_template(self):
        """
        The blogpost plugin should render according to variant choice.
        """
        staff = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=staff.username, password="******")

        # Create an blogpost
        blogpost = BlogPostFactory(page_title="public title",
                                   should_publish=True)
        blogpost_page = blogpost.extended_object

        # Create a page to add the plugin to
        page = create_i18n_page("A page")
        placeholder = page.placeholders.get(slot="maincontent")

        # Add blogpost plugin with default template
        add_plugin(placeholder, BlogPostPlugin, "en", page=blogpost_page)

        url = "{:s}?edit".format(page.get_absolute_url(language="en"))

        # The blogpost-glimpse default variant should be glimpse
        response = self.client.get(url)
        self.assertContains(response, "blogpost-glimpse")

        # Add blogpost plugin with small variant
        add_plugin(placeholder,
                   BlogPostPlugin,
                   "en",
                   page=blogpost_page,
                   variant="small")

        # The blogpost-glimpse default template should not have the small attribute
        response = self.client.get(url)
        self.assertContains(response, "blogpost-small")
    def test_templates_blogpost_detail_cms_published_content(self):
        """
        Validate that the important elements are displayed on a published blogpost page
        """
        author = PersonFactory(page_title={"en": "Comte de Saint-Germain"},
                               should_publish=True)
        blogpost = BlogPostFactory(page_title="Preums",
                                   fill_cover=True,
                                   fill_body=True,
                                   fill_author=[author])
        page = blogpost.extended_object

        # The page should not be visible before it is published
        url = page.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

        # Publish the blogpost and ensure the content is correct
        page.publish("en")
        response = self.client.get(url)
        self.assertContains(response,
                            "<title>Preums</title>",
                            html=True,
                            status_code=200)
        self.assertContains(response,
                            '<h1 class="blogpost-detail__title">Preums</h1>',
                            html=True)
        self.assertContains(response, "Comte de Saint-Germain", html=True)
    def test_templates_blogpost_detail_open_graph_description_excerpt(self):
        """
        An opengraph description meta should be present if the excerpt placeholder is set.
        """
        blogpost = BlogPostFactory()
        page = blogpost.extended_object

        # Add an excerpt to the blogpost
        placeholder = blogpost.extended_object.placeholders.get(slot="excerpt")
        add_plugin(
            language="en",
            placeholder=placeholder,
            plugin_type="PlainTextPlugin",
            body="A further sub title of the blog post",
        )
        page.publish("en")

        url = blogpost.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        self.assertContains(
            response,
            '<meta property="og:description" content="A further sub title of the blog post" />',
        )
    def test_templates_blogpost_detail_meta_description_excerpt(self):
        """
        The blogpost meta description should show the excerpt placeholder if no meta_description
        placeholoder exists
        """
        blogpost = BlogPostFactory()
        page = blogpost.extended_object

        # Add an excerpt to the blogpost
        placeholder = blogpost.extended_object.placeholders.get(slot="excerpt")
        add_plugin(
            language="en",
            placeholder=placeholder,
            plugin_type="PlainTextPlugin",
            body="A further sub title of the blog post",
        )
        page.publish("en")

        url = blogpost.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        self.assertContains(
            response,
            '<meta name="description" content="A further sub title of the blog post" />',
        )
    def test_templates_blogpost_list_related_categories(self):
        """
        The top of the page should list all categories related to at least one of the blog
        posts on the blog posts list page.
        """
        page = PageFactory(
            template="courses/cms/blogpost_list.html",
            title__language="en",
            should_publish=True,
        )

        post1, post2 = BlogPostFactory.create_batch(2,
                                                    page_parent=page,
                                                    should_publish=True)

        category1, category2, category12, category_alone = CategoryFactory.create_batch(
            4, should_publish=True)

        # Attach categories to post1
        placeholder = post1.extended_object.get_public_object(
        ).placeholders.all()[0]
        add_plugin(placeholder,
                   "CategoryPlugin",
                   "en",
                   page=category1.extended_object)
        add_plugin(placeholder,
                   "CategoryPlugin",
                   "en",
                   page=category12.extended_object)

        # Attach categories to post2
        placeholder = post2.extended_object.get_public_object(
        ).placeholders.all()[0]
        add_plugin(placeholder,
                   "CategoryPlugin",
                   "en",
                   page=category2.extended_object)
        add_plugin(placeholder,
                   "CategoryPlugin",
                   "en",
                   page=category12.extended_object)

        response = self.client.get(page.get_absolute_url())
        self.assertEqual(response.status_code, 200)

        for category in [category1, category2, category12]:
            self.assertContains(
                response,
                ('<a class="category-tag" href="{slug:s}">'
                 '<span class="category-tag__title">{title:s}</span>'
                 "</a>").format(
                     slug=category.extended_object.get_absolute_url(),
                     title=category.extended_object.get_title(),
                 ),
                html=True,
            )

        self.assertNotContains(
            response, category_alone.extended_object.get_absolute_url())
 def test_models_category_get_blogposts_several_languages(self):
     """
     The blogposts should not be duplicated if they exist in several languages.
     """
     category = CategoryFactory(should_publish=True)
     BlogPostFactory(
         page_title={"en": "my title", "fr": "mon titre"},
         fill_categories=[category],
         should_publish=True,
     )
     self.assertEqual(BlogPost.objects.count(), 2)
     self.assertEqual(category.get_blogposts().count(), 1)
    def test_templates_blogpost_list_cms_content(self):
        """
        Validate that the public website only displays blogposts that are currently published,
        while staff users can see draft and unpublished blogposts.
        """
        page = PageFactory(
            template="courses/cms/blogpost_list.html",
            title__language="en",
            should_publish=True,
        )

        BlogPostFactory(page_parent=page, page_title="First post")
        BlogPostFactory(page_parent=page,
                        page_title="Second post",
                        should_publish=True)

        # Publish with a publication date in the future
        future = timezone.now() + timedelta(hours=1)
        with mock.patch("cms.models.pagemodel.now", return_value=future):
            BlogPostFactory(page_parent=page,
                            page_title="Third post",
                            should_publish=True)

        # Anonymous users should only see published blogposts
        response = self.client.get(page.get_absolute_url())

        self.assertEqual(response.status_code, 200)
        self.assertNotContains(response, "First")
        self.assertContains(response, "Second")
        self.assertNotContains(response, "Third")

        # Staff users can see draft and unpublished blogposts
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        response = self.client.get(page.get_absolute_url())
        self.assertEqual(response.status_code, 200)

        for title in ["First", "Second", "Third"]:
            self.assertContains(response, title)
Exemple #16
0
 def test_models_person_get_blogposts_several_languages(self):
     """
     The blogposts should not be duplicated if they exist in several languages.
     """
     person = PersonFactory(should_publish=True)
     BlogPostFactory(
         page_title={
             "en": "my title",
             "fr": "mon titre"
         },
         fill_author=[person],
         should_publish=True,
     )
     self.assertEqual(BlogPost.objects.count(), 2)
     self.assertEqual(person.get_blogposts().count(), 1)
    def test_templates_blogpost_detail_open_graph_description_excerpt_empty(self):
        """
        The opengraph description meta should be missing if the excerpt placeholder is not set.
        """
        blogpost = BlogPostFactory()
        page = blogpost.extended_object
        page.publish("en")

        url = blogpost.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        self.assertNotContains(
            response,
            "og:description",
        )
    def test_models_blogpost_get_related_blogposts(self):
        """
        Blogposts related via a plugin on the draft page should appear in
        their draft version on the draft page.
        Blogposts related via a plugin on the public page should appear in
        their public version on the public page.
        """
        blogpost1, blogpost2, blogpost3 = BlogPostFactory.create_batch(
            3, should_publish=True
        )
        category = CategoryFactory(should_publish=True)

        # Attach categories
        self._attach_category(blogpost1, category)
        self._attach_category(blogpost2, category)
        self._attach_category(blogpost1.public_extension, category)
        self._attach_category(blogpost3.public_extension, category)

        # Draft blogposts
        with self.assertNumQueries(1):
            self.assertEqual(list(blogpost1.get_related_blogposts()), [blogpost2])
        with self.assertNumQueries(1):
            self.assertEqual(list(blogpost2.get_related_blogposts()), [blogpost1])
        # 2 queries because blogpost3 page fields were not retrieved when attaching categories
        with self.assertNumQueries(2):
            self.assertFalse(blogpost3.get_related_blogposts().exists())

        blogpost1_public = blogpost1.public_extension
        with self.assertNumQueries(1):
            self.assertEqual(
                list(blogpost1_public.get_related_blogposts()),
                [blogpost3.public_extension],
            )

        # Public blogposts
        blogpost2_public = blogpost2.public_extension
        # 2 queries because blogpost2.public_extension page fields were not retrieved when
        # attaching categories
        with self.assertNumQueries(2):
            self.assertFalse(blogpost2_public.get_related_blogposts().exists())

        blogpost3_public = blogpost3.public_extension
        with self.assertNumQueries(1):
            self.assertEqual(
                list(blogpost3_public.get_related_blogposts()),
                [blogpost1.public_extension],
            )
    def test_factories_blogpost_body(self):
        """
        BlogPostFactory should be able to generate plugins with a realistic body for
        several languages.
        """
        blogpost = BlogPostFactory(page_languages=["fr", "en"], fill_body=True)

        # Check that the body plugins were created as expected
        body = blogpost.extended_object.placeholders.get(slot="body")
        self.assertEqual(body.cmsplugin_set.count(), 2)

        # The body plugins should contain paragraphs
        for language in ["fr", "en"]:
            description_plugin = body.cmsplugin_set.get(
                plugin_type="TextPlugin", language=language)
            self.assertIn("<p>",
                          description_plugin.djangocms_text_ckeditor_text.body)
    def test_templates_blogpost_detail_meta_description_empty(self):
        """
        The blogpost meta description should not be present if neither the meta_description field
        on the page, nor the excerpt placeholder are filled
        """
        blogpost = BlogPostFactory()
        page = blogpost.extended_object
        page.publish("en")

        url = blogpost.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        self.assertNotContains(
            response,
            '<meta name="description"',
        )
Exemple #21
0
    def test_templates_person_detail_related_blog_posts(self):
        """
        The blog posts written by a person should appear on this person's detail page.
        """
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        person = PersonFactory()
        blog_post = BlogPostFactory(fill_author=[person])

        url = person.extended_object.get_absolute_url()
        response = self.client.get(url)
        html = lxml.html.fromstring(response.content)

        # The blog post should be present on the page
        title = html.cssselect("h3.blogpost-glimpse__title")[0]
        self.assertEqual(title.text_content().strip(),
                         blog_post.extended_object.get_title())
Exemple #22
0
    def test_models_category_get_blogposts_ordering(self):
        """The related blogposts should be sorted by their position in the pages tree."""
        category = CategoryFactory(should_publish=True)
        blogpost1, blogpost2, blogpost3 = BlogPostFactory.create_batch(
            3, fill_categories=[category], should_publish=True)
        self.assertEqual(list(category.get_blogposts()),
                         [blogpost1, blogpost2, blogpost3])

        # Move pages in the tree and check that they are returned in the new order
        blogpost3.extended_object.move_page(blogpost1.extended_object.node,
                                            position="left")
        self.assertEqual(list(category.get_blogposts()),
                         [blogpost3, blogpost1, blogpost2])

        blogpost1.extended_object.move_page(blogpost3.extended_object.node,
                                            position="left")
        self.assertEqual(list(category.get_blogposts()),
                         [blogpost1, blogpost3, blogpost2])
    def test_models_category_get_blogposts(self):
        """
        It should be possible to retrieve the list of related blogposts on the category
        instance. The number of queries should be minimal.
        """
        category = CategoryFactory(should_publish=True)
        blogposts = BlogPostFactory.create_batch(
            2, page_title="my title", fill_categories=[category], should_publish=True
        )
        retrieved_blogposts = category.get_blogposts()

        with self.assertNumQueries(2):
            self.assertEqual(set(retrieved_blogposts), set(blogposts))

        with self.assertNumQueries(0):
            for blogpost in retrieved_blogposts:
                self.assertEqual(
                    blogpost.extended_object.prefetched_titles[0].title, "my title"
                )
    def test_templates_person_detail_related_blog_posts(self):
        """
        The blog posts written by a person should appear on this person's detail page.
        """
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        person = PersonFactory()
        blog_post = BlogPostFactory(fill_author=[person])

        url = person.extended_object.get_absolute_url()
        response = self.client.get(url)

        # The blog post should be present on the page
        self.assertContains(
            response,
            f'<p class="blogpost-glimpse__title">{blog_post.extended_object.get_title():s}</p>',
            html=True,
        )
Exemple #25
0
    def test_cms_plugins_blogpost_fallback_when_published_unpublished(self):
        """
        The blogpost plugin should not render when the blogpost was voluntarily
        unpublished in the current language.
        """
        # Create a blogpost
        blogpost = BlogPostFactory(
            page_title={
                "en": "public title",
                "fr": "titre public"
            },
            fill_cover={
                "original_filename": "cover.jpg",
                "default_alt_text": "my cover",
            },
        )
        blogpost_page = blogpost.extended_object

        # Create a page to add the plugin to
        page = create_i18n_page({"en": "A page", "fr": "Une page"})
        placeholder = page.placeholders.get(slot="maincontent")
        add_plugin(placeholder, BlogPostPlugin, "en",
                   **{"page": blogpost_page})
        add_plugin(placeholder, BlogPostPlugin, "fr",
                   **{"page": blogpost_page})

        # Publish only the French version of the blog post
        with mock.patch(
                "cms.models.pagemodel.now",
                return_value=datetime(2019, 11, 30, tzinfo=timezone.utc),
        ):
            blogpost_page.publish("fr")

        blogpost_page.publish("en")
        blogpost_page.unpublish("en")

        # Check the page content in English
        page.publish("en")
        url = page.get_absolute_url(language="en")
        response = self.client.get(url)

        self.assertNotContains(response, "glimpse")
Exemple #26
0
    def test_cms_plugins_blogpost_form_page_choices(self):
        """
        The form to create a blogpost plugin should only list blogpost pages
        in the select box.
        """
        class BlogPostPluginModelForm(forms.ModelForm):
            """A form for testing the choices in the select box"""
            class Meta:
                model = BlogPostPluginModel
                fields = ["page"]

        blog_page = create_i18n_page("my title", published=True)
        blogpost = BlogPostFactory(page_parent=blog_page)
        other_page_title = "other page"
        create_page(other_page_title, "richie/single_column.html",
                    settings.LANGUAGE_CODE)
        plugin_form = BlogPostPluginModelForm()
        rendered_form = plugin_form.as_table()
        self.assertEqual(
            rendered_form.count(blogpost.extended_object.get_title()), 1)
        self.assertNotIn(other_page_title, plugin_form.as_table())
    def test_factories_blogpost_cover(self):
        """
        BlogPostFactory should be able to generate plugins with a realistic cover for several
        languages.
        """
        blogpost = BlogPostFactory(page_languages=["fr", "en"],
                                   fill_cover=True)

        # Check that the cover plugins were created as expected
        cover = blogpost.extended_object.placeholders.get(slot="cover")
        self.assertEqual(cover.cmsplugin_set.count(), 2)

        # The cover plugins should point to one of our fixtures images
        for language in ["fr", "en"]:
            cover_plugin = cover.cmsplugin_set.get(
                plugin_type="SimplePicturePlugin", language=language)
            self.assertIn(
                "cover",
                os.path.basename(
                    cover_plugin.djangocms_picture_picture.picture.file.name),
            )
    def test_templates_blogpost_detail_meta_description(self):
        """
        The blogpost meta description should show meta_description placeholder if defined
        """
        blogpost = BlogPostFactory()
        page = blogpost.extended_object

        title_obj = page.get_title_obj(language="en")
        title_obj.meta_description = "A custom description of the blog post"
        title_obj.save()

        page.publish("en")

        url = blogpost.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        self.assertContains(
            response,
            '<meta name="description" content="A custom description of the blog post" />',
        )
    def test_templates_blogpost_detail_cms_published_content(self):
        """
        Validate that the important elements are displayed on a published blogpost page
        """
        author = PersonFactory(page_title={"en": "Comte de Saint-Germain"},
                               should_publish=True)
        blogpost = BlogPostFactory(page_title="Preums",
                                   fill_cover=True,
                                   fill_body=True,
                                   fill_author=[author])
        page = blogpost.extended_object

        # The page should not be visible before it is published
        url = page.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

        # Publish the blogpost with a past date and ensure the content is correct
        with mock.patch(
                "cms.models.pagemodel.now",
                return_value=datetime(2019, 11, 27, tzinfo=timezone.utc),
        ):
            page.publish("en")

        response = self.client.get(url)

        self.assertContains(response,
                            "<title>Preums</title>",
                            html=True,
                            status_code=200)
        self.assertContains(response,
                            '<h1 class="blogpost-detail__title">Preums</h1>',
                            html=True)
        self.assertNotContains(response, "Comte de Saint-Germain", html=True)

        self.assertContains(
            response,
            '<p class="blogpost-detail__pubdate">11/27/2019</p>',
            html=True,
        )
    def test_models_category_get_blogposts_public_category_page(self):
        """
        When a category is added on a draft blog post, the blog post should not be visible on
        the public category page until the blog post is published.
        """
        category = CategoryFactory(should_publish=True)
        category_page = category.extended_object
        blog_post = BlogPostFactory(page_title="my title", should_publish=True)
        blog_post_page = blog_post.extended_object

        # Add a category to the blog post but don't publish the modification
        placeholder = blog_post_page.placeholders.get(slot="categories")
        add_plugin(placeholder, CategoryPlugin, "en", page=category_page)

        self.assertEqual(list(category.get_blogposts()), [blog_post])
        self.assertEqual(list(category.public_extension.get_blogposts()), [])

        # Now publish the modification and check that the blog post is displayed
        # on the public category page
        blog_post.extended_object.publish("en")
        self.assertEqual(
            list(category.public_extension.get_blogposts()),
            [blog_post.public_extension],
        )