예제 #1
0
    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)
예제 #2
0
 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)
예제 #3
0
    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
예제 #4
0
    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'))
예제 #5
0
    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,
            )
예제 #6
0
    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'))
예제 #7
0
    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
예제 #8
0
 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)
예제 #9
0
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)
예제 #10
0
    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)
예제 #11
0
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)
예제 #12
0
 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)
예제 #14
0
    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'])
예제 #15
0
 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)
예제 #16
0
    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'
예제 #18
0
    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
예제 #19
0
    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
예제 #21
0
 def setUp(self):
     super(UpdateCourseKeySerializerTests, self).setUp()
     self.course_run = CourseRunFactory()
     self.request = RequestFactory()
     self.user = UserFactory()
     self.request.user = self.user