Skip to content

Commit

Permalink
chore: doing some updates
Browse files Browse the repository at this point in the history
  • Loading branch information
AfaqShuaib09 committed Dec 8, 2024
1 parent df385ed commit bd53de5
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 45 deletions.
26 changes: 26 additions & 0 deletions course_discovery/apps/course_metadata/data_loaders/csv_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,9 @@ def ingest(self): # pylint: disable=too-many-statements
logger.error(error_message)
self._register_ingestion_error(CSVIngestionErrors.LOGO_IMAGE_DOWNLOAD_FAILURE, error_message)

else:
self._update_course_entitlement_price(data=row, course_uuid=course.uuid, course_type=course_type)

# No need to update the course run if the run is already in the review
if not course_run.in_review:
try:
Expand Down Expand Up @@ -684,6 +687,29 @@ def _create_course(self, data, course_type, course_run_type_uuid):
logger.info("Course creation response: {}".format(response.content)) # lint-amnesty, pylint: disable=logging-format-interpolation
return response.json()

def _update_course_entitlement_price(self, data, course_uuid, course_type):
"""
Update the course entitlement price through course api.
"""
course_api_url = reverse('api:v1:course-detail', kwargs={'key': course_uuid})
url = f"{settings.DISCOVERY_BASE_URL}{course_api_url}"
pricing = (
self.get_pricing_representation(data['verified_price'], course_type)
if data.get('restriction_type', 'None') != CourseRunRestrictionType.CustomB2BEnterprise.value else {}
)

request_data = {
'org': data['organization'],
'title': data['title'],
'number': data['number'],
'prices': pricing,
}
response = self._call_course_api('PATCH', url, request_data)
if response.status_code not in (200, 201):
logger.info("Course creation response: {}".format(response.content))
logger.info("Course Price has been updated to {}".format(pricing))
return response.json()

def _create_course_run(self, data, course, course_type, course_run_type_uuid, rerun=None):
"""
Make a course run entry through course run api.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"""
Unit tests for CSV Data loader.
"""
import copy
import datetime
from decimal import Decimal
from tempfile import NamedTemporaryFile
from unittest import mock
from unittest.mock import patch
from course_discovery.apps.course_metadata.tests.factories import CSVDataLoaderConfigurationFactory

import responses
from ddt import data, ddt, unpack
Expand Down Expand Up @@ -599,6 +602,78 @@ def test_ingest_flow_for_preexisting_published_course_with_new_run_creation(self
'errors': loader.error_logs
}

@responses.activate
def test_success_flow_course_with_multiple_variants(self, jwt_decode_patch):
"""
Verify that the loader correctly ingests multiple variants of a course.
"""
self._setup_prerequisites(self.partner)
self.mock_studio_calls(self.partner)
studio_url = '{root}/api/v1/course_runs/'.format(root=self.partner.studio_url.strip('/'))
responses.add(responses.POST, f'{studio_url}{self.COURSE_RUN_KEY}/rerun/', status=200)
self.mock_studio_calls(self.partner, run_key='course-v1:edx+csv_123+1T2020a')
self.mock_ecommerce_publication(self.partner)
_, image_content = self.mock_image_response()

course = CourseFactory(
key=self.COURSE_KEY,
partner=self.partner,
type=self.course_type,
draft=True,
key_for_reruns=''
)

CourseRunFactory(
course=course,
start=datetime.datetime(2014, 3, 1, tzinfo=UTC),
end=datetime.datetime(2040, 3, 1, tzinfo=UTC),
key=self.COURSE_RUN_KEY,
type=self.course_run_type,
status='published',
draft=True,
)

mocked_data = copy.deepcopy(mock_data.VALID_COURSE_AND_COURSE_RUN_CSV_DICT)
mocked_data.update(
{
"publish_date": "01/26/2022",
"start_date": "01/25/2022",
"start_time": "00:00",
"end_date": "02/25/2055",
"end_time": "00:00",
"reg_close_date": "01/25/2055",
"reg_close_time": "00:00",
"course_pacing": "self-paced",
"course_run_enrollment_track": "Paid Executive Education",
"staff": "staff_1,staff_2",
"minimum_effort": "4",
"maximum_effort": "10",
"length": "10",
"content_language": "English - United States",
"transcript_language": "English - Great Britain",
"expected_program_type": "professional-certificate",
"expected_program_name": "New Program for all",
"upgrade_deadline_override_date": "01/25/2024",
"upgrade_deadline_override_time": "00:00",
'variant_id': "00000000-0000-0000-0000-000000000011",
}
)

with NamedTemporaryFile() as csv:
csv = self._write_csv(csv, [mock_data.VALID_COURSE_AND_COURSE_RUN_CSV_DICT, mocked_data])
with override_waffle_switch(IS_COURSE_RUN_VARIANT_ID_EDITABLE, active=True):
with LogCapture(LOGGER_PATH) as log_capture:
with mock.patch.object(
CSVDataLoader,
'_call_course_api',
self.mock_call_course_api
):
loader = CSVDataLoader(self.partner, csv_path=csv.name, product_source=self.source.slug)
loader.ingest()

assert Course.everything.count() == 2
assert CourseRun.everything.count() == 4

@responses.activate
def test_invalid_language(self, jwt_decode_patch): # pylint: disable=unused-argument
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,51 +204,6 @@ def test_success_flow(self, email_patch, jwt_decode_patch): # pylint: disable=u
self._assert_course_run_data(course_run, self.BASE_EXPECTED_COURSE_RUN_DATA)
email_patch.assert_called_once()

@responses.activate
@mock.patch('course_discovery.apps.course_metadata.management.commands.import_course_metadata.send_ingestion_email')
def test_success_flow_2(self, email_patch, jwt_decode_patch): # pylint: disable=unused-argument
"""
Verify that for a single row of valid data, the command completes CSV loader ingestion flow successfully.
"""
self._setup_prerequisites(self.partner)
self.mock_studio_calls(self.partner)
studio_url = '{root}/api/v1/course_runs/'.format(root=self.partner.studio_url.strip('/'))
responses.add(responses.POST, f'{studio_url}{self.COURSE_RUN_KEY}/rerun/', status=200)
self.mock_studio_calls(self.partner, run_key='course-v1:edx+csv_123+1T2020a')
self.mock_ecommerce_publication(self.partner)
_, image_content = self.mock_image_response()

_ = CSVDataLoaderConfigurationFactory.create(enabled=True, csv_file=self.csv_file_1)

with override_waffle_switch(IS_SUBDIRECTORY_SLUG_FORMAT_ENABLED, active=True):
with override_waffle_switch(IS_COURSE_RUN_VARIANT_ID_EDITABLE, active=True):
with override_waffle_switch(IS_SUBDIRECTORY_SLUG_FORMAT_FOR_EXEC_ED_ENABLED, active=True):
with LogCapture(LOGGER_PATH) as log_capture:
with mock.patch.object(
CSVDataLoader,
'_call_course_api',
self.mock_call_course_api
):
call_command(
'import_course_metadata',
'--partner_code', self.partner.short_code,
'--product_type', 'EXECUTIVE_EDUCATION',
'--product_source', self.source.slug,
)
log_capture.check_present(
(
LOGGER_PATH,
'INFO',
'Starting CSV loader import flow for partner {}'.format(self.partner.short_code)
)
)
log_capture.check_present(
(LOGGER_PATH, 'INFO', 'CSV loader import flow completed.')
)

assert Course.everything.count() == 2
assert CourseRun.everything.count() == 4

@responses.activate
@mock.patch('course_discovery.apps.course_metadata.management.commands.import_course_metadata.send_ingestion_email')
def test_exec_ed_slug__disabled_switch(self, _email_patch, _jwt_decode_patch):
Expand Down

0 comments on commit bd53de5

Please sign in to comment.