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)
def test_create_seat_masters_track(self, form_data): course_run = CourseRunFactory() form = SeatForm(data=form_data) seat = form.save(course_run=course_run) expected_masters = 'masters_track' in form_data and form_data[ 'masters_track'] self.assertEqual(expected_masters, seat.masters_track)
def test_create_course_run_in_studio_with_image_failure(self, __): organization = OrganizationFactory() OrganizationExtensionFactory(organization=organization) 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) course = CourseFactory(organizations=[organization]) with mock.patch('course_discovery.apps.api.utils.logger.exception' ) as mock_logger: publisher_course_run = CourseRunFactory( course=course, start=start, lms_course_id=None, ) assert mock_logger.call_count == 1 assert mock_logger.call_args_list[0] == mock.call( 'An error occurred while setting the course run image for [{key}] in studio. All other fields ' 'were successfully saved in Studio.'.format(key=course_run_key)) publisher_course_run.refresh_from_db() assert len(responses.calls) == 2 assert publisher_course_run.lms_course_id == course_run_key
def test_create_course_run_in_studio_with_image_api_failure( self, mock_access_token): 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) body = {'error': 'Server error'} url = '{root}/api/v1/course_runs/{course_run_key}/images/'.format( root=studio_url_root, course_run_key=course_run_key) responses.add(responses.POST, url, json=body, status=500) 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) == 2 assert publisher_course_run.lms_course_id == course_run_key mock_logger.assert_called_with( 'Failed to update Studio image for course run [%s]: %s', course_run_key, json.dumps(body).encode('utf8'))
def test_create_course_run_in_studio(self, mock_access_token): # 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) body = {'card_image': 'https://example.com/image.jpg'} url = '{root}/api/v1/course_runs/{course_run_key}/images/'.format( root=studio_url_root, course_run_key=course_run_key) 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]) # We refresh because the signal should update the instance with the course run key from Studio publisher_course_run.refresh_from_db() assert len(responses.calls) == 2 assert publisher_course_run.lms_course_id == course_run_key mock_logger.assert_called_with( 'Organization [%s] does not have an associated OrganizationExtension', organization.key, )
def test_create_course_run_error_with_discovery_run( self, mock_access_token): # pylint: disable=unused-argument """ Tests that course run creations raises exception and logs expected exception message """ number = 'TestX' organization = OrganizationFactory() partner = organization.partner course_key = '{org}+{number}'.format(org=organization.key, number=number) discovery_course_run = DiscoveryCourseRunFactory( course__partner=partner, course__key=course_key) body = {'error': 'Server error'} studio_url_root = partner.studio_url.strip('/') url = '{root}/api/v1/course_runs/{course_run_key}/rerun/'.format( root=studio_url_root, course_run_key=discovery_course_run.key) responses.add(responses.POST, url, json=body, status=500) with mock.patch( 'course_discovery.apps.publisher.signals.logger.exception' ) as mock_logger: with pytest.raises(HttpServerError): CourseRunFactory(lms_course_id=None, course__organizations=[organization], course__number=number) assert len(responses.calls) == 1 mock_logger.assert_called_with( 'Failed to create course run [%s] on Studio: %s', course_key, json.dumps(body).encode('utf8'))
def test_create_course_run_in_studio_as_rerun(self, mock_access_token): # pylint: disable=unused-argument number = 'TestX' organization = OrganizationFactory() 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() course_run_key = 'course-v1:TestX+Testing101x+1T2017' body = {'id': course_run_key} studio_url_root = partner.studio_url.strip('/') url = '{root}/api/v1/course_runs/{course_run_key}/rerun/'.format( root=studio_url_root, course_run_key=discovery_course_run.key) responses.add(responses.POST, url, json=body, status=200) body = {'card_image': 'https://example.com/image.jpg'} url = '{root}/api/v1/course_runs/{course_run_key}/images/'.format( root=studio_url_root, course_run_key=course_run_key) responses.add(responses.POST, url, json=body, status=200) publisher_course_run = CourseRunFactory( start=start, lms_course_id=None, course__organizations=[organization], course__number=number) # We refresh because the signal should update the instance with the course run key from Studio publisher_course_run.refresh_from_db() assert len(responses.calls) == 2 assert publisher_course_run.lms_course_id == course_run_key
def setUp(self): super(CourseRunSerializerTests, self).setUp() self.course_run = CourseRunFactory() self.course_run.lms_course_id = 'course-v1:edX+DemoX+Demo_Course' self.request = RequestFactory() self.user = UserFactory() self.request.user = self.user self.course_state = CourseRunStateFactory(course_run=self.course_run, owner_role=PublisherUserRole.Publisher)
def test_update_course_run_image_in_studio_without_course_image(): publisher_course_run = CourseRunFactory(course__image=None) api = StudioAPI(None) with mock.patch('course_discovery.apps.api.utils.logger') as mock_logger: api.update_course_run_image_in_studio(publisher_course_run) mock_logger.warning.assert_called_with( 'Card image for course run [%d] cannot be updated. The related course [%d] has no image defined.', publisher_course_run.id, publisher_course_run.course.id)
def test_create_course_run_in_studio_without_partner(self): with mock.patch('course_discovery.apps.publisher.signals.logger.error' ) as mock_logger: publisher_course_run = CourseRunFactory(course__organizations=[]) assert publisher_course_run.course.partner is None mock_logger.assert_called_with( 'Failed to publish course run [%d] to Studio. Related course [%d] has no associated Partner.', publisher_course_run.id, publisher_course_run.course.id)
def test_generate_data_for_studio_api_without_team(): course_run = CourseRunFactory( course__organizations=[OrganizationFactory()]) with mock.patch( 'course_discovery.apps.api.utils.logger.warning') as mock_logger: assert_data_generated_correctly(course_run, []) mock_logger.assert_called_with( 'No course team admin specified for course [%s]. This may result in a Studio course run ' 'being created without a course team.', course_run.course.number)
def _create_course_run_for_publication(self): organization = OrganizationFactory() transcript_languages = [LanguageTag.objects.first()] mock_image_file = make_image_file('test_image.jpg') return CourseRunFactory(course__organizations=[organization], course__tertiary_subject=None, course__image__from_file=mock_image_file, lms_course_id='a/b/c', transcript_languages=transcript_languages, staff=PersonFactory.create_batch(2))
def test_generate_data_for_studio_api(): course_run = CourseRunFactory(course__organizations=[OrganizationFactory()]) course = course_run.course role = CourseUserRoleFactory(course=course, role=PublisherUserRole.CourseTeam) team = [ { 'user': role.user.username, 'role': 'instructor', }, ] assert_data_generated_correctly(course_run, team)
def test_successful_post(self): """Posting data to the comment post endpoint creates a comment.""" path = reverse('comments-post-comment') self.assertEqual(Comments.objects.count(), 0) course_run = CourseRunFactory() generated_data = self.generate_data(course_run) self.client.post(path, data=generated_data) self.assertEqual(Comments.objects.count(), 1) comment = Comments.objects.first() self.assertEqual(comment.user_name, generated_data['name']) self.assertEqual(comment.comment, generated_data['comment']) self.assertEqual(comment.user_email, generated_data['email'])
def setUp(self): super(CourseRunSerializerTests, self).setUp() self.course_run = CourseRunFactory() self.course_run.lms_course_id = 'course-v1:edX+DemoX+Demo_Course' self.course_run.external_key = 'testOrg-course-1' self.person = PersonFactory() self.discovery_course_run = DiscoveryCourseRunFactory( key=self.course_run.lms_course_id, external_key=self.course_run.external_key, staff=[self.person]) self.request = RequestFactory() self.user = UserFactory() self.request.user = self.user self.course_state = CourseRunStateFactory( course_run=self.course_run, owner_role=PublisherUserRole.Publisher)
def test_create_course_run_in_studio_with_organization_opt_out(self): with mock.patch( 'course_discovery.apps.publisher.signals.logger.warning' ) as mock_logger: course_organization = OrganizationFactory() OrganizationExtensionFactory(organization=course_organization, auto_create_in_studio=False) publisher_course_run = CourseRunFactory( course__organizations=[course_organization]) mock_logger.assert_called_with( ('Course run [%d] will not be automatically created in studio.' 'Organization [%s] has opted out of this feature.'), publisher_course_run.course.id, course_organization.key, )
def test_calculate_course_run_key_run_value_with_multiple_runs_per_trimester(): number = 'TestX' organization = OrganizationFactory() partner = organization.partner course_key = '{org}+{number}'.format(org=organization.key, number=number) discovery_course = DiscoveryCourseFactory(partner=partner, key=course_key) DiscoveryCourseRunFactory(key='course-v1:TestX+Testing101x+1T2017', course=discovery_course) course_run = CourseRunFactory( start=datetime.datetime(2017, 2, 1), lms_course_id=None, course__organizations=[organization], course__number=number ) assert StudioAPI.calculate_course_run_key_run_value(course_run) == '1T2017a' DiscoveryCourseRunFactory(key='course-v1:TestX+Testing101x+1T2017a', course=discovery_course) assert StudioAPI.calculate_course_run_key_run_value(course_run) == '1T2017b'
def test_create_course_run_in_studio(self, mock_access_token): # 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) body = {'card_image': 'https://example.com/image.jpg'} url = '{root}/api/v1/course_runs/{course_run_key}/images/'.format( root=studio_url_root, course_run_key=course_run_key) responses.add(responses.POST, url, json=body, status=200) publisher_course_run = CourseRunFactory( start=start, lms_course_id=None, course__organizations=[organization]) assert len(responses.calls) == 2 assert publisher_course_run.lms_course_id == course_run_key
def test_create_course_run_in_studio_with_api_failure( self, mock_access_token): # pylint: disable=unused-argument organization = OrganizationFactory() partner = organization.partner body = {'error': 'Server error'} studio_url_root = partner.studio_url.strip('/') url = '{}/api/v1/course_runs/'.format(studio_url_root) responses.add(responses.POST, url, json=body, status=500) with mock.patch( 'course_discovery.apps.publisher.signals.logger.exception' ) as mock_logger: with pytest.raises(HttpServerError): publisher_course_run = CourseRunFactory( lms_course_id=None, course__organizations=[organization]) assert len(responses.calls) == 1 assert publisher_course_run.lms_course_id is None mock_logger.assert_called_with( 'Failed to create course run [%d] on Studio: %s', publisher_course_run.id, json.dumps(body).encode('utf8'))
def test_calculate_course_run_key_run_value(month, expected): course_run = CourseRunFactory(start=datetime.datetime(2017, month, 1)) assert StudioAPI.calculate_course_run_key_run_value(course_run) == expected
def setUp(self): super(UpdateCourseKeySerializerTests, self).setUp() self.course_run = CourseRunFactory() self.request = RequestFactory() self.user = UserFactory() self.request.user = self.user