Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_templates_organization_detail_cms_published_content_max_courses(
self, _mock_page_url
):
"""
Make sure the organization detail page does not display too many courses, even when a large
number are related to the current organization, as this can cause the page to load very
slowly and is not a great experience for the user anyway.
"""
# Create our dummy organization and the 3 courses we'll attach to it
organization = OrganizationFactory(should_publish=True)
courses = CourseFactory.create_batch(
3, fill_organizations=[organization], should_publish=True
)
# Link the 3 courses with our organization through the relevant placeholder
for course in courses:
add_plugin(
course.extended_object.placeholders.get(slot="course_organizations"),
OrganizationPlugin,
"en",
page=organization.extended_object,
)
# Make sure we do have 3 courses on the organization
self.assertEqual(organization.get_courses().count(), 3)
# Only the first two are rendered in the template
response = self.client.get(organization.extended_object.get_absolute_url())
self.assertContains(response, courses[0].extended_object.get_title())
def test_templates_program_detail_cms_draft_content(self):
"""
A staff user should see a draft program including its draft elements with an
annotation.
"""
user = UserFactory(is_staff=True, is_superuser=True)
self.client.login(username=user.username, password="password")
courses = CourseFactory.create_batch(4)
program = ProgramFactory(
page_title="Preums",
fill_cover=True,
fill_excerpt=True,
fill_body=True,
fill_courses=courses,
)
page = program.extended_object
# Publish only 2 out of 4 courses
courses[0].extended_object.publish("en")
courses[1].extended_object.publish("en")
# The unpublished objects may have been published and unpublished which puts them in a
# status different from objects that have never been published.
# We want to test both cases.
def test_signals_categories(self, mock_bulk, *_):
"""
Publishing a category should update its document in the Elasticsearch categories
index, and the documents for published courses to which it is related, excluding snapshots.
"""
parent = CategoryFactory(should_publish=True)
category = CategoryFactory(page_parent=parent.extended_object)
published_course, _unpublished_course = CourseFactory.create_batch(
2, fill_categories=[category]
)
published_course.extended_object.publish("en")
published_course.refresh_from_db()
self.run_commit_hooks()
mock_bulk.reset_mock()
category.extended_object.publish("en")
category.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"]), 3)
def test_models_category_get_courses_descendants(self):
"""
Related courses should include the courses 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)
courses = CourseFactory.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
)
courses_child = CourseFactory.create_batch(
2, fill_categories=[child_category], should_publish=True
)
category = CategoryFactory(extended_object=category_page, should_publish=True)
courses = CourseFactory.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
)
courses_child = CourseFactory.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
)
courses_grand_child = CourseFactory.create_batch(
2, fill_categories=[grand_child_category], should_publish=True
)
number are related to the current category, as this can cause the page to load very slowly
and is not a great experience for the user anyway.
"""
# Create our dummy category and the 3 courses we'll attach to it
meta = CategoryFactory(
page_parent=create_i18n_page(
{"en": "Categories", "fr": "Catégories"}, published=True
),
page_reverse_id="subjects",
page_title={"en": "Subjects", "fr": "Sujets"},
should_publish=True,
)
category = CategoryFactory(
page_parent=meta.extended_object, should_publish=True
)
courses = CourseFactory.create_batch(
3, fill_categories=[category], should_publish=True
)
# Link the 3 courses with our category through the relevant placeholder
for course in courses:
add_plugin(
course.extended_object.placeholders.get(slot="course_categories"),
CategoryPlugin,
"en",
page=category.extended_object,
)
# Make sure we do have 3 courses on the category
self.assertEqual(category.get_courses().count(), 3)
# Only the first two are rendered in the template
response = self.client.get(category.extended_object.get_absolute_url())
self.assertContains(response, courses[0].extended_object.get_title())
def test_signals_categories_no_parent(self, mock_bulk, *_):
"""
Publishing a category should update its document in the Elasticsearch categories
index, and the documents for published courses to which it is related, excluding snapshots.
"""
category = CategoryFactory()
published_course, _unpublished_course = CourseFactory.create_batch(
2, fill_categories=[category]
)
published_course.extended_object.publish("en")
published_course.refresh_from_db()
self.run_commit_hooks()
mock_bulk.reset_mock()
category.extended_object.publish("en")
category.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)
def test_models_category_get_courses_queries(self):
"""
It should be possible to retrieve the list of related courses on the category instance.
The number of queries should be minimal.
"""
category = CategoryFactory(should_publish=True)
courses = CourseFactory.create_batch(
3, page_title="my title", fill_categories=[category], should_publish=True
)
retrieved_courses = category.get_courses()
with self.assertNumQueries(2):
self.assertEqual(list(retrieved_courses), courses)
with self.assertNumQueries(0):
for course in retrieved_courses:
self.assertEqual(
course.extended_object.prefetched_titles[0].title, "my title"
)
)
courses_child = CourseFactory.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
)
courses_grand_child = CourseFactory.create_batch(
2, fill_categories=[grand_child_category], should_publish=True
)
# Check that each category gets courses from its descendants
# ...unless we pass an argument to deactivate it
self.assertEqual(
list(category.get_courses()), courses + courses_child + courses_grand_child
)
self.assertEqual(list(category.get_courses(include_descendants=False)), courses)
self.assertEqual(
list(child_category.get_courses()), courses_child + courses_grand_child
)
self.assertEqual(
list(child_category.get_courses(include_descendants=False)), courses_child
)