diff --git a/course_discovery/apps/course_metadata/tests/test_utils.py b/course_discovery/apps/course_metadata/tests/test_utils.py index 3a6377977d..af0f155558 100644 --- a/course_discovery/apps/course_metadata/tests/test_utils.py +++ b/course_discovery/apps/course_metadata/tests/test_utils.py @@ -1194,12 +1194,16 @@ class ValidateSlugFormatTest(TestCase): def setUp(self): self.product_source = SourceFactory(slug=settings.DEFAULT_PRODUCT_SOURCE_SLUG) self.external_product_source = SourceFactory(slug=settings.EXTERNAL_PRODUCT_SOURCE_SLUG) - self.course_type = CourseTypeFactory(slug=CourseType.EXECUTIVE_EDUCATION_2U) + self.bootcamp_course_type = CourseTypeFactory(slug=CourseType.BOOTCAMP_2U) + self.exec_ed_course_type = CourseTypeFactory(slug=CourseType.EXECUTIVE_EDUCATION_2U) self.test_course_1 = CourseFactory(title='test-title', product_source=self.product_source) self.test_course_2 = CourseFactory(title='test-title-2') self.test_course_3 = CourseFactory(title='test-title-3', product_source=self.product_source) self.test_course_4 = CourseFactory( - title='test-title-4', product_source=self.external_product_source, type=self.course_type + title='test-title-4', product_source=self.external_product_source, type=self.exec_ed_course_type + ) + self.bootcamp_course = CourseFactory( + title='bootcamp-course', product_source=self.external_product_source, type=self.bootcamp_course_type ) CourseRunFactory(course=self.test_course_1, status=CourseRunStatus.Published) @@ -1352,3 +1356,48 @@ def test_validate_slug_format__raise_exception_for_for_exec_ed_course( expected_error_message = expected_error_message.format(url_slug=slug) actual_error_message = str(context.exception) self.assertIn(expected_error_message, actual_error_message) + + @ddt.data( + ('boot-camps/physics/edx-applied-physics', True), + ('boot-camps/python/harvard-python-for-beginners', True), + ('custom-slug', True), + ('custom-slug', False), + ) + @ddt.unpack + def test_validate_slug_format__for_bootcamps(self, slug, is_subdirectory_slug_format_active): + """ + Test that validate_slug_format to check if the slug is in correct format for bootcamps + """ + with override_waffle_switch(IS_SUBDIRECTORY_SLUG_FORMAT_ENABLED, active=is_subdirectory_slug_format_active): + assert validate_slug_format(slug, self.bootcamp_course) is None + + @ddt.data( + ('boot-camps/primary-subject/org-name-course-name', False), + ('boot-camps/primary-subject/org-name-course-name/', True), + ('boot-camps/primary-subject/org-name-course-name/', False), + ('boot-camps/org-name-course-name', True), + ('learn/test-course', True), + ) + @ddt.unpack + def test_validate_slug_format__raise_exception_for_bootcamp_course(self, slug, is_subdirectory_slug_format_active): + """ + Test that validate_slug_format raises exception if the slug is not in the correct format + for bootcamp courses + """ + expected_error_message = None + + if is_subdirectory_slug_format_active: + expected_error_message = ( + settings.COURSE_URL_SLUGS_PATTERN[settings.EXTERNAL_PRODUCT_SOURCE_SLUG] + .get('bootcamp-2u').get('error_msg') + ) + else: + expected_error_message = DEFAULT_SLUG_FORMAT_ERROR_MSG + + with override_waffle_switch(IS_SUBDIRECTORY_SLUG_FORMAT_ENABLED, active=is_subdirectory_slug_format_active): + with self.assertRaises(ValidationError) as context: + validate_slug_format(slug, self.bootcamp_course) + + expected_error_message = expected_error_message.format(url_slug=slug) + actual_error_message = str(context.exception) + self.assertIn(expected_error_message, actual_error_message) diff --git a/course_discovery/settings/base.py b/course_discovery/settings/base.py index 138aa68fe5..f5a6213195 100644 --- a/course_discovery/settings/base.py +++ b/course_discovery/settings/base.py @@ -710,6 +710,10 @@ {'default': { 'slug_format': '', 'error_msg': '', + }, + 'bootcamp-2u': { + 'slug_format': '', + 'error_msg': '', }}, 'ext-source': {'default': { @@ -719,6 +723,10 @@ 'executive-education-2u': { 'slug_format': '', 'error_msg': '', + }, + 'bootcamp-2u': { + 'slug_format': '', + 'error_msg': '', }} } diff --git a/course_discovery/settings/test.py b/course_discovery/settings/test.py index 0b24e8aa1f..0ce23636fd 100644 --- a/course_discovery/settings/test.py +++ b/course_discovery/settings/test.py @@ -126,12 +126,17 @@ SLUG_FORMAT_REGEX = '[a-zA-Z0-9-_]+$' SUBDIRECTORY_SLUG_FORMAT_REGEX = 'learn/[a-zA-Z0-9-_]+/[a-zA-Z0-9-_]+$' EXEC_ED_SLUG_FORMAT_REGEX = 'executive-education/[a-zA-Z0-9-_]+$' +BOOTCAMP_SLUG_FORMAT_REGEX = 'boot-camps/[a-zA-Z0-9-_]+/[a-zA-Z0-9-_]+$' COURSE_URL_SLUGS_PATTERN = { 'test-source': {'default': { 'slug_format': f'{SLUG_FORMAT_REGEX}|{SUBDIRECTORY_SLUG_FORMAT_REGEX}', 'error_msg': 'Course edit was unsuccessful. The course URL slug "[{url_slug}]" is an invalid format. Please ensure that the slug is in the format `learn//-`', + }, + 'bootcamp-2u': { + 'slug_format': f'{SLUG_FORMAT_REGEX}|{BOOTCAMP_SLUG_FORMAT_REGEX}', + 'error_msg': 'Course edit was unsuccessful. The course URL slug "[{url_slug}]" is an invalid format. Please ensure that the slug is in the format `boot-camps//-`', }}, 'external-test-source': {'default': { @@ -141,5 +146,9 @@ 'executive-education-2u': { 'slug_format': f'{SLUG_FORMAT_REGEX}|{EXEC_ED_SLUG_FORMAT_REGEX}', 'error_msg': 'Course edit was unsuccessful. The course URL slug "[{url_slug}]" is an invalid format. Please ensure that the slug is in the format `executive-education/-`', - }} + }, + 'bootcamp-2u': { + 'slug_format': f'{SLUG_FORMAT_REGEX}|{BOOTCAMP_SLUG_FORMAT_REGEX}', + 'error_msg': 'Course edit was unsuccessful. The course URL slug "[{url_slug}]" is an invalid format. Please ensure that the slug is in the format `boot-camps//-`', + }}, }