Skip to content

Commit cdf63eb

Browse files
authored
Make sure enrollment_modes are always removed from mitxonline run dicts (#3033)
1 parent 0c821d5 commit cdf63eb

4 files changed

Lines changed: 39 additions & 2 deletions

File tree

learning_resources/etl/mitxonline.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
get_department_id_by_name,
2727
parse_certification,
2828
parse_string_to_int,
29+
strip_enrollment_modes,
2930
transform_price,
3031
transform_topics,
3132
)
@@ -314,6 +315,7 @@ def _transform_course(course):
314315
if course_run
315316
]
316317
has_certification = parse_certification(OFFERED_BY["code"], runs)
318+
strip_enrollment_modes(runs)
317319
return {
318320
"readable_id": course["readable_id"],
319321
"platform": PlatformType.mitxonline.name,
@@ -443,6 +445,7 @@ def transform_programs(programs: list[dict]) -> list[dict]:
443445
"max_weekly_hours": parse_string_to_int(program.get("max_weekly_hours")),
444446
}
445447
has_certification = parse_certification(OFFERED_BY["code"], [run])
448+
strip_enrollment_modes([run])
446449
yield {
447450
"readable_id": program["readable_id"],
448451
"title": program["title"],

learning_resources/etl/mitxonline_test.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
get_department_id_by_name,
4040
parse_certification,
4141
parse_string_to_int,
42+
strip_enrollment_modes,
4243
)
4344
from learning_resources.test_utils import set_up_topics
4445
from main.test_utils import any_instance_of
@@ -145,6 +146,7 @@ def test_mitxonline_transform_programs(
145146
for course_run in course_data["courseruns"]
146147
]
147148
has_certification = parse_certification(OFFERED_BY["code"], runs)
149+
strip_enrollment_modes(runs)
148150
expected_courses.append(
149151
{
150152
"readable_id": course_data["readable_id"],
@@ -303,6 +305,7 @@ def test_mitxonline_transform_courses(settings, mock_mitxonline_courses_data, mo
303305
for course_run in course_data["courseruns"]
304306
]
305307
has_certification = parse_certification(OFFERED_BY["code"], runs)
308+
strip_enrollment_modes(runs)
306309
expected.append(
307310
{
308311
"readable_id": course_data["readable_id"],

learning_resources/etl/utils.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,17 +1091,23 @@ def parse_certification(offeror, runs_data):
10911091
run.get("status")
10921092
and run.get("status") != RunStatus.archived.value
10931093
and (
1094-
"enrollment_modes" not in run
1094+
run.get("enrollment_modes") is None
10951095
or any(
10961096
mode.get("mode_slug") == "verified"
1097-
for mode in run.pop("enrollment_modes", [])
1097+
for mode in (run.get("enrollment_modes") or [])
10981098
)
10991099
)
11001100
for run in runs_data
11011101
if run.get("published", True)
11021102
)
11031103

11041104

1105+
def strip_enrollment_modes(runs_data):
1106+
"""Remove enrollment_modes from run dicts before passing downstream."""
1107+
for run in runs_data:
1108+
run.pop("enrollment_modes", None)
1109+
1110+
11051111
def iso8601_duration(duration_str: str) -> str | None:
11061112
"""
11071113
Parse the duration from a string and return it in ISO-8601 format

learning_resources/etl/utils_test.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
get_s3_prefix_for_source,
2424
parse_certification,
2525
parse_string_to_int,
26+
strip_enrollment_modes,
2627
)
2728
from learning_resources.factories import (
2829
ContentFileFactory,
@@ -489,6 +490,30 @@ def test_parse_certification(offered_by, status, enrollment_modes, has_cert):
489490
assert parse_certification(offered_by_obj.code, runs) == has_cert
490491

491492

493+
def test_parse_certification_handles_explicit_none_enrollment_modes():
494+
"""A run with enrollment_modes=None should not error and should be treated as cert-eligible for MITx."""
495+
runs = [
496+
{
497+
"published": True,
498+
"status": RunStatus.current.value,
499+
"enrollment_modes": None,
500+
}
501+
]
502+
503+
assert parse_certification(OfferedBy.mitx.name, runs) is True
504+
505+
506+
def test_strip_enrollment_modes():
507+
"""strip_enrollment_modes should remove enrollment_modes from all run dicts."""
508+
runs = [
509+
{"status": "current", "enrollment_modes": [{"mode_slug": "verified"}]},
510+
{"status": "current"},
511+
{"status": "current", "enrollment_modes": None},
512+
]
513+
strip_enrollment_modes(runs)
514+
assert all("enrollment_modes" not in run for run in runs)
515+
516+
492517
@pytest.mark.parametrize(
493518
("previous_archive", "identical"),
494519
[

0 commit comments

Comments
 (0)