From 6bb39741a963a87c6bcfe1d744c525fc4c3900d7 Mon Sep 17 00:00:00 2001 From: aliadnan Date: Mon, 20 Jun 2022 21:54:25 +0500 Subject: [PATCH] feat: Add default value for status in Program Model and remove hardcoded value from degree loader --- .../data_loaders/degrees_loader.py | 2 -- .../tests/test_degree_csv_loader.py | 2 ++ .../0286_add_default_status_to_program.py | 24 +++++++++++++++++++ .../apps/course_metadata/models.py | 2 +- .../apps/course_metadata/tests/factories.py | 7 ++++-- .../apps/course_metadata/tests/test_models.py | 5 ++++ 6 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 course_discovery/apps/course_metadata/migrations/0286_add_default_status_to_program.py diff --git a/course_discovery/apps/course_metadata/data_loaders/degrees_loader.py b/course_discovery/apps/course_metadata/data_loaders/degrees_loader.py index 27265b5a72..53897b756e 100644 --- a/course_discovery/apps/course_metadata/data_loaders/degrees_loader.py +++ b/course_discovery/apps/course_metadata/data_loaders/degrees_loader.py @@ -4,7 +4,6 @@ import csv import logging -from course_discovery.apps.course_metadata.choices import ProgramStatus from course_discovery.apps.course_metadata.data_loaders import AbstractDataLoader from course_discovery.apps.course_metadata.models import ( Curriculum, Degree, DegreeAdditionalMetadata, LanguageTag, LevelType, Organization, Program, ProgramType, @@ -164,7 +163,6 @@ def _update_or_create_degree( """ data_dict = { "type": program_type, - "status": ProgramStatus.Unpublished, "primary_subject_override": primary_subject_override, "level_type_override": level_type_override, "language_override": language_override, diff --git a/course_discovery/apps/course_metadata/data_loaders/tests/test_degree_csv_loader.py b/course_discovery/apps/course_metadata/data_loaders/tests/test_degree_csv_loader.py index 39660dac5f..984d50d734 100644 --- a/course_discovery/apps/course_metadata/data_loaders/tests/test_degree_csv_loader.py +++ b/course_discovery/apps/course_metadata/data_loaders/tests/test_degree_csv_loader.py @@ -10,6 +10,7 @@ from course_discovery.apps.api.v1.tests.test_views.mixins import APITestCase, OAuth2Mixin from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory +from course_discovery.apps.course_metadata.choices import ProgramStatus from course_discovery.apps.course_metadata.data_loaders.degrees_loader import DegreeCSVDataLoader from course_discovery.apps.course_metadata.data_loaders.tests import mock_data from course_discovery.apps.course_metadata.data_loaders.tests.mixins import DegreeCSVLoaderMixin @@ -258,6 +259,7 @@ def test_ingest_flow_for_minimal_degree_data(self, jwt_decode_patch): # pylint: assert degree.additional_metadata.external_identifier == '123456' assert degree.additional_metadata.organic_url == 'http://example.com/organic-page.html' assert degree.specializations.count() == 2 + assert degree.status == ProgramStatus.Unpublished @responses.activate def test_image_download_failure(self, jwt_decode_patch): # pylint: disable=unused-argument diff --git a/course_discovery/apps/course_metadata/migrations/0286_add_default_status_to_program.py b/course_discovery/apps/course_metadata/migrations/0286_add_default_status_to_program.py new file mode 100644 index 0000000000..bf68e92831 --- /dev/null +++ b/course_discovery/apps/course_metadata/migrations/0286_add_default_status_to_program.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.13 on 2022-06-20 16:21 + +from django.db import migrations, models +import djchoices.choices + + +class Migration(migrations.Migration): + + dependencies = [ + ('course_metadata', '0285_org_uuid_editable'), + ] + + operations = [ + migrations.AlterField( + model_name='historicalprogram', + name='status', + field=models.CharField(choices=[('unpublished', 'Unpublished'), ('active', 'Active'), ('retired', 'Retired'), ('deleted', 'Deleted')], db_index=True, default='unpublished', help_text='The lifecycle status of this Program.', max_length=24, validators=[djchoices.choices.ChoicesValidator({'active': 'Active', 'deleted': 'Deleted', 'retired': 'Retired', 'unpublished': 'Unpublished'})]), + ), + migrations.AlterField( + model_name='program', + name='status', + field=models.CharField(choices=[('unpublished', 'Unpublished'), ('active', 'Active'), ('retired', 'Retired'), ('deleted', 'Deleted')], db_index=True, default='unpublished', help_text='The lifecycle status of this Program.', max_length=24, validators=[djchoices.choices.ChoicesValidator({'active': 'Active', 'deleted': 'Deleted', 'retired': 'Retired', 'unpublished': 'Unpublished'})]), + ), + ] diff --git a/course_discovery/apps/course_metadata/models.py b/course_discovery/apps/course_metadata/models.py index 97e29b4e40..9cd41c1e0d 100644 --- a/course_discovery/apps/course_metadata/models.py +++ b/course_discovery/apps/course_metadata/models.py @@ -2258,7 +2258,7 @@ class Program(PkSearchableMixin, TimeStampedModel): type = models.ForeignKey(ProgramType, models.CASCADE, null=True, blank=True) status = models.CharField( help_text=_('The lifecycle status of this Program.'), max_length=24, null=False, blank=False, db_index=True, - choices=ProgramStatus.choices, validators=[ProgramStatus.validator] + choices=ProgramStatus.choices, validators=[ProgramStatus.validator], default=ProgramStatus.Unpublished ) marketing_slug = models.CharField( help_text=_('Slug used to generate links to the marketing site'), unique=True, max_length=255, db_index=True) diff --git a/course_discovery/apps/course_metadata/tests/factories.py b/course_discovery/apps/course_metadata/tests/factories.py index 2aa2b857eb..9c21439014 100644 --- a/course_discovery/apps/course_metadata/tests/factories.py +++ b/course_discovery/apps/course_metadata/tests/factories.py @@ -505,7 +505,7 @@ class Meta: source = FuzzyText(length=99) -class ProgramFactory(factory.django.DjangoModelFactory): +class ProgramBaseFactory(factory.django.DjangoModelFactory): class Meta: model = Program @@ -514,7 +514,6 @@ class Meta: subtitle = FuzzyText() marketing_hook = FuzzyText() type = factory.SubFactory(ProgramTypeFactory) - status = ProgramStatus.Active marketing_slug = factory.Sequence(lambda n: f'test-slug-{n}') card_image_url = FuzzyText(prefix='https://example.com/program/card') partner = factory.SubFactory(PartnerFactory) @@ -590,6 +589,10 @@ def curricula(self, create, extracted, **kwargs): add_m2m_data(self.curricula, extracted) +class ProgramFactory(ProgramBaseFactory): + status = ProgramStatus.Active + + class SpecializationFactory(factory.django.DjangoModelFactory): class Meta: model = Specialization diff --git a/course_discovery/apps/course_metadata/tests/test_models.py b/course_discovery/apps/course_metadata/tests/test_models.py index 156e85fc46..a2fd6e336a 100644 --- a/course_discovery/apps/course_metadata/tests/test_models.py +++ b/course_discovery/apps/course_metadata/tests/test_models.py @@ -2177,6 +2177,11 @@ def test_same_title_slug_programs(self): weeks_to_complete=15 ) + def test_program_default_status(self): + """Verify that program default status is Unpublished""" + program = factories.ProgramBaseFactory() + assert program.status == ProgramStatus.Unpublished + class PathwayTests(TestCase): """ Tests of the Pathway model."""