Beispiel #1
0
    def test_models_person_get_courses_snapshots(self):
        """
        Snapshot courses should be excluded from the list of courses returned.
        The new filter query we added to exclude snapshots should not create duplicates.
        Indeed, we had to add a "distinct" clause to the query so this test enforces it.
        """
        # We create a root page because it was responsible for duplicate results when the
        # distinct clause is not applied.
        # This is because of the clause "extended_object__node__parent__cms_pages__..."
        # which is there to exclude snapshots but also acts on the main course page and
        # checks its parent (so the root page) and the duplicate comes from the fact that
        # the parent has a draft and a public page... so "cms_pages" has a cardinality of 2
        root_page = create_i18n_page("my title", published=True)

        person = PersonFactory(should_publish=True)
        course = CourseFactory(page_parent=root_page,
                               fill_team=[person],
                               should_publish=True)
        CourseFactory(page_parent=course.extended_object,
                      fill_team=[person],
                      should_publish=True)

        self.assertEqual(Course.objects.count(), 4)
        self.assertEqual(person.get_courses().count(), 1)
        self.assertEqual(person.public_extension.get_courses().count(), 1)
Beispiel #2
0
    def test_models_person_get_courses_public_person_page(self):
        """
        When a person is added on a draft course, the course should not be visible on
        the public person page until the course is published.
        """
        person = PersonFactory(should_publish=True)
        person_page = person.extended_object
        course = CourseFactory(page_title="my title", should_publish=True)
        course_page = course.extended_object

        # Add a person to the course but don't publish the modification
        placeholder = course_page.placeholders.get(slot="course_team")
        add_plugin(placeholder, PersonPlugin, "en", page=person_page)

        self.assertEqual(list(person.get_courses()), [course])
        self.assertEqual(list(person.public_extension.get_courses()), [])

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

        # If the course is unpublished, it should not be displayed on the public
        # page anymore
        course_page.unpublish("en")
        self.assertEqual(list(person.get_courses()), [course])
        self.assertEqual(list(person.public_extension.get_courses()), [])
Beispiel #3
0
    def test_signals_persons_publish(self, mock_bulk, *_):
        """
        Publishing a person should update its document in the Elasticsearch persons
        index, and the documents for published courses to which it is related, excluding snapshots.
        """
        person = PersonFactory()
        published_course, _unpublished_course = CourseFactory.create_batch(
            2, fill_team=[person])
        self.assertTrue(published_course.extended_object.publish("en"))
        published_course.refresh_from_db()
        self.run_commit_hooks()
        mock_bulk.reset_mock()

        self.assertTrue(person.extended_object.publish("en"))
        person.refresh_from_db()

        # Elasticsearch should not be called before the db transaction is successful
        self.assertFalse(mock_bulk.called)
        self.run_commit_hooks()

        self.assertEqual(mock_bulk.call_count, 1)
        self.assertEqual(len(mock_bulk.call_args[1]["actions"]), 2)
        actions = list(mock_bulk.call_args[1]["actions"])
        self.assertEqual(actions[0]["_id"], published_course.get_es_id())
        self.assertEqual(actions[0]["_op_type"], "index")
        self.assertEqual(actions[0]["_index"], "test_courses")
        self.assertEqual(actions[1]["_id"], person.get_es_id())
        self.assertEqual(actions[1]["_op_type"], "index")
        self.assertEqual(actions[1]["_index"], "richie_persons")
Beispiel #4
0
    def test_models_course_get_persons_language(self):
        """
        The `get_persons` method should only return persons linked to a course by a plugin
        in the current language.
        """
        person_fr = PersonFactory(page_languages=["fr"])
        person_en = PersonFactory(page_languages=["en"])

        course = CourseFactory(should_publish=True)
        placeholder = course.extended_object.placeholders.get(
            slot="course_team")

        add_plugin(
            language="en",
            placeholder=placeholder,
            plugin_type="PersonPlugin",
            page=person_en.extended_object,
        )
        add_plugin(
            language="fr",
            placeholder=placeholder,
            plugin_type="PersonPlugin",
            page=person_fr.extended_object,
        )

        with translation.override("fr"):
            self.assertEqual(list(course.get_persons()), [person_fr])

        with translation.override("en"):
            self.assertEqual(list(course.get_persons()), [person_en])
Beispiel #5
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()), [])
Beispiel #6
0
 def test_get_es_id_for_draft_person_with_public_extension(self):
     """
     A draft person with a public extension. Its ES ID is the ID of the page linked to the
     public extension.
     """
     person = PersonFactory(should_publish=True)
     self.assertEqual(person.get_es_id(),
                      str(person.public_extension.extended_object_id))
Beispiel #7
0
    def test_models_category_get_persons_descendants(self):
        """
        Related persons should include the persons linked to the category's descendants,
        unless specifically deactivated by the "include_descendants" argument.
        """
        category_page = create_page("Subjects",
                                    "courses/cms/category_detail.html",
                                    "en",
                                    published=True)
        category = CategoryFactory(extended_object=category_page,
                                   should_publish=True)
        persons = PersonFactory.create_batch(2,
                                             fill_categories=[category],
                                             should_publish=True)

        child_category_page = create_page(
            "Literature",
            "courses/cms/category_detail.html",
            "en",
            parent=category_page,
            published=True,
        )
        child_category = CategoryFactory(extended_object=child_category_page,
                                         should_publish=True)
        persons_child = PersonFactory.create_batch(
            2, fill_categories=[child_category], should_publish=True)

        grand_child_category_page = create_page(
            "Literature",
            "courses/cms/category_detail.html",
            "en",
            parent=child_category_page,
            published=True,
        )
        grand_child_category = CategoryFactory(
            extended_object=grand_child_category_page, should_publish=True)
        persons_grand_child = PersonFactory.create_batch(
            2, fill_categories=[grand_child_category], should_publish=True)

        # Check that each category gets persons from its descendants
        # ...unless we pass an argument to deactivate it
        self.assertEqual(list(category.get_persons()),
                         persons + persons_child + persons_grand_child)
        self.assertEqual(list(category.get_persons(include_descendants=False)),
                         persons)

        self.assertEqual(list(child_category.get_persons()),
                         persons_child + persons_grand_child)
        self.assertEqual(
            list(child_category.get_persons(include_descendants=False)),
            persons_child)

        self.assertEqual(
            list(grand_child_category.get_persons(include_descendants=False)),
            persons_grand_child,
        )
        self.assertEqual(list(grand_child_category.get_persons()),
                         persons_grand_child)
Beispiel #8
0
 def test_models_person_get_courses_several_languages(self):
     """
     The courses should not be duplicated if they exist in several languages.
     """
     person = PersonFactory(should_publish=True)
     CourseFactory(
         page_title={
             "en": "my title",
             "fr": "mon titre"
         },
         fill_team=[person],
         should_publish=True,
     )
     self.assertEqual(Course.objects.count(), 2)
     self.assertEqual(person.get_courses().count(), 1)
Beispiel #9
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_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_person_detail_open_graph_description_bio(self):
        """
        An opengraph description meta should be present if the person bio placeholder is set.
        """
        person = PersonFactory()
        page = person.extended_object

        # Add a bio to a person
        placeholder = person.extended_object.placeholders.get(slot="bio")
        add_plugin(
            language="en",
            placeholder=placeholder,
            plugin_type="PlainTextPlugin",
            body="A biographic description of the person",
        )
        page.publish("en")

        url = person.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 biographic description of the person" />',
        )
Beispiel #12
0
    def test_cms_plugins_person_fallback_when_published_unpublished(self):
        """
        The person plugin should not render when the person was voluntarily
        unpublished in the current language.
        """
        # Create a person
        person = PersonFactory(
            page_title={
                "en": "public title",
                "fr": "titre public"
            },
            fill_portrait={
                "original_filename": "portrait.jpg",
                "default_alt_text": "my portrait",
            },
        )
        person_page = person.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, PersonPlugin, "en", **{"page": person_page})
        add_plugin(placeholder, PersonPlugin, "fr", **{"page": person_page})

        # Publish only the French version of the person
        person_page.publish("fr")
        person_page.publish("en")
        person_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")
    def test_templates_organization_detail_related_persons(self):
        """
        Persons related to an organization via a plugin should appear on the organization
        detail page.
        """
        user = UserFactory(is_staff=True, is_superuser=True)
        self.client.login(username=user.username, password="******")

        organization = OrganizationFactory()
        person = PersonFactory(fill_organizations=[organization])
        page = organization.extended_object

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

        # The person should be present on the page
        pattern = (
            r'<a href="{url:s}">'
            r'<h2 class="person-glimpse__content__wrapper__title">'
            r".*{name:s}.*</h2></a>"
        ).format(
            url=person.extended_object.get_absolute_url(),
            name=person.extended_object.get_title(),
        )
        self.assertIsNotNone(re.search(pattern, str(response.content)))
Beispiel #14
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_person_detail_cms_published_content_opengraph(self):
        """The person logo should be used as opengraph image."""
        person = PersonFactory(
            fill_portrait={
                "original_filename": "portrait.jpg",
                "default_alt_text": "my portrait",
            },
            should_publish=True,
        )
        url = person.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        self.assertContains(response,
                            '<meta property="og:type" content="profile" />')
        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/.*portrait\.jpg__200x200"
        )
        self.assertIsNotNone(re.search(pattern, str(response.content)))
        self.assertContains(
            response, '<meta property="og:image:width" content="200" />')
        self.assertContains(
            response, '<meta property="og:image:height" content="200" />')
    def test_cms_wizards_person_submit_form_slug_duplicate(self):
        """
        Trying to create a person 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(
            "Persons",
            "richie/single_column.html",
            "en",
            reverse_id=Person.PAGE["reverse_id"],
        )
        # Create an existing page with a known slug
        PersonFactory(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_superuser=True, is_staff=True)
        form = PersonWizardForm(data=data,
                                wizard_language="en",
                                wizard_user=user)
        self.assertFalse(form.is_valid())
        self.assertEqual(form.errors,
                         {"slug": ["This slug is already in use"]})
    def test_templates_person_detail_meta_description_bio(self):
        """
        The person meta description should show the bio if no meta_description is
        specified
        """
        person = PersonFactory()
        page = person.extended_object

        # Add a bio to a person
        placeholder = person.extended_object.placeholders.get(slot="bio")
        add_plugin(
            language="en",
            placeholder=placeholder,
            plugin_type="PlainTextPlugin",
            body="A biographic description of the person",
        )
        page.publish("en")

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

        self.assertContains(
            response,
            '<meta name="description" content="A biographic description of the person" />',
        )
    def test_models_organization_get_persons_public_organization_page(self):
        """
        When a organization is added on a draft person, the person should not be visible on
        the public organization page until the person is published.
        """
        organization = OrganizationFactory(should_publish=True)
        organization_page = organization.extended_object
        person = PersonFactory(page_title="my title", should_publish=True)
        person_page = person.extended_object

        # Add a organization to the person but don't publish the modification
        placeholder = person_page.placeholders.get(slot="organizations")
        add_plugin(placeholder,
                   OrganizationPlugin,
                   "en",
                   page=organization_page)

        self.assertEqual(list(organization.get_persons()), [person])
        self.assertEqual(list(organization.public_extension.get_persons()), [])

        # Now publish the modification and check that the person is displayed
        # on the public organization page
        person.extended_object.publish("en")
        self.assertEqual(list(organization.public_extension.get_persons()),
                         [person.public_extension])
    def test_templates_person_detail_meta_description_bio_exceeds_max_length(
            self):
        """
        The person meta description should be cut if it exceeds more than 160 caracters
        """
        person = PersonFactory()
        page = person.extended_object
        placeholder_value = (
            "Long description that describes the page with a summary. "
            "Long description that describes the page with a summary. "
            "Long description that describes the page with a summary. ")

        # Add a bio to a person
        placeholder = person.extended_object.placeholders.get(slot="bio")
        add_plugin(
            language="en",
            placeholder=placeholder,
            plugin_type="PlainTextPlugin",
            body=placeholder_value,
        )
        page.publish("en")

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

        cut = placeholder_value[0:160]
        self.assertContains(
            response,
            f'<meta name="description" content="{cut}" />',
        )
Beispiel #20
0
    def test_models_course_get_persons_other_placeholders(self):
        """
        The `get_persons` method should return all persons linked to a course via a plugin
        on whichever placeholder.
        """
        person1, person2 = PersonFactory.create_batch(2)

        course = CourseFactory(should_publish=True)
        placeholder1 = course.extended_object.placeholders.get(
            slot="course_description")
        placeholder2 = course.extended_object.placeholders.get(
            slot="course_format")

        add_plugin(
            language="en",
            placeholder=placeholder1,
            plugin_type="PersonPlugin",
            page=person1.extended_object,
        )
        add_plugin(
            language="en",
            placeholder=placeholder2,
            plugin_type="PersonPlugin",
            page=person2.extended_object,
        )

        self.assertEqual(list(course.get_persons()), [person1, person2])
Beispiel #21
0
 def test_get_es_id_for_published_person(self):
     """
     A published person. Its ES ID is the ID of the page linked to it.
     """
     person = PersonFactory(should_publish=True)
     self.assertEqual(
         person.public_extension.get_es_id(),
         str(person.public_extension.extended_object_id),
     )
Beispiel #22
0
    def test_indexers_courses_get_es_document_for_course_related_names_related_unpublished(
        self,
    ):
        """
        When related objects are unpublished in one language, that language should not be taken
        into account to build related object names.
        """
        # Create a course with related pages in both english and french but only
        # published in one language
        category = CategoryFactory(
            page_title={
                "en": "english category title",
                "fr": "titre catégorie français",
            },
            should_publish=True,
        )
        category.extended_object.unpublish("fr")

        organization = OrganizationFactory(
            page_title={
                "en": "english organization title",
                "fr": "titre organisation français",
            },
            should_publish=True,
        )
        organization.extended_object.unpublish("fr")

        person = PersonFactory(
            page_title={"en": "Brian", "fr": "François"}, should_publish=True
        )
        person.extended_object.unpublish("fr")

        course = CourseFactory(
            fill_categories=[category],
            fill_organizations=[organization],
            fill_team=[person],
            page_title={
                "en": "an english course title",
                "fr": "un titre cours français",
            },
            should_publish=True,
        )

        course_document = CoursesIndexer.get_es_document_for_course(course)
        self.assertEqual(
            course_document["organizations_names"],
            {"en": ["english organization title"]},
        )
        self.assertEqual(
            course_document["organization_highlighted"],
            {"en": "english organization title"},
        )
        self.assertEqual(
            course_document["categories_names"], {"en": ["english category title"]}
        )
        self.assertEqual(course_document["persons_names"], {"en": ["Brian"]})
Beispiel #23
0
    def test_cms_plugins_person_fallback_when_never_published(self):
        """
        The person plugin should render in the fallback language when the person
        page has never been published in the current language.
        """
        # Create a person
        person = PersonFactory(
            page_title={
                "en": "public person",
                "fr": "personne publique"
            },
            fill_portrait={
                "original_filename": "portrait.jpg",
                "default_alt_text": "my portrait",
            },
        )
        person_page = person.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, PersonPlugin, "en", **{"page": person_page})
        add_plugin(placeholder, PersonPlugin, "fr", **{"page": person_page})

        # Publish only the French version of the person
        person_page.publish("fr")

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

        # Person's name should be present as a link to the cms page
        self.assertContains(response,
                            '<a href="/en/personne-publique/">',
                            status_code=200)
        # The person's full name should be wrapped in a h2
        self.assertContains(
            response,
            '<h2 class="person-glimpse__title">personne publique</h2>',
            html=True,
        )
        self.assertNotContains(response, "public person")

        # Person's portrait should be present
        pattern = (
            r'<a class="person-glimpse__media" href="/en/personne-publique/" '
            r'tabindex="-1" aria-hidden="true" property="url">'
            r'<img src="/media/filer_public_thumbnails/filer_public/.*portrait\.jpg__200x200'
            r'.*alt="" property="image"')
        content = (htmlmin.minify(
            response.content.decode("UTF-8"),
            reduce_empty_attributes=False,
            remove_optional_attribute_quotes=False,
        ), )
        self.assertIsNotNone(re.search(pattern, str(content)))
Beispiel #24
0
    def test_signals_persons_unpublish(self, mock_bulk, *_):
        """
        Unpublishing a person in a language should update its document in the Elasticsearch
        persons index or delete it if there is no language published anymore.
        It should also reindex the documents for published courses to which it is related,
        excluding snapshots.
        """
        person = PersonFactory(page_languages=["en", "fr"],
                               should_publish=True)
        published_course, _unpublished_course = CourseFactory.create_batch(
            2, fill_team=[person])
        self.assertTrue(published_course.extended_object.publish("en"))
        published_course.refresh_from_db()
        self.run_commit_hooks()
        mock_bulk.reset_mock()

        # - Unpublish the first language
        self.assertTrue(person.extended_object.unpublish("en"))
        person.refresh_from_db()

        # Elasticsearch should not be called before the db transaction is successful
        self.assertFalse(mock_bulk.called)
        self.run_commit_hooks()

        self.assertEqual(mock_bulk.call_count, 1)
        self.assertEqual(len(mock_bulk.call_args[1]["actions"]), 2)
        actions = list(mock_bulk.call_args[1]["actions"])
        self.assertEqual(actions[0]["_id"], published_course.get_es_id())
        self.assertEqual(actions[0]["_op_type"], "index")
        self.assertEqual(actions[0]["_index"], "test_courses")
        self.assertEqual(actions[1]["_id"], person.get_es_id())
        self.assertEqual(actions[1]["_op_type"], "index")
        self.assertEqual(actions[1]["_index"], "richie_persons")

        mock_bulk.reset_mock()

        # - Unpublish the second language
        self.assertTrue(person.extended_object.unpublish("fr"))
        person.refresh_from_db()

        # Elasticsearch should not be called before the db transaction is successful
        self.assertFalse(mock_bulk.called)
        self.run_commit_hooks()

        self.assertEqual(mock_bulk.call_count, 1)
        self.assertEqual(len(mock_bulk.call_args[1]["actions"]), 2)
        actions = list(mock_bulk.call_args[1]["actions"])
        self.assertEqual(actions[0]["_id"], published_course.get_es_id())
        self.assertEqual(actions[0]["_op_type"], "index")
        self.assertEqual(actions[0]["_index"], "test_courses")
        self.assertEqual(actions[1]["_id"], person.get_es_id())
        self.assertEqual(actions[1]["_op_type"], "delete")
        self.assertEqual(actions[1]["_index"], "richie_persons")
Beispiel #25
0
    def test_models_course_get_persons(self):
        """
        The `get_persons` method should return all persons linked to a course and
        should respect publication status.
        """
        # The 2 first persons are grouped in one variable name and will be linked to the
        # course in the following, the third person will not be linked so we can check that
        # only the persons linked to the course are retrieved (its name starts with `_`
        # because it is not used and only here for unpacking purposes)
        *draft_persons, _other_draft = PersonFactory.create_batch(3)
        *published_persons, _other_public = PersonFactory.create_batch(
            3, should_publish=True)
        course = CourseFactory(fill_team=draft_persons + published_persons,
                               should_publish=True)

        self.assertEqual(list(course.get_persons()),
                         draft_persons + published_persons)
        self.assertEqual(list(course.public_extension.get_persons()),
                         published_persons)
Beispiel #26
0
 def test_models_person_str(self):
     """
     The string representation should be built with the page `title`
     and all person fields. Only 1 query to the associated page should be generated.
     """
     page = create_page("Page of Lady Louise Dupont",
                        "courses/cms/person_detail.html", "en")
     person = PersonFactory(extended_object=page)
     with self.assertNumQueries(2):
         self.assertEqual(str(person), "Person: Page of Lady Louise Dupont")
    def test_cms_plugins_person_render_on_public_page_custom_bio(self):
        """
        It should be possible to override the person's bio on the glimpse rendered by the plugin.
        """
        # Create a Person
        person = PersonFactory(
            page_title={"en": "person title", "fr": "titre personne"},
            should_publish=True,
        )

        # Add bio to related placeholder
        bio_placeholder = person.extended_object.placeholders.get(slot="bio")
        add_plugin(
            bio_placeholder, PlainTextPlugin, "en", **{"body": "original public bio"}
        )
        add_plugin(
            bio_placeholder,
            PlainTextPlugin,
            "fr",
            **{"body": "résumé public d'origine"}
        )

        # 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,
            PersonPlugin,
            "en",
            **{"page": person.extended_object, "bio": "custom public bio"}
        )
        add_plugin(
            placeholder,
            PersonPlugin,
            "fr",
            **{"page": person.extended_object, "bio": "résumé public modifié"}
        )
        page.publish("en")
        page.publish("fr")

        # The custom bio should be present on the glimpse and not the original bio

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

        self.assertContains(response, "custom public bio", status_code=200)
        self.assertNotContains(response, "origine")

        # Check the page content in French
        url = page.get_absolute_url(language="fr")
        response = self.client.get(url)

        self.assertContains(response, "résumé public modifié", status_code=200)
        self.assertNotContains(response, "original")
Beispiel #28
0
    def test_models_person_get_courses(self):
        """
        It should be possible to retrieve the list of related courses on the person instance.
        The number of queries should be minimal.
        """
        person = PersonFactory(should_publish=True)
        courses = CourseFactory.create_batch(3,
                                             page_title="my title",
                                             fill_team=[person],
                                             should_publish=True)
        retrieved_courses = person.get_courses()

        with self.assertNumQueries(2):
            self.assertEqual(set(retrieved_courses), set(courses))

        with self.assertNumQueries(0):
            for course in retrieved_courses:
                self.assertEqual(
                    course.extended_object.prefetched_titles[0].title,
                    "my title")
Beispiel #29
0
    def test_templates_person_detail_maincontent_empty(self):
        """
        The "maincontent" placeholder block should not be displayed when empty.
        """
        person = PersonFactory(should_publish=True)

        # The "organizations" section should not be present on the public page
        url = person.public_extension.extended_object.get_absolute_url()
        response = self.client.get(url)
        self.assertContains(response, person.extended_object.get_title())
        self.assertNotContains(response, "person-detail__maincontent")
Beispiel #30
0
    def test_models_person_get_blogposts(self):
        """
        It should be possible to retrieve the list of related blogposts on the person
        instance. The number of queries should be minimal.
        """
        person = PersonFactory(should_publish=True)
        blogposts = BlogPostFactory.create_batch(2,
                                                 page_title="my title",
                                                 fill_author=[person],
                                                 should_publish=True)
        retrieved_blogposts = person.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")