Skip to content

Commit

Permalink
feat: add RestrictedCourseRun model (#4318)
Browse files Browse the repository at this point in the history
  • Loading branch information
zawan-ila authored Apr 9, 2024
1 parent a700f20 commit 2a1e914
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 3 deletions.
6 changes: 6 additions & 0 deletions course_discovery/apps/course_metadata/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,12 @@ class ProgramSubscriptionPriceAdmin(admin.ModelAdmin):
"price", "currency__name")


@admin.register(RestrictedCourseRun)
class RestrictedCourseRunAdmin(admin.ModelAdmin):
list_display = ['course_run', 'restriction_type']
search_fields = ['course_run__key', 'restriction_type']


class CourseReviewAdmin(admin.ModelAdmin):
"""
Admin settings for CourseReview model
Expand Down
5 changes: 5 additions & 0 deletions course_discovery/apps/course_metadata/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,8 @@ class ExternalCourseMarketingType(models.TextChoices):
ShortCourse = 'short_course', _('Short Course')
Sprint = 'sprint', _('Sprint')
CourseStack = 'course_stack', _('Course Stack')


class CourseRunRestrictionType(models.TextChoices):
CustomB2BEnterprise = 'custom-b2b-enterprise', _('Custom B2B Enterprise')
CustomB2C = 'custom-b2c', _('Custom B2C')
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Generated by Django 4.2.11 on 2024-04-09 09:34

from django.db import migrations, models
import django.db.models.deletion
import django.db.models.manager
import django_extensions.db.fields


class Migration(migrations.Migration):

dependencies = [
('course_metadata', '0340_auto_20231211_1032'),
]

operations = [
migrations.CreateModel(
name='RestrictedCourseRun',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('draft', models.BooleanField(default=False, help_text='Is this a draft version?')),
('restriction_type', models.CharField(blank=True, choices=[('custom-b2b-enterprise', 'Custom B2B Enterprise'), ('custom-b2c', 'Custom B2C')], help_text='The type of restriction for the above course run', max_length=255, null=True)),
('course_run', models.OneToOneField(help_text='Course Run that will be restricted', on_delete=django.db.models.deletion.CASCADE, related_name='restricted_run', to='course_metadata.courserun')),
('draft_version', models.OneToOneField(blank=True, limit_choices_to={'draft': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='_official_version', to='course_metadata.restrictedcourserun')),
],
options={
'abstract': False,
},
managers=[
('everything', django.db.models.manager.Manager()),
],
),
]
24 changes: 22 additions & 2 deletions course_discovery/apps/course_metadata/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
from course_discovery.apps.core.models import Currency, Partner
from course_discovery.apps.course_metadata import emails
from course_discovery.apps.course_metadata.choices import (
CertificateType, CourseLength, CourseRunPacing, CourseRunStatus, ExternalCourseMarketingType, ExternalProductStatus,
PayeeType, ProgramStatus, ReportingType
CertificateType, CourseLength, CourseRunPacing, CourseRunRestrictionType, CourseRunStatus,
ExternalCourseMarketingType, ExternalProductStatus, PayeeType, ProgramStatus, ReportingType
)
from course_discovery.apps.course_metadata.constants import SUBDIRECTORY_SLUG_FORMAT_REGEX, PathwayType
from course_discovery.apps.course_metadata.fields import AutoSlugWithSlashesField, HtmlField, NullHtmlField
Expand Down Expand Up @@ -4537,3 +4537,23 @@ class Meta:

def __str__(self):
return self.arguments


class RestrictedCourseRun(DraftModelMixin, TimeStampedModel):
"""
Model to hold information for restricted Course Runs. Restricted course
runs will only be exposed in the APIs if explicitly asked for through
a query param. Consult ADR-27 for more details
"""
course_run = models.OneToOneField(
CourseRun, models.CASCADE, related_name='restricted_run',
help_text='Course Run that will be restricted'
)
restriction_type = models.CharField(
max_length=255, null=True, blank=True,
choices=CourseRunRestrictionType.choices,
help_text='The type of restriction for the course run'
)

def __str__(self):
return f"{self.course_run.key}: <{self.restriction_type}>"
8 changes: 8 additions & 0 deletions course_discovery/apps/course_metadata/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -995,3 +995,11 @@ class Meta:
class MigrateProgramSlugConfigurationFactory(factory.django.DjangoModelFactory):
class Meta:
model = MigrateProgramSlugConfiguration


class RestrictedCourseRunFactory(factory.django.DjangoModelFactory):
class Meta:
model = RestrictedCourseRun

course_run = factory.SubFactory(CourseRunFactory)
restriction_type = FuzzyChoice([name for name, __ in CourseRunRestrictionType.choices])
20 changes: 19 additions & 1 deletion course_discovery/apps/course_metadata/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
from course_discovery.apps.core.models import Currency
from course_discovery.apps.core.tests.helpers import make_image_file
from course_discovery.apps.core.utils import SearchQuerySetWrapper
from course_discovery.apps.course_metadata.choices import CourseRunStatus, ExternalProductStatus, ProgramStatus
from course_discovery.apps.course_metadata.choices import (
CourseRunRestrictionType, CourseRunStatus, ExternalProductStatus, ProgramStatus
)
from course_discovery.apps.course_metadata.constants import SUBDIRECTORY_PROGRAM_SLUG_FORMAT_REGEX as slug_format
from course_discovery.apps.course_metadata.models import (
FAQ, AbstractHeadingBlurbModel, AbstractMediaModel, AbstractNamedModel, AbstractTitleDescriptionModel,
Expand Down Expand Up @@ -3982,3 +3984,19 @@ def test_recommendation_ordering(self):
assert course2_recs[0].key == 'course3'
assert course2_recs[1].key == 'course6'
assert course2_recs[2].key == 'course4'


class RestrictedCourseRunTests(TestCase):
""" Tests for the `RestrictedCourseRun` model. """

def test_basic(self):
""" Some sanity checks """
course_run = factories.CourseRunFactory(key="course-v1:SC+BreadX+3T2015")
restricted_course_run = factories.RestrictedCourseRunFactory(
course_run=course_run,
restriction_type=CourseRunRestrictionType.CustomB2BEnterprise.value
)

self.assertEqual(course_run.restricted_run, restricted_course_run)
self.assertEqual(restricted_course_run.restriction_type, 'custom-b2b-enterprise')
self.assertEqual(str(restricted_course_run), "course-v1:SC+BreadX+3T2015: <custom-b2b-enterprise>")

0 comments on commit 2a1e914

Please sign in to comment.