Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: autogeneration of bootcamp url slug #4076

Merged
merged 2 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions course_discovery/apps/course_metadata/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
)
from course_discovery.apps.course_metadata.query import CourseQuerySet, CourseRunQuerySet, ProgramQuerySet
from course_discovery.apps.course_metadata.toggles import (
IS_SUBDIRECTORY_SLUG_FORMAT_ENABLED, IS_SUBDIRECTORY_SLUG_FORMAT_FOR_EXEC_ED_ENABLED
IS_SUBDIRECTORY_SLUG_FORMAT_ENABLED, IS_SUBDIRECTORY_SLUG_FORMAT_FOR_BOOTCAMP_ENABLED,
IS_SUBDIRECTORY_SLUG_FORMAT_FOR_EXEC_ED_ENABLED
)
from course_discovery.apps.course_metadata.utils import (
UploadToFieldNamePath, clean_query, custom_render_variations, get_slug_for_course, is_ocm_course,
Expand Down Expand Up @@ -1862,10 +1863,13 @@ def set_subdirectory_slug(self):
"""
is_slug_in_subdirectory_format = bool(re.match(SUBDIRECTORY_SLUG_FORMAT_REGEX, self.active_url_slug))
is_exec_ed_course = self.type.slug == CourseType.EXECUTIVE_EDUCATION_2U
is_bootcamp_course = self.type.slug == CourseType.BOOTCAMP_2U
if is_exec_ed_course and not IS_SUBDIRECTORY_SLUG_FORMAT_FOR_EXEC_ED_ENABLED.is_enabled():
return
if is_bootcamp_course and not IS_SUBDIRECTORY_SLUG_FORMAT_FOR_BOOTCAMP_ENABLED.is_enabled():
return
is_open_course = is_ocm_course(self)
if not is_slug_in_subdirectory_format and (is_exec_ed_course or is_open_course):
if not is_slug_in_subdirectory_format and (is_exec_ed_course or is_open_course or is_bootcamp_course):
slug, error = get_slug_for_course(self)
if slug:
self.set_active_url_slug(slug)
Expand Down
56 changes: 54 additions & 2 deletions course_discovery/apps/course_metadata/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from django.core.management import call_command
from django.db import IntegrityError, transaction
from django.test import TestCase, override_settings
from edx_toggles.toggles.testutils import override_waffle_switch
from freezegun import freeze_time
from slugify import slugify
from taggit.models import Tag
Expand All @@ -44,10 +45,13 @@
)
from course_discovery.apps.course_metadata.tests import factories
from course_discovery.apps.course_metadata.tests.factories import (
AdditionalMetadataFactory, CourseFactory, CourseRunFactory, CourseUrlSlugFactory, ImageFactory, PartnerFactory,
ProgramFactory, SeatFactory, SeatTypeFactory, SourceFactory
AdditionalMetadataFactory, CourseFactory, CourseRunFactory, CourseTypeFactory, CourseUrlSlugFactory, ImageFactory,
OrganizationFactory, PartnerFactory, ProgramFactory, SeatFactory, SeatTypeFactory, SourceFactory, SubjectFactory
)
from course_discovery.apps.course_metadata.tests.mixins import MarketingSitePublisherTestMixin
from course_discovery.apps.course_metadata.toggles import (
IS_SUBDIRECTORY_SLUG_FORMAT_ENABLED, IS_SUBDIRECTORY_SLUG_FORMAT_FOR_BOOTCAMP_ENABLED
)
from course_discovery.apps.course_metadata.utils import ensure_draft_world
from course_discovery.apps.course_metadata.utils import logger as utils_logger
from course_discovery.apps.ietf_language_tags.models import LanguageTag
Expand Down Expand Up @@ -105,6 +109,54 @@ def test_watchers(self):
course.refresh_from_db()
assert course.watchers == ['[email protected]']

@ddt.data(
(True, True),
(True, False),
(False, False),
)
@ddt.unpack
def test_automate_url_restructuring_for_bootcamps_with_feature_flag_state(
self, is_subdirectory_slug_format_enabled, is_subdirectory_slug_format_for_bootcamp_enabled
):
"""
Tests automate url slug restructuring for bootcamps must work under its relevant feature flag
"""
bootcamp_type = CourseTypeFactory(slug=CourseType.BOOTCAMP_2U)
bootcamp_course_draft = CourseFactory(draft=True, type=bootcamp_type)
draft_course_run = CourseRunFactory(draft=True, course=bootcamp_course_draft)
subject = SubjectFactory(name='Subject1')
org = OrganizationFactory(name='organization1')
bootcamp_course_draft.subjects.add(subject)
bootcamp_course_draft.authoring_organizations.add(org)
bootcamp_course_draft.save()

draft_course_run.status = CourseRunStatus.Unpublished
draft_course_run.save()
active_url_slug = draft_course_run.course.active_url_slug

with override_waffle_switch(IS_SUBDIRECTORY_SLUG_FORMAT_ENABLED, active=is_subdirectory_slug_format_enabled):
with override_waffle_switch(IS_SUBDIRECTORY_SLUG_FORMAT_FOR_BOOTCAMP_ENABLED,
active=is_subdirectory_slug_format_for_bootcamp_enabled):
draft_course_run.status = CourseRunStatus.LegalReview
draft_course_run.save()
course = draft_course_run.course
official_version = draft_course_run.update_or_create_official_version()
course.refresh_from_db()

if is_subdirectory_slug_format_for_bootcamp_enabled:
assert course.active_url_slug.startswith('boot-camps/')
assert course.active_url_slug == f'boot-camps/{subject.slug}/{org.name}-{slugify(course.title)}'
assert official_version.course.active_url_slug.startswith('boot-camps/')
assert (
official_version.course.active_url_slug ==
f'boot-camps/{subject.slug}/{org.name}-{slugify(course.title)}'
)
else:
assert not course.active_url_slug.startswith('boot-camps/')
assert course.active_url_slug == f'{active_url_slug}'
assert not official_version.course.active_url_slug.startswith('boot-camps/')
assert official_version.course.active_url_slug == f'{active_url_slug}'

@ddt.data(
('https://www.example.com', 'test-slug', 'https://www.example.com/course/test-slug'),
# pylint: disable=line-too-long
Expand Down
11 changes: 11 additions & 0 deletions course_discovery/apps/course_metadata/toggles.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,14 @@
IS_SUBDIRECTORY_SLUG_FORMAT_FOR_EXEC_ED_ENABLED = WaffleSwitch(
'course_metadata.is_subdirectory_slug_format_for_exec_ed_enabled', __name__
)
# .. toggle_name: course_metadata.is_subdirectory_slug_format_for_bootcamp_enabled
# .. toggle_implementation: WaffleSwitch
# .. toggle_default: False
# .. toggle_description: Enable to use subdirectory slug format for bootcamp courses.
# .. toggle_use_cases: open_edx
# .. toggle_creation_date: 2023-09-05
# .. toggle_target_removal_date: 2023-09-20
# .. toggle_tickets: PROD-3611
IS_SUBDIRECTORY_SLUG_FORMAT_FOR_BOOTCAMP_ENABLED = WaffleSwitch(
'course_metadata.is_subdirectory_slug_format_for_bootcamp_enabled', __name__
)