From 6b869dc2977cdce28e4d6e607b7e313c0df6e2d3 Mon Sep 17 00:00:00 2001 From: Tiago-Salles Date: Mon, 16 Dec 2024 17:20:22 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(backend)=20skip=20hidden=20course?= =?UTF-8?q?=20runs=20from=20state=20calculation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - On the state property skip the hidden ones --- CHANGELOG.md | 1 + src/richie/apps/courses/models/course.py | 2 +- .../courses/test_templates_category_detail.py | 46 ++++++++++++++++++ .../test_templates_organization_detail.py | 48 +++++++++++++++++++ .../courses/test_templates_person_detail.py | 46 ++++++++++++++++++ 5 files changed, 142 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b3cd48d3b..155fd5a3d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Versioning](https://semver.org/spec/v2.0.0.html). ### Fixed +- Skip hidden course runs from state calculation - Fix frontend translation of Enroll now for external LMS backend ## [2.33.0] - 2024-12-02 diff --git a/src/richie/apps/courses/models/course.py b/src/richie/apps/courses/models/course.py index ddb491bbe2..f6e70ee08c 100644 --- a/src/richie/apps/courses/models/course.py +++ b/src/richie/apps/courses/models/course.py @@ -633,7 +633,7 @@ def state(self): for course_run in self.course_runs.only( "start", "end", "enrollment_start", "enrollment_end" - ): + ).exclude(catalog_visibility=CourseRunCatalogVisibility.HIDDEN): state = course_run.state best_state = min(state, best_state) if state["priority"] == CourseState.ONGOING_OPEN: diff --git a/tests/apps/courses/test_templates_category_detail.py b/tests/apps/courses/test_templates_category_detail.py index 9299ef0d6a..5b5e461e3f 100644 --- a/tests/apps/courses/test_templates_category_detail.py +++ b/tests/apps/courses/test_templates_category_detail.py @@ -2,6 +2,7 @@ End-to-end tests for the category detail view """ +import datetime import re from unittest import mock @@ -18,9 +19,11 @@ BlogPostFactory, CategoryFactory, CourseFactory, + CourseRunFactory, OrganizationFactory, PersonFactory, ) +from richie.apps.courses.models.course import CourseRun, CourseRunCatalogVisibility from richie.plugins.nesteditem.defaults import ACCORDION @@ -715,3 +718,46 @@ def test_template_category_detail_additional_info_page_id(self): self.assertEqual(response.status_code, 200) self.assertNotContains(response, message) + + def test_templates_category_detail_cms_published_hidden_courses(self): + """ + Ensures that changing the course run `catalog_visibility` paratemer + will prevent it from showing on the category detail page + """ + + category = CategoryFactory(should_publish=True) + course = CourseFactory.create(fill_categories=[category], should_publish=True) + CourseRunFactory.create( + direct_course=course, + catalog_visibility=CourseRunCatalogVisibility.COURSE_AND_SEARCH, + start=datetime.datetime.now(), + end=datetime.datetime.now() + datetime.timedelta(days=5), + enrollment_start=datetime.datetime.now() - datetime.timedelta(days=2), + enrollment_end=datetime.datetime.now() - datetime.timedelta(days=1), + ) + + course.refresh_from_db() + add_plugin( + course.extended_object.placeholders.get(slot="course_categories"), + CategoryPlugin, + "en", + page=category.extended_object, + ) + + courses_query = category.get_courses() + + self.assertEqual(courses_query.count(), 1) + self.assertEqual(course.state["priority"], 5) + self.assertEqual(course.state["text"], "on-going") + + course_runs = CourseRun.objects.filter(direct_course=course) + self.assertEqual(len(course_runs), 1) + + course_runs[0].catalog_visibility = CourseRunCatalogVisibility.HIDDEN + course_runs[0].save() + + courses_query = category.get_courses() + + self.assertEqual(courses_query.count(), 1) + self.assertEqual(course.state["priority"], 7) + self.assertEqual(course.state["text"], "to be scheduled") diff --git a/tests/apps/courses/test_templates_organization_detail.py b/tests/apps/courses/test_templates_organization_detail.py index b8429b5030..6a71dfc91f 100644 --- a/tests/apps/courses/test_templates_organization_detail.py +++ b/tests/apps/courses/test_templates_organization_detail.py @@ -2,6 +2,7 @@ End-to-end tests for the organization detail view """ +import datetime import re from unittest import mock @@ -16,9 +17,11 @@ from richie.apps.courses.factories import ( CategoryFactory, CourseFactory, + CourseRunFactory, OrganizationFactory, PersonFactory, ) +from richie.apps.courses.models.course import CourseRun, CourseRunCatalogVisibility class OrganizationCMSTestCase(CMSTestCase): @@ -698,3 +701,48 @@ def test_templates_organization_detail_with_related_organizations(self): section = html.cssselect(".organization-detail__organizations")[0] organization_glimpse = section.cssselect(".section__items--organizations > *") self.assertEqual(len(organization_glimpse), 2) + + def test_templates_organization_detail_cms_published_hidden_courses(self): + """ + Ensures that changing the course run `catalog_visibility` paratemer + will prevent it from showing on the organization detail page + """ + + organization = OrganizationFactory(should_publish=True) + course = CourseFactory.create( + fill_organizations=[organization], should_publish=True + ) + CourseRunFactory.create( + direct_course=course, + catalog_visibility=CourseRunCatalogVisibility.COURSE_AND_SEARCH, + start=datetime.datetime.now(), + end=datetime.datetime.now() + datetime.timedelta(days=5), + enrollment_start=datetime.datetime.now() - datetime.timedelta(days=2), + enrollment_end=datetime.datetime.now() - datetime.timedelta(days=1), + ) + + course.refresh_from_db() + add_plugin( + course.extended_object.placeholders.get(slot="course_organizations"), + OrganizationPlugin, + "en", + page=organization.extended_object, + ) + + courses_query = organization.get_courses() + + self.assertEqual(courses_query.count(), 1) + self.assertEqual(course.state["priority"], 5) + self.assertEqual(course.state["text"], "on-going") + + course_runs = CourseRun.objects.filter(direct_course=course) + self.assertEqual(len(course_runs), 1) + + course_runs[0].catalog_visibility = CourseRunCatalogVisibility.HIDDEN + course_runs[0].save() + + courses_query = organization.get_courses() + + self.assertEqual(courses_query.count(), 1) + self.assertEqual(course.state["priority"], 7) + self.assertEqual(course.state["text"], "to be scheduled") diff --git a/tests/apps/courses/test_templates_person_detail.py b/tests/apps/courses/test_templates_person_detail.py index 66211ebbd8..800357be39 100644 --- a/tests/apps/courses/test_templates_person_detail.py +++ b/tests/apps/courses/test_templates_person_detail.py @@ -2,6 +2,7 @@ End-to-end tests for the person detail view """ +import datetime import re from unittest import mock @@ -22,9 +23,11 @@ BlogPostFactory, CategoryFactory, CourseFactory, + CourseRunFactory, OrganizationFactory, PersonFactory, ) +from richie.apps.courses.models.course import CourseRun, CourseRunCatalogVisibility class PersonCMSTestCase(CMSTestCase): @@ -661,3 +664,46 @@ def test_templates_person_detail_meta_description_empty(self): response, '