def test_typeahead_org_course_runs_come_up_first(self):
     """ Test typeahead response to ensure org is taken into account. """
     MITx = OrganizationFactory(key='MITx')
     HarvardX = OrganizationFactory(key='HarvardX')
     mit_run = CourseRunFactory(
         authoring_organizations=[MITx, HarvardX],
         title='MIT Testing1',
         course__partner=self.partner
     )
     harvard_run = CourseRunFactory(
         authoring_organizations=[HarvardX],
         title='MIT Testing2',
         course__partner=self.partner
     )
     mit_program = ProgramFactory(
         authoring_organizations=[MITx, HarvardX],
         title='MIT Testing1',
         partner=self.partner
     )
     harvard_program = ProgramFactory(
         authoring_organizations=[HarvardX],
         title='MIT Testing2',
         partner=self.partner
     )
     response = self.get_response({'q': 'mit'})
     self.assertEqual(response.status_code, 200)
     expected = {
         'course_runs': [self.serialize_course_run_search(mit_run),
                         self.serialize_course_run_search(harvard_run)],
         'programs': [self.serialize_program_search(mit_program),
                      self.serialize_program_search(harvard_program)]
     }
     self.assertDictEqual(response.data, expected)
Beispiel #2
0
    def test_200(self):
        self.login_staff()
        org1 = OrganizationFactory()
        org2 = OrganizationFactory()
        program1 = self.create_program([org1])
        program2 = self.create_program([org2])
        program12 = self.create_program([org1, org2])
        programs = [program1, program2, program12]
        uuids = [program.uuid for program in programs]

        response = self.get(uuids)
        self.assertEqual(response.status_code, 200)
        fixture = json.loads(response.content.decode('utf-8'))

        # To make this tests less brittle, allow (inclusive) ranges for each model count.
        # For some models (e.g. Course) we DO care about the exact count.
        # For others (e.g. Video) we just want to make sure that they are there,
        # but that we're not loading a crazy amount of them.
        expected_count_ranges_by_model = {
            Organization: (2, 2),
            Program: (3, 3),
            Curriculum: (3, 3),
            Course: (9, 9),
            CourseRun: (12, 12),
            CurriculumCourseMembership: (6, 6),
            CurriculumCourseRunExclusion: (3, 3),
            ProgramType: (1, 1),
            SeatType: (1, 1),
            AdditionalPromoArea: (5, 15),
            Image: (20, 60),
            LevelType: (5, 15),
            Video: (20, 60),
            LanguageTag: (10, 30),
        }

        actual_appearances_by_model_label = defaultdict(set)
        for record in fixture:
            pk = record['pk']
            model_label = record['model']
            # Assert no duplicate objects
            self.assertNotIn(pk,
                             actual_appearances_by_model_label[model_label])
            actual_appearances_by_model_label[model_label].add(pk)

        for model, (min_expected,
                    max_expected) in expected_count_ranges_by_model.items():
            model_label = model._meta.label_lower
            actual_count = len(actual_appearances_by_model_label[model_label])
            err_string = "object count of {} for {} outside expected range [{}, {}]".format(
                actual_count, model_label, min_expected, max_expected)
            self.assertGreaterEqual(actual_count, min_expected, err_string)
            self.assertLessEqual(actual_count, max_expected, err_string)
 def test_organization_key(self):
     """ Verify that the wrapper return the organization key. """
     organization = OrganizationFactory()
     course_run = factories.CourseRunFactory(
         course__organizations=[organization])
     wrapped_course_run = CourseRunWrapper(course_run)
     self.assertEqual(wrapped_course_run.organization_key, organization.key)
 def test_partner(self):
     """ Verify that the wrapper can return partner values. """
     organization = OrganizationFactory()
     self.course.organizations.add(organization)
     partner = "/".join(
         [org.key for org in self.course_run.course.organizations.all()])
     self.assertEqual(self.wrapped_course_run.partner, partner)
    def test_is_multiple_partner_course(self):
        """ Verify that the wrapper return the is_multiple_partner_course. """
        self.assertFalse(self.wrapped_course_run.is_multiple_partner_course)
        organization = OrganizationFactory()
        self.course.organizations.add(organization)

        self.assertTrue(self.wrapped_course_run.is_multiple_partner_course)
Beispiel #6
0
    def setUp(self):
        super(CourseRunStateSerializerTests, self).setUp()
        self.run_state = CourseRunStateFactory(
            name=CourseRunStateChoices.Draft)
        self.course_run = self.run_state.course_run
        self.request = RequestFactory()
        self.user = UserFactory()
        self.request.user = self.user
        CourseStateFactory(name=CourseStateChoices.Approved,
                           course=self.course_run.course)

        SeatFactory(course_run=self.course_run, type=Seat.AUDIT)
        language_tag = LanguageTag(code='te-st', name='Test Language')
        language_tag.save()
        self.course_run.transcript_languages.add(language_tag)
        self.course_run.language = language_tag
        organization = OrganizationFactory()
        self.course_run.course.organizations.add(organization)
        self.course_run.save()
        self.course_run.staff.add(PersonFactory())

        toggle_switch('enable_publisher_email_notifications', True)
        CourseUserRoleFactory(course=self.course_run.course,
                              role=PublisherUserRole.CourseTeam,
                              user=self.user)
        CourseUserRoleFactory(course=self.course_run.course,
                              role=PublisherUserRole.ProjectCoordinator,
                              user=UserFactory())
    def setUp(self):
        super(ChangeCourseRunStateViewTests, self).setUp()
        self.seat = factories.SeatFactory(type=Seat.VERIFIED, price=2)
        self.course_run = self.seat.course_run

        self.run_state = factories.CourseRunStateFactory(name=CourseRunStateChoices.Draft, course_run=self.course_run)
        self.course_state = factories.CourseStateFactory(
            name=CourseStateChoices.Approved, course=self.course_run.course
        )
        self.user = UserFactory()
        self.user.groups.add(Group.objects.get(name=INTERNAL_USER_GROUP_NAME))

        self.change_state_url = reverse('publisher:api:change_course_run_state', kwargs={'pk': self.run_state.id})

        self.client.login(username=self.user.username, password=USER_PASSWORD)

        language_tag = LanguageTag(code='te-st', name='Test Language')
        language_tag.save()
        self.course_run.transcript_languages.add(language_tag)
        self.course_run.language = language_tag
        self.course_run.lms_course_id = 'course-v1:edX+DemoX+Demo_Course'
        self.course_run.course.organizations.add(OrganizationFactory())
        self.course_run.save()

        self.course_run.staff.add(PersonFactory())

        toggle_switch('enable_publisher_email_notifications', True)
    def setUp(self):
        super().setUp()
        self.pk_generator = itertools.count(1)

        stored_site, created = Site.objects.get_or_create(  # pylint: disable=unused-variable
            domain='example.com')
        self.default_partner = Partner.objects.create(site=stored_site,
                                                      name='edX',
                                                      short_code='edx')

        SeatType.objects.all().delete()
        ProgramType.objects.all().delete()

        self.partner = PartnerFactory(name='Test')
        self.organization = OrganizationFactory(partner=self.partner)
        self.seat_type_verified = SeatTypeFactory(name='Verified',
                                                  slug='verified')
        self.program_type_masters = ProgramTypeFactory(
            name='Masters',
            name_t='Masters',
            slug='masters',
            applicable_seat_types=[self.seat_type_verified])
        self.program_type_masters_translation = self.program_type_masters.translations.all(
        )[0]

        self.program_type_mm = ProgramTypeFactory(
            name='MicroMasters',
            name_t='MicroMasters',
            slug='micromasters',
            applicable_seat_types=[self.seat_type_verified])
        self.program_type_mm_translation = self.program_type_mm.translations.all(
        )[0]

        self.course = CourseFactory(
            partner=self.partner, authoring_organizations=[self.organization])
        self.course_run = CourseRunFactory(course=self.course)
        self.program = ProgramFactory(
            type=self.program_type_masters,
            partner=self.partner,
            authoring_organizations=[self.organization])
        self.course_mm = CourseFactory(
            partner=self.partner, authoring_organizations=[self.organization])
        self.course_run_mm = CourseRunFactory(course=self.course)
        self.program_mm = ProgramFactory(
            type=self.program_type_mm,
            partner=self.partner,
            authoring_organizations=[self.organization],
            courses=[self.course_mm])
        self.curriculum = CurriculumFactory(program=self.program)
        self.curriculum_course_membership = CurriculumCourseMembershipFactory(
            course=self.course, curriculum=self.curriculum)
        self.curriculum_program_membership = CurriculumProgramMembershipFactory(
            program=self.program_mm, curriculum=self.curriculum)

        self.program_2 = ProgramFactory(
            type=self.program_type_masters,
            partner=self.partner,
            authoring_organizations=[self.organization])

        self._mock_oauth_request()
Beispiel #9
0
    def test_discovery_counterpart_success(self):
        """
        Verify that CourseRun discovery_counterpart property returns
        corresponding Discovery CourseRun object.
        """
        pacing_type_test_value = 'test_pacing_type_value'

        # create a fresh course run object to avoid issues with caching of discovery_counterpart property
        course_run = factories.CourseRunFactory()
        organization = OrganizationFactory()

        discovery_course = self.create_discovery_course_with_partner(organization.partner)
        discovery_course_run = self.create_discovery_course_run_with_metadata(
            discovery_course,
            {'pacing_type': pacing_type_test_value}
        )

        self.add_organization_to_course(course_run.course, organization)

        # make sure Publisher course key and Course Metadata course key match
        course_run.course.key = discovery_course.key
        # make sure Publisher course run key and Course Metadata course run key match
        course_run.lms_course_id = discovery_course_run.key

        assert course_run.discovery_counterpart == discovery_course_run
Beispiel #10
0
    def setUp(self):
        super(TestMigrateCommentsToSalesforce, self).setUp()
        self.partner = PartnerFactory()
        self.user_1 = UserFactory()
        self.org_1 = OrganizationFactory(partner=self.partner)
        self.course_1 = CourseFactory(
            partner=self.partner,
            authoring_organizations=[self.org_1],
            key=self.org_1.key + '+101x',
            title='Old Title',
        )
        self.course_run_1 = CourseRunFactory(
            key='course-v1:{key}+1T2019'.format(
                key=self.course_1.key,
            ),
            course=self.course_1,
        )

        self.publisher_course_1 = PublisherCourseFactory(number='101x', title='New Title')
        self.publisher_course_1.organizations.add(self.org_1)  # pylint: disable=no-member
        self.publisher_course_run_1 = PublisherCourseRunFactory(
            course=self.publisher_course_1,
            lms_course_id='course-v1:{org}+{number}+1T2019'.format(
                org=self.org_1.key, number=self.publisher_course_1.number
            ),
        )
Beispiel #11
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
Beispiel #12
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'))
Beispiel #13
0
    def test_do_not_index_if_not_active(self):
        unpublished_program = AlgoliaProxyProgramFactory(partner=self.__class__.edxPartner,
                                                         status=ProgramStatus.Unpublished)
        unpublished_program.authoring_organizations.add(OrganizationFactory())

        retired_program = AlgoliaProxyProgramFactory(partner=self.__class__.edxPartner,
                                                     status=ProgramStatus.Retired)
        retired_program.authoring_organizations.add(OrganizationFactory())

        deleted_program = AlgoliaProxyProgramFactory(partner=self.__class__.edxPartner,
                                                     status=ProgramStatus.Deleted)
        deleted_program.authoring_organizations.add(OrganizationFactory())

        assert not unpublished_program.should_index
        assert not retired_program.should_index
        assert not deleted_program.should_index
Beispiel #14
0
 def setUp(self):
     super(PublisherCustomCourseFormTests, self).setUp()
     self.course_form = CourseForm()
     self.organization = OrganizationFactory()
     self.course = CourseFactory(title='Test',
                                 number='a123',
                                 organizations=[self.organization])
Beispiel #15
0
    def setUp(self):
        super(CourseRunWrapperTests, self).setUp()
        organization = OrganizationFactory()
        self.course_run = factories.CourseRunFactory(course__organizations=[organization])
        self.course = self.course_run.course

        self.wrapped_course_run = CourseRunWrapper(self.course_run)
Beispiel #16
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
Beispiel #17
0
    def test_search_single(self):
        org = OrganizationFactory()
        course = CourseFactory(authoring_organizations=[org])
        person1 = PersonFactory(partner=self.partner)
        person2 = PersonFactory(partner=self.partner)
        PersonFactory(partner=self.partner)
        CourseRunFactory(staff=[person1, person2], course=course)

        facet_name = 'organizations_exact:{org_key}'.format(org_key=org.key)
        self.reindex_people(person1)
        self.reindex_people(person2)

        query = {'selected_facets': facet_name}
        qs = urllib.parse.urlencode(query)
        url = '{path}?{qs}'.format(path=self.path, qs=qs)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        response_data = response.json()
        self.assertEqual(response_data['objects']['count'], 2)

        query = {'selected_facets': facet_name, 'q': person1.uuid}
        qs = urllib.parse.urlencode(query)
        url = '{path}?{qs}'.format(path=self.path, qs=qs)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        response_data = response.json()
        self.assertEqual(response_data['objects']['count'], 1)
        self.assertEqual(response_data['objects']['results'][0]['uuid'],
                         str(person1.uuid))
        self.assertEqual(response_data['objects']['results'][0]['full_name'],
                         person1.full_name)
Beispiel #18
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'))
Beispiel #19
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,
            )
    def setUp(self):
        super(CourseRunMarkAsReviewedEmailTests, self).setUp()
        self.user = UserFactory()
        self.user_2 = UserFactory()
        self.user_3 = UserFactory()

        self.seat = factories.SeatFactory()
        self.course_run = self.seat.course_run
        self.course = self.course_run.course
        self.course.organizations.add(OrganizationFactory())

        # add user in course-user-role table
        factories.CourseUserRoleFactory(course=self.course,
                                        role=PublisherUserRole.CourseTeam,
                                        user=self.user_2)
        factories.CourseUserRoleFactory(course=self.course,
                                        role=PublisherUserRole.Publisher,
                                        user=self.user_3)
        self.course_run_state = factories.CourseRunStateFactory(
            course_run=self.course_run)

        self.course_run.lms_course_id = 'course-v1:edX+DemoX+Demo_Course'
        self.course_run.save()

        toggle_switch('enable_publisher_email_notifications', True)
Beispiel #21
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)
 def test_do_not_index_if_no_url_slug(self):
     course = self.create_course_with_basic_active_course_run()
     course.authoring_organizations.add(OrganizationFactory())
     for url_slug in course.url_slug_history.all():
         url_slug.is_active = False
         url_slug.save()
     assert not course.should_index
 def test_do_not_index_if_active_course_run_is_hidden(self):
     course = self.create_course_with_basic_active_course_run()
     course.authoring_organizations.add(OrganizationFactory())
     for course_run in course.course_runs.all():
         course_run.hidden = True
         course_run.save()
     assert not course.should_index
Beispiel #24
0
 def test_404_nonexistent(self):
     self.login_staff()
     program = self.create_program([OrganizationFactory()])
     bad_uuid = 'e9222eb7-7218-4a8b-9dff-b42bafbf6ed7'
     with self.assertNumQueries(self.queries(1)):
         response = self.get([program.uuid, bad_uuid])
     self.assertEqual(response.status_code, 404)
Beispiel #25
0
    def test_ingest_respects_partner(self):
        """
        Existing organizations with the same key but linked to different partners
        shouldn't cause organization data loading to fail.
        """
        api_data = self.mock_api()
        key = api_data[1]['short_name']

        OrganizationFactory(key=key, partner=self.partner)
        OrganizationFactory(key=key)

        assert Organization.objects.count() == 2

        self.loader.ingest()

        assert Organization.objects.count() == len(api_data) + 1
Beispiel #26
0
    def setUp(self):
        super().setUp()
        self.org = OrganizationFactory(name='MyOrg', key='myorg')
        self.course_run = CourseRunFactory(draft=True,
                                           title_override='MyCourse')
        self.course = self.course_run.course
        self.course.authoring_organizations.add(self.org)
        self.partner = self.course.partner
        self.group = GroupFactory()
        self.pc = self.make_user(email='*****@*****.**')
        self.editor = self.make_user(groups=[self.group])
        self.editor2 = self.make_user(groups=[self.group])
        self.non_editor = self.make_user(groups=[self.group])
        self.legal = self.make_user(
            groups=[Group.objects.get(name=LEGAL_TEAM_GROUP_NAME)])

        CourseEditorFactory(user=self.editor, course=self.course)
        CourseEditorFactory(user=self.editor2, course=self.course)
        OrganizationExtensionFactory(group=self.group, organization=self.org)
        OrganizationUserRoleFactory(user=self.pc,
                                    organization=self.org,
                                    role=InternalUserRole.ProjectCoordinator)

        self.publisher_url = '{}courses/{}'.format(self.partner.publisher_url,
                                                   self.course_run.course.uuid)
        self.studio_url = '{}course/{}'.format(self.partner.studio_url,
                                               self.course_run.key)
        self.admin_url = 'https://{}/admin/course_metadata/courserun/{}/change/'.format(
            self.partner.site.domain, self.course_run.id)
        self.run_num = CourseKey.from_string(self.course_run.key).run
Beispiel #27
0
    def test_publish_with_additional_organization(self, mock_access_token):
        """
        Test that the publish button does not remove existing organization
        """
        publisher_course_run = self._create_course_run_for_publication()

        partner = publisher_course_run.course.organizations.first().partner
        self._set_test_client_domain_and_login(partner)

        self._mock_studio_api_success(publisher_course_run)
        self._mock_ecommerce_api(publisher_course_run)

        publish_url = reverse('publisher:api:v1:course_run-publish',
                              kwargs={'pk': publisher_course_run.pk})
        response = self.client.post(publish_url, {})
        assert response.status_code == 200
        discovery_course_run = CourseRun.objects.get(
            key=publisher_course_run.lms_course_id)
        publisher_course = publisher_course_run.course
        discovery_course = discovery_course_run.course
        assert discovery_course.authoring_organizations.all().count() == 1

        publisher_course.organizations.add(OrganizationFactory())
        response = self.client.post(publish_url, {})
        assert response.status_code == 200
        assert discovery_course.authoring_organizations.all().count() == 2
Beispiel #28
0
    def test_ingest_handles_draft(self, official_exists, draft_exists, partner_uses_publisher):
        """
        Verify the method ingests data from the Courses API, and updates both official and draft versions.
        """
        datum = mock_data.COURSES_API_BODY_ORIGINAL
        self.mock_api([datum])

        if not partner_uses_publisher:
            self.partner.publisher_url = None
            self.partner.save()

        official_run = None
        draft_run = None

        course_key = '{org}+{number}'.format(org=datum['org'], number=datum['number'])
        run_key = datum['id']
        official_course_kwargs = {}
        official_run_kwargs = {}
        all_courses = set()
        all_runs = set()
        audit_run_type = CourseRunType.objects.get(slug=CourseRunType.AUDIT)
        if draft_exists or official_exists:
            org = OrganizationFactory(key=datum['org'])
        if draft_exists:
            draft_course = Course.objects.create(partner=self.partner, key=course_key, title='Title', draft=True)
            draft_run = CourseRun.objects.create(course=draft_course, key=run_key, type=audit_run_type, draft=True)
            draft_course.canonical_course_run = draft_run
            draft_course.save()
            draft_course.authoring_organizations.add(org)
            official_course_kwargs = {'draft_version': draft_course}
            official_run_kwargs = {'draft_version': draft_run}
            all_courses.add(draft_course)
            all_runs.add(draft_run)
        if official_exists:
            official_course = Course.objects.create(partner=self.partner, key=course_key, title='Title',
                                                    **official_course_kwargs)
            official_run = CourseRun.objects.create(course=official_course, key=run_key, type=audit_run_type,
                                                    **official_run_kwargs)
            official_course.canonical_course_run = official_run
            official_course.save()
            official_course.authoring_organizations.add(org)
            all_courses.add(official_course)
            all_runs.add(official_run)

        self.loader.ingest()

        if draft_exists or official_exists:
            self.assertEqual(set(Course.everything.all()), all_courses)
            self.assertEqual(set(CourseRun.everything.all()), all_runs)
        else:
            # We should have made official versions of the data
            official_course = Course.everything.get()
            official_run = CourseRun.everything.get()
            self.assertFalse(official_course.draft)
            self.assertFalse(official_run.draft)
            self.assertEqual(official_course.canonical_course_run, official_run)

        self.assert_run_and_course_updated(datum, draft_run, draft_exists, True, partner_uses_publisher)
        self.assert_run_and_course_updated(datum, official_run, official_exists, False, partner_uses_publisher)
    def test_retrieve(self):
        """ Verify the endpoint returns details for a single organization. """
        organization = OrganizationFactory(partner=self.partner)
        url = reverse('api:v1:organization-detail', kwargs={'uuid': organization.uuid})

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assert_response_data_valid(response, organization, many=False)
 def test_data(self):
     request = make_request()
     organizations = OrganizationFactory()
     course = CourseFactory(authoring_organizations=[organizations])
     CourseRunFactory.create_batch(2, course=course)
     serializer = self.serializer_class(course,
                                        context={'request': request})
     expected = self.get_expected_data(course, request)
     self.assertDictEqual(serializer.data, expected)