Skip to content

Commit 4022cd3

Browse files
authored
feat: add support of multiple product sources to populate product sources management command (#4454)
1 parent 18d78aa commit 4022cd3

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

course_discovery/apps/course_metadata/management/commands/populate_product_catalog.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def add_arguments(self, parser):
4646
dest='product_source',
4747
type=str,
4848
required=False,
49-
help='The product source to filter the products'
49+
help='The comma-separated product source str to filter the products'
5050
)
5151
parser.add_argument(
5252
'--use_gspread_client',
@@ -86,7 +86,7 @@ def get_products(self, product_type, product_source):
8686
queryset = queryset.filter(type__slug=CourseType.BOOTCAMP_2U)
8787

8888
if product_source:
89-
queryset = queryset.filter(product_source__slug=product_source)
89+
queryset = queryset.filter(product_source__slug__in=product_source.split(','))
9090

9191
queryset = queryset.annotate(
9292
num_orgs=Count('authoring_organizations')
@@ -109,7 +109,7 @@ def get_products(self, product_type, product_source):
109109
.select_related('partner', 'type', 'primary_subject_override', 'language_override')
110110

111111
if product_source:
112-
queryset = queryset.filter(product_source__slug=product_source)
112+
queryset = queryset.filter(product_source__slug__in=product_source.split(','))
113113

114114
queryset = queryset.annotate(
115115
num_orgs=Count('authoring_organizations')

course_discovery/apps/course_metadata/management/commands/tests/test_populate_product_catalog.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def setUp(self):
2727
self.organization = OrganizationFactory(partner=self.partner)
2828
self.course_type = CourseTypeFactory(slug=CourseType.AUDIT)
2929
self.source = SourceFactory.create(slug="edx")
30+
self.source_2 = SourceFactory.create(slug="test-source")
3031
self.courses = CourseFactory.create_batch(
3132
2,
3233
product_source=self.source,
@@ -346,6 +347,91 @@ def test_populate_product_catalog_with_degrees_having_overrides(self):
346347
self.assertIn(degree.primary_subject_override.name, row["Subjects"])
347348
self.assertEqual(row["Languages"], degree.language_override.code)
348349

350+
def test_populate_product_catalog_supports_multiple_product_sources(self):
351+
"""
352+
Test that the populate_product_catalog command supports multiple product sources.
353+
"""
354+
marketable_degree = DegreeFactory.create(
355+
partner=self.partner,
356+
additional_metadata=None,
357+
type=self.program_type,
358+
status=ProgramStatus.Active,
359+
marketing_slug="valid-marketing-slug",
360+
title="Marketable Degree",
361+
authoring_organizations=[self.organization],
362+
card_image=factory.django.ImageField(),
363+
product_source=self.source,
364+
)
365+
marketable_degree_2 = DegreeFactory.create(
366+
partner=self.partner,
367+
additional_metadata=None,
368+
type=self.program_type,
369+
status=ProgramStatus.Active,
370+
marketing_slug="valid-marketing-slug",
371+
title="Marketable Degree - with different product sources",
372+
authoring_organizations=[self.organization],
373+
card_image=factory.django.ImageField(),
374+
language_override=None,
375+
product_source=self.source_2,
376+
)
377+
378+
with NamedTemporaryFile() as output_csv:
379+
call_command(
380+
"populate_product_catalog",
381+
product_type="degree",
382+
output_csv=output_csv.name,
383+
product_source="edx",
384+
gspread_client_flag=False,
385+
)
386+
387+
with open(output_csv.name, "r") as output_csv_file:
388+
csv_reader = csv.DictReader(output_csv_file)
389+
rows = list(csv_reader)
390+
391+
# Check that the marketable degree is in the CSV for the specified product source
392+
matching_rows = [
393+
row for row in rows if row["UUID"] == str(marketable_degree.uuid.hex)
394+
]
395+
self.assertEqual(
396+
len(matching_rows), 1, f"Marketable degree '{marketable_degree.title}' should be in the CSV",
397+
)
398+
399+
# Check that the marketable degree with different product sources is not in the CSV
400+
matching_rows = [
401+
row for row in rows if row["UUID"] == str(marketable_degree_2.uuid.hex)
402+
]
403+
self.assertEqual(
404+
len(matching_rows), 0,
405+
f"'{marketable_degree_2.title}' with different product sources should not be in the CSV",
406+
)
407+
408+
with NamedTemporaryFile() as output_csv:
409+
call_command(
410+
"populate_product_catalog",
411+
product_type="degree",
412+
output_csv=output_csv.name,
413+
product_source="edx,test-source",
414+
gspread_client_flag=False,
415+
)
416+
417+
with open(output_csv.name, "r") as output_csv_file:
418+
csv_reader = csv.DictReader(output_csv_file)
419+
rows = list(csv_reader)
420+
421+
# Check that the marketable degree is in the CSV for the specified product sources
422+
matching_rows = [
423+
row for row in rows if row["UUID"] == str(marketable_degree.uuid.hex)
424+
]
425+
self.assertEqual(
426+
len(matching_rows), 1, f"Marketable degree '{marketable_degree.title}' should be in the CSV",
427+
)
428+
matching_rows = [
429+
row for row in rows if row["UUID"] == str(marketable_degree_2.uuid.hex)
430+
]
431+
self.assertEqual(
432+
len(matching_rows), 1, f"'{marketable_degree_2.title}' should be in the CSV",
433+
)
434+
349435
@mock.patch(
350436
"course_discovery.apps.course_metadata.management.commands.populate_product_catalog.Command.get_products"
351437
)

0 commit comments

Comments
 (0)