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_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_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_models_category_get_blogposts_descendants(self): """ Related blogposts should include the blogposts 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) blogposts = BlogPostFactory.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) blogposts_child = BlogPostFactory.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) blogposts_grand_child = BlogPostFactory.create_batch( 2, fill_categories=[grand_child_category], should_publish=True) # Check that each category gets blogposts from its descendants # ...unless we pass an argument to deactivate it self.assertEqual( list(category.get_blogposts()), blogposts + blogposts_child + blogposts_grand_child, ) self.assertEqual( list(category.get_blogposts(include_descendants=False)), blogposts) self.assertEqual( list(child_category.get_blogposts()), blogposts_child + blogposts_grand_child, ) self.assertEqual( list(child_category.get_blogposts(include_descendants=False)), blogposts_child, ) self.assertEqual( list( grand_child_category.get_blogposts(include_descendants=False)), blogposts_grand_child, ) self.assertEqual(list(grand_child_category.get_blogposts()), blogposts_grand_child)
def test_models_person_get_blogposts_language_fallback_published(self): """ Validate that the reverse blogposts lookup works as expected with language fallback on a published page. """ person1, person2, person3 = PersonFactory.create_batch( 3, should_publish=True) public_person1 = person1.public_extension public_person2 = person2.public_extension public_person3 = person3.public_extension blogpost, blogpost_unpublished = BlogPostFactory.create_batch( 2, page_languages=["en", "fr", "de"], should_publish=True) public_blogpost = blogpost.public_extension public_blogpost_unpublished = blogpost_unpublished.public_extension blogpost_unpublished.extended_object.unpublish("en") blogpost_unpublished.extended_object.unpublish("fr") blogpost_unpublished.extended_object.unpublish("de") placeholder = public_blogpost.extended_object.placeholders.get( slot="author") placeholder_unpublished = ( public_blogpost_unpublished.extended_object.placeholders.get( slot="author")) # Reverse plugin lookups should fallback up to the second priority language add_plugin( language="de", placeholder=placeholder, plugin_type="PersonPlugin", **{"page": person1.extended_object}, ) add_plugin( language="de", placeholder=placeholder_unpublished, plugin_type="PersonPlugin", **{"page": person1.extended_object}, ) with translation.override("en"): self.assertEqual(list(public_person1.get_blogposts()), [public_blogpost]) self.assertEqual(list(public_person2.get_blogposts()), []) self.assertEqual(list(public_person3.get_blogposts()), []) with translation.override("fr"): self.assertEqual(list(public_person1.get_blogposts()), [public_blogpost]) self.assertEqual(list(public_person2.get_blogposts()), []) self.assertEqual(list(public_person3.get_blogposts()), []) with translation.override("de"): self.assertEqual(list(public_person1.get_blogposts()), [public_blogpost]) self.assertEqual(list(public_person2.get_blogposts()), []) self.assertEqual(list(public_person3.get_blogposts()), []) # Reverse plugin lookups should fallback to the first priority language if available # and ignore the second priority language unless it is the current language add_plugin( language="fr", placeholder=placeholder, plugin_type="PersonPlugin", **{"page": person2.extended_object}, ) add_plugin( language="fr", placeholder=placeholder_unpublished, plugin_type="PersonPlugin", **{"page": person2.extended_object}, ) with translation.override("en"): self.assertEqual(list(public_person1.get_blogposts()), []) self.assertEqual(list(public_person2.get_blogposts()), [public_blogpost]) self.assertEqual(list(public_person3.get_blogposts()), []) with translation.override("fr"): self.assertEqual(list(public_person1.get_blogposts()), []) self.assertEqual(list(public_person2.get_blogposts()), [public_blogpost]) self.assertEqual(list(public_person3.get_blogposts()), []) with translation.override("de"): self.assertEqual(list(public_person1.get_blogposts()), [public_blogpost]) self.assertEqual(list(public_person2.get_blogposts()), []) self.assertEqual(list(public_person3.get_blogposts()), []) # Reverse plugin lookups should stick to the current language if available and # ignore plugins on fallback languages add_plugin( language="en", placeholder=placeholder, plugin_type="PersonPlugin", **{"page": person3.extended_object}, ) add_plugin( language="en", placeholder=placeholder_unpublished, plugin_type="PersonPlugin", **{"page": person3.extended_object}, ) with translation.override("en"): self.assertEqual(list(public_person1.get_blogposts()), []) self.assertEqual(list(public_person2.get_blogposts()), []) self.assertEqual(list(public_person3.get_blogposts()), [public_blogpost]) with translation.override("fr"): self.assertEqual(list(public_person1.get_blogposts()), []) self.assertEqual(list(public_person2.get_blogposts()), [public_blogpost]) self.assertEqual(list(public_person3.get_blogposts()), []) with translation.override("de"): self.assertEqual(list(public_person1.get_blogposts()), [public_blogpost]) self.assertEqual(list(public_person2.get_blogposts()), []) self.assertEqual(list(public_person3.get_blogposts()), [])