Commit b2ed6602 by Clinton Blackburn Committed by Clinton Blackburn

Updated enrollment date publishing to Studio

- When creating a new course run, enrollment dates are no longer copied from the previous run
- Temporary code in signal receiver has been removed. The enrollment dates will always be empty when creating a re-run.
- Added additional exception handling around API call to create images. Errors from this operation will no longer prevent a course run from being saved.

LEARNER-2469
parent 59ae0bed
......@@ -250,8 +250,11 @@ class Course(TimeStampedModel, ChangedByMixin):
@cached_property
def discovery_counterpart(self):
course_key = '{org}+{number}'.format(org=self.organizations.first().key, number=self.number)
return DiscoveryCourse.objects.get(partner=self.partner, key=course_key)
return DiscoveryCourse.objects.get(partner=self.partner, key=self.key)
@cached_property
def key(self):
return '{org}+{number}'.format(org=self.organizations.first().key, number=self.number)
class CourseRun(TimeStampedModel, ChangedByMixin):
......
......@@ -31,15 +31,13 @@ def create_course_run_in_studio_receiver(sender, instance, created, **kwargs):
logger.info('Publishing course run [%d] to Studio...', instance.id)
api = StudioAPI(instance.course.partner.studio_api_client)
# TODO How to handle the fact that Publisher does not expose enrollment date fields?
instance.enrollment_start = instance.enrollment_start or instance.start
instance.enrollment_end = instance.enrollment_end or instance.end
try:
try:
discovery_course_run = get_related_discovery_course_run(instance)
logger.info('Creating a re-run of [%s]...', discovery_course_run.key)
response = api.create_course_rerun_in_studio(instance, discovery_course_run)
except ObjectDoesNotExist:
logger.info('Creating a new run of [%s]...', instance.course.key)
response = api.create_course_run_in_studio(instance)
instance.lms_course_id = response['id']
......@@ -54,5 +52,7 @@ def create_course_run_in_studio_receiver(sender, instance, created, **kwargs):
logger.exception(
'Failed to update Studio image for course run [%s]: %s', instance.lms_course_id, ex.content
)
except: # pylint: disable=bare-except
logger.exception('Failed to update Studio image for course run [%s]', instance.lms_course_id)
logger.info('Completed creation of course run [%s] on Studio.', instance.lms_course_id)
......@@ -4,6 +4,7 @@ import json
import mock
import pytest
import responses
from freezegun import freeze_time
from slumber.exceptions import HttpServerError
from waffle.testutils import override_switch
......@@ -14,6 +15,7 @@ from course_discovery.apps.publisher.studio_api_utils import StudioAPI
from course_discovery.apps.publisher.tests.factories import CourseRunFactory
@freeze_time('2017-01-01T00:00:00Z')
@pytest.mark.django_db
class TestSignals:
@override_switch('enable_publisher_create_course_run_in_studio', active=True)
......@@ -34,10 +36,8 @@ class TestSignals:
def test_create_course_run_in_studio(self, mock_access_token): # pylint: disable=unused-argument
organization = OrganizationFactory()
partner = organization.partner
start = datetime.datetime.utcnow()
run = StudioAPI.calculate_course_run_key_run_value(CourseRunFactory.build(start=start))
course_run_key = 'course-v1:TestX+Testing101x+' + run
course_run_key = 'course-v1:TestX+Testing101x+1T2017'
body = {'id': course_run_key}
studio_url_root = partner.studio_url.strip('/')
......@@ -68,10 +68,8 @@ class TestSignals:
partner = organization.partner
course_key = '{org}+{number}'.format(org=organization.key, number=number)
discovery_course_run = DiscoveryCourseRunFactory(course__partner=partner, course__key=course_key)
start = datetime.datetime.utcnow()
run = StudioAPI.calculate_course_run_key_run_value(CourseRunFactory.build(start=start))
course_run_key = 'course-v1:TestX+Testing101x+' + run
course_run_key = 'course-v1:TestX+Testing101x+1T2017'
body = {'id': course_run_key}
studio_url_root = partner.studio_url.strip('/')
......@@ -103,14 +101,40 @@ class TestSignals:
@responses.activate
@mock.patch.object(Partner, 'access_token', return_value='JWT fake')
@mock.patch.object(StudioAPI, 'update_course_run_image_in_studio', side_effect=Exception)
@override_switch('enable_publisher_create_course_run_in_studio', active=True)
def test_create_course_run_in_studio_with_image_failure(self, mock_access_token): # pylint: disable=unused-argument
def test_create_course_run_in_studio_with_image_failure(self, __, ___): # pylint: disable=unused-argument
organization = OrganizationFactory()
partner = organization.partner
start = datetime.datetime.utcnow()
course_run_key = 'course-v1:TestX+Testing101x+1T2017'
body = {'id': course_run_key}
studio_url_root = partner.studio_url.strip('/')
url = '{}/api/v1/course_runs/'.format(studio_url_root)
responses.add(responses.POST, url, json=body, status=200)
with mock.patch('course_discovery.apps.publisher.signals.logger.exception') as mock_logger:
publisher_course_run = CourseRunFactory(
start=start,
lms_course_id=None,
course__organizations=[organization]
)
assert len(responses.calls) == 1
assert publisher_course_run.lms_course_id == course_run_key
mock_logger.assert_called_with('Failed to update Studio image for course run [%s]', course_run_key)
# pylint: disable=unused-argument
@responses.activate
@mock.patch.object(Partner, 'access_token', return_value='JWT fake')
@override_switch('enable_publisher_create_course_run_in_studio', active=True)
def test_create_course_run_in_studio_with_image_api_failure(self, mock_access_token):
organization = OrganizationFactory()
partner = organization.partner
start = datetime.datetime.utcnow()
run = StudioAPI.calculate_course_run_key_run_value(CourseRunFactory.build(start=start))
course_run_key = 'course-v1:TestX+Testing101x+' + run
course_run_key = 'course-v1:TestX+Testing101x+1T2017'
body = {'id': course_run_key}
studio_url_root = partner.studio_url.strip('/')
......
......@@ -533,7 +533,8 @@ class CreateCourseRunView(mixins.LoginRequiredMixin, CreateView):
# Delete all those fields which cannot be copied from previous run
del (last_run_data['id'], last_run_data['start'], last_run_data['end'], last_run_data['pacing_type'],
last_run_data['preview_url'], last_run_data['lms_course_id'], last_run_data['changed_by'],
last_run_data['course'], last_run_data['sponsor'])
last_run_data['course'], last_run_data['sponsor'], last_run_data['enrollment_start'],
last_run_data['enrollment_end'])
staff = Person.objects.filter(id__in=last_run_data.pop('staff'))
transcript_languages = LanguageTag.objects.filter(code__in=last_run_data.pop('transcript_languages'))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment