Ejemplo n.º 1
0
    def test_exclude_utm(self):
        request = make_request()
        course = CourseFactory()
        CourseRunFactory.create_batch(3, course=course)
        serializer = self.serializer_class(course, context={'request': request, 'exclude_utm': 1})

        self.assertEqual(serializer.data['marketing_url'], course.marketing_url)
    def test_filter_by_license(self):
        CourseRun.objects.all().delete()
        course_runs_cc = CourseRunFactory.create_batch(3, course__partner=self.partner, license='cc-by-sa')
        CourseRunFactory.create_batch(3, course__partner=self.partner, license='')

        url = reverse('api:v1:course_run-list') + '?license=cc-by-sa'
        self.assert_list_results(url, course_runs_cc)
    def test_data(self):
        course = CourseFactory()
        image = course.image
        video = course.video

        request = make_request()

        CourseRunFactory.create_batch(3, course=course)
        serializer = CourseSerializer(course, context={'request': request})

        expected = {
            'key': course.key,
            'title': course.title,
            'short_description': course.short_description,
            'full_description': course.full_description,
            'level_type': course.level_type.name,
            'subjects': [],
            'prerequisites': [],
            'expected_learning_items': [],
            'image': ImageSerializer(image).data,
            'video': VideoSerializer(video).data,
            'owners': [],
            'sponsors': [],
            'modified': json_date_format(course.modified),  # pylint: disable=no-member
            'course_runs': CourseRunSerializer(course.course_runs, many=True, context={'request': request}).data,
            'marketing_url': '{url}?{params}'.format(
                url=course.marketing_url,
                params=urlencode({
                    'utm_source': request.user.username,
                    'utm_medium': request.user.referral_tracking_id,
                })
            )
        }

        self.assertDictEqual(serializer.data, expected)
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
 def test_filter_by_marketable(self):
     """ Verify the endpoint filters course runs to those that are marketable. """
     CourseRun.objects.all().delete()
     expected = CourseRunFactory.create_batch(3, course__partner=self.partner)
     CourseRunFactory.create_batch(3, slug=None, course__partner=self.partner)
     CourseRunFactory.create_batch(3, slug='', course__partner=self.partner)
     url = reverse('api:v1:course_run-list') + '?marketable=1'
     self.assert_list_results(url, expected)
Ejemplo n.º 6
0
 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)
Ejemplo n.º 7
0
    def setUp(self):
        super(SearchQuerySetWrapperTests, self).setUp()
        title = 'Some random course'
        query = 'title:' + title

        CourseRunFactory.create_batch(3, title=title)
        self.search_queryset = SearchQuerySet().models(CourseRun).raw_search(query).load_all()
        self.course_runs = [e.object for e in self.search_queryset]
        self.wrapper = SearchQuerySetWrapper(self.search_queryset)
 def test_filter_by_hidden(self):
     """ Verify the endpoint filters course runs that are hidden. """
     CourseRun.objects.all().delete()
     course_runs = CourseRunFactory.create_batch(3, course__partner=self.partner)
     hidden_course_runs = CourseRunFactory.create_batch(3, hidden=True, course__partner=self.partner)
     url = reverse('api:v1:course_run-list')
     self.assert_list_results(url, course_runs + hidden_course_runs)
     url = reverse('api:v1:course_run-list') + '?hidden=False'
     self.assert_list_results(url, course_runs)
Ejemplo n.º 9
0
    def setUp(self):
        super(SearchQuerySetWrapperTests, self).setUp()
        title = 'Some random course'
        query = 'title:' + title

        CourseRunFactory.create_batch(3, title=title)
        self.search_queryset = SearchQuerySet().models(CourseRun).raw_search(
            query).load_all()
        self.course_runs = [e.object for e in self.search_queryset]
        self.wrapper = SearchQuerySetWrapper(self.search_queryset)
Ejemplo n.º 10
0
    def setUp(self):
        super().setUp()
        title = 'Some random course'
        query = 'title:' + title

        CourseRunFactory.create_batch(3, title=title)
        self.search_queryset = CourseRunDocument().search().query(
            'query_string', query=query)
        self.course_runs = [e.object for e in self.search_queryset]
        self.wrapper = SearchQuerySetWrapper(self.search_queryset)
Ejemplo n.º 11
0
    def test_update_using_api(self):
        """
        Verify endpoint successfully updates a program.
        """
        program_data = self._program_data()

        response = self.client.post(self.list_path, program_data, format='json')
        assert response.status_code == 201
        program = Program.objects.last()
        assert program.courses.count() == 3
        assert program.authoring_organizations.count() == 3
        assert program.credit_backing_organizations.count() == 3

        program_detail_url = reverse('api:v1:program-detail', kwargs={'uuid': str(program.uuid)})
        program.title = '{orignal_title} Test Update'.format(orignal_title=program_data['title'])
        program_data['status'] = 'unpublished'

        course_runs = CourseRunFactory.create_batch(2)
        course_runs = [course_run.key for course_run in course_runs]
        program_data['course_runs'] = program_data['course_runs'] + course_runs

        organizations = OrganizationFactory.create_batch(3)
        organizations = [organization.key for organization in organizations]
        program_data['authoring_organizations'] = program_data['authoring_organizations'] + organizations
        program_data['credit_backing_organizations'] = program_data['credit_backing_organizations'] + organizations

        data = json.dumps(program_data)
        response = self.client.patch(program_detail_url, data, content_type='application/json')
        assert response.status_code == 200
        program = Program.objects.last()
        assert program.title == response.data['title']
        assert program.status == response.data['status']
        assert program.courses.count() == 5
        assert program.authoring_organizations.count() == 6
        assert program.credit_backing_organizations.count() == 6

        course_runs = CourseRunFactory.create_batch(2)
        course_runs = [course_run.key for course_run in course_runs]
        course_runs.append(program_data['course_runs'][0])
        program_data['course_runs'] = course_runs

        organizations = OrganizationFactory.create_batch(3)
        organizations = [organization.key for organization in organizations]
        organizations.append(program_data['authoring_organizations'][0])
        program_data['authoring_organizations'] = organizations
        program_data['credit_backing_organizations'] = organizations

        data = json.dumps(program_data)
        response = self.client.patch(program_detail_url, data, content_type='application/json')
        assert response.status_code == 200
        program = Program.objects.last()
        assert program.courses.count() == 3
        assert program.authoring_organizations.count() == 4
        assert program.credit_backing_organizations.count() == 4
Ejemplo n.º 12
0
 def test_filter_by_marketable(self):
     """ Verify the endpoint filters course runs to those that are marketable. """
     CourseRun.objects.all().delete()
     expected = CourseRunFactory.create_batch(3,
                                              course__partner=self.partner)
     CourseRunFactory.create_batch(3,
                                   slug=None,
                                   course__partner=self.partner)
     CourseRunFactory.create_batch(3, slug='', course__partner=self.partner)
     url = reverse('api:v1:course_run-list') + '?marketable=1'
     self.assert_list_results(url, expected)
Ejemplo n.º 13
0
    def test_exclude_utm(self):
        request = make_request()
        course = CourseFactory()
        CourseRunFactory.create_batch(3, course=course)
        serializer = self.serializer_class(course,
                                           context={
                                               'request': request,
                                               'exclude_utm': 1
                                           })

        self.assertEqual(serializer.data['marketing_url'],
                         course.marketing_url)
 def test_filter_by_keys(self):
     """ Verify the endpoint returns a list of course runs filtered by the specified keys. """
     CourseRun.objects.all().delete()
     expected = CourseRunFactory.create_batch(3, course__partner=self.partner)
     keys = ','.join([course.key for course in expected])
     url = '{root}?keys={keys}'.format(root=reverse('api:v1:course_run-list'), keys=keys)
     self.assert_list_results(url, expected)
Ejemplo n.º 15
0
    def setUp(self):
        super(CreateCoursesTests, self).setUp()

        transcript_languages = LanguageTag.objects.all()[:2]
        self.subjects = SubjectFactory.create_batch(3)
        self.course = CourseFactory(subjects=self.subjects)

        self.command_name = 'import_metadata_courses'
        self.command_args = ['--start_id={}'.format(self.course.id), '--end_id={}'.format(self.course.id)]

        # create multiple course-runs against course.
        course_runs = CourseRunFactory.create_batch(
            3, course=self.course, transcript_languages=transcript_languages,
            language=transcript_languages[0],
            short_description_override='Testing description'
        )

        canonical_course_run = course_runs[0]
        for seat_type in ['honor', 'credit', 'verified']:  # to avoid same type seat creation.
            SeatFactory(course_run=canonical_course_run, type=seat_type)

        staff = PersonFactory.create_batch(2)
        canonical_course_run.staff.add(*staff)

        self.course.canonical_course_run = canonical_course_run
        self.course.save()

        # create org and assign to the course-metadata
        self.forganization_extension = factories.OrganizationExtensionFactory()
        self.organization = self.forganization_extension.organization
        self.course.authoring_organizations.add(self.organization)
Ejemplo n.º 16
0
 def test_filter_by_keys(self):
     """ Verify the endpoint returns a list of course runs filtered by the specified keys. """
     CourseRun.objects.all().delete()
     expected = CourseRunFactory.create_batch(3, course__partner=self.partner)
     keys = ','.join([course.key for course in expected])
     url = '{root}?keys={keys}'.format(root=reverse('api:v1:course_run-list'), keys=keys)
     self.assert_list_results(url, expected)
Ejemplo n.º 17
0
    def test_sanity_check_success(self):
        """ Verify the command does not raise a CommandError error if the new index passes the sanity check. """
        CourseRunFactory.create_batch(59)
        ProgramFactory.create_batch(59)
        PersonFactory.create_batch(59)
        record_count = 60

        # Ensure that no error is raised and the sanity check passes the second time
        with mock.patch(
                'course_discovery.apps.core.utils.ElasticsearchUtils.set_alias',
                return_value=True):
            with mock.patch(
                    'course_discovery.apps.edx_elasticsearch_dsl_extensions.management.commands.'
                    'update_index.Command.get_record_count',
                    return_value=record_count):
                call_command('update_index')
Ejemplo n.º 18
0
    def test_with_exclusions(self):
        """
        Test serializer with course_run exclusions within program
        """
        request = make_request()
        course = CourseFactory()
        excluded_runs = []
        course_runs = CourseRunFactory.create_batch(2, course=course)
        excluded_runs.append(course_runs[0])
        program = ProgramFactory(courses=[course],
                                 excluded_course_runs=excluded_runs)

        serializer_context = {
            'request': request,
            'program': program,
            'course_runs': list(program.course_runs)
        }
        serializer = MinimalProgramCourseSerializer(course,
                                                    context=serializer_context)

        expected = MinimalCourseSerializer(course,
                                           context=serializer_context).data
        expected['course_runs'] = MinimalCourseRunSerializer([course_runs[1]],
                                                             many=True,
                                                             context={
                                                                 'request':
                                                                 request
                                                             }).data
        self.assertDictEqual(serializer.data, expected)
Ejemplo n.º 19
0
    def test_sanity_check_error(self):
        """ Verify the command raises a CommandError if new index fails the sanity check. """
        CourseRunFactory()
        additional_runs = int(100 * settings.INDEX_SIZE_CHANGE_THRESHOLD + 1)
        CourseRunFactory.create_batch(additional_runs)

        # Ensure that an error is raised if the sanity check does not pass
        with pytest.raises(CommandError):
            with mock.patch(
                    'course_discovery.apps.core.utils.ElasticsearchUtils.set_alias',
                    return_value=True):
                with mock.patch(
                        'course_discovery.apps.edx_elasticsearch_dsl_extensions.management.commands.'
                        'update_index.Command.percentage_change',
                        return_value=0.5):
                    call_command('update_index')
Ejemplo n.º 20
0
    def test_sanity_check_success(self):
        """ Verify the command does not raise a CommandError error if the new index passes the sanity check. """
        CourseRunFactory.create_batch(30)
        record_count = 60
        additional_runs = int(10 * settings.INDEX_SIZE_CHANGE_THRESHOLD - 1)
        CourseRunFactory.create_batch(additional_runs)

        # Ensure that no error is raised and the sanity check passes the second time
        with mock.patch(
                'course_discovery.apps.edx_haystack_extensions.management.commands.'
                'update_index.Command.set_alias',
                return_value=True):
            with mock.patch(
                    'course_discovery.apps.edx_haystack_extensions.management.commands.'
                    'update_index.Command.get_record_count',
                    return_value=record_count):
                call_command('update_index')
Ejemplo n.º 21
0
    def test_sanity_check_error(self):
        """ Verify the command raises a CommandError if new index fails the sanity check. """
        CourseRunFactory()
        record_count = 2
        additional_runs = int(100 * settings.INDEX_SIZE_CHANGE_THRESHOLD + 1)
        CourseRunFactory.create_batch(additional_runs)

        # Ensure that an error is raised if the sanity check does not pass
        with pytest.raises(CommandError):
            with mock.patch(
                    'course_discovery.apps.edx_haystack_extensions.management.commands.'
                    'update_index.Command.set_alias',
                    return_value=True):
                with mock.patch(
                        'course_discovery.apps.edx_haystack_extensions.management.commands.'
                        'update_index.Command.get_record_count',
                        return_value=record_count):
                    call_command('update_index')
    def test_list_key_filter(self):
        """ Verify the endpoint returns a list of course runs filtered by the specified keys. """
        course_runs = CourseRunFactory.create_batch(3)
        course_runs = sorted(course_runs, key=lambda course: course.key.lower())
        keys = ','.join([course.key for course in course_runs])
        url = '{root}?keys={keys}'.format(root=reverse('api:v1:course_run-list'), keys=keys)

        response = self.client.get(url)
        self.assertListEqual(response.data['results'], self.serialize_course_run(course_runs, many=True))
Ejemplo n.º 23
0
    def test_course_run_autocomplete(self, admin_client):
        course_runs = CourseRunFactory.create_batch(3)
        path = reverse('admin_metadata:course-run-autocomplete')
        response = admin_client.get(path)
        data = json.loads(response.content.decode('utf-8'))
        assert response.status_code == 200
        assert len(data['results']) == 3

        # Search for substrings of course run keys and titles
        course_run = course_runs[0]
        self.assert_valid_query_result(admin_client, path, course_run.key[14:], course_run)
        self.assert_valid_query_result(admin_client, path, course_run.title[12:], course_run)

        course = course_run.course
        CourseRunFactory.create_batch(3, course=course)
        response = admin_client.get(path + '?forward={f}'.format(f=json.dumps({'course': course.pk})))
        data = json.loads(response.content.decode('utf-8'))
        assert response.status_code == 200
        assert len(data['results']) == 4
Ejemplo n.º 24
0
    def create_program(self):
        organizations = OrganizationFactory.create_batch(2)
        person = PersonFactory()

        courses = CourseFactory.create_batch(3)
        for course in courses:
            CourseRunFactory.create_batch(2, course=course, staff=[person], start=datetime.now())

        return ProgramFactory(
            courses=courses,
            authoring_organizations=organizations,
            credit_backing_organizations=organizations,
            corporate_endorsements=CorporateEndorsementFactory.create_batch(1),
            individual_endorsements=EndorsementFactory.create_batch(1),
            expected_learning_items=ExpectedLearningItemFactory.create_batch(1),
            job_outlook_items=JobOutlookItemFactory.create_batch(1),
            banner_image=make_image_file('test_banner.jpg'),
            video=VideoFactory(),
            order_courses_by_start_date=False,
        )
Ejemplo n.º 25
0
    def setUp(self):
        super(ImportCoursesTests, self).setUp()
        self.course = CourseFactory()
        self.course_runs = CourseRunFactory.create_batch(3, course=self.course)
        self.course.canonical_course_run = self.course_runs[2]
        self.course.save()

        # add multiple courses.
        self.course_2 = CourseFactory()

        self.command_name = 'import_metadata_courses'
        self.command_args = ['--start_id={}'.format(self.course.id), '--end_id={}'.format(self.course.id)]
    def test_list_query(self):
        """ Verify the endpoint returns a filtered list of courses """
        title = 'Some random title'
        course_runs = CourseRunFactory.create_batch(3, title=title)
        CourseRunFactory(title='non-matching name')
        query = 'title:' + title
        url = '{root}?q={query}'.format(root=reverse('api:v1:course_run-list'), query=query)

        response = self.client.get(url)
        actual_sorted = sorted(response.data['results'], key=lambda course_run: course_run['key'])
        expected_sorted = sorted(self.serialize_course_run(course_runs, many=True),
                                 key=lambda course_run: course_run['key'])
        self.assertListEqual(actual_sorted, expected_sorted)
    def test_list_query(self):
        """ Verify the endpoint returns a filtered list of courses """
        course_runs = CourseRunFactory.create_batch(3, title='Some random title', course__partner=self.partner)
        CourseRunFactory(title='non-matching name')
        query = 'title:Some random title'
        url = '{root}?q={query}'.format(root=reverse('api:v1:course_run-list'), query=query)

        with self.assertNumQueries(39):
            response = self.client.get(url)

        actual_sorted = sorted(response.data['results'], key=lambda course_run: course_run['key'])
        expected_sorted = sorted(self.serialize_course_run(course_runs, many=True),
                                 key=lambda course_run: course_run['key'])
        self.assertListEqual(actual_sorted, expected_sorted)
Ejemplo n.º 28
0
 def _program_data(self):
     course_runs = CourseRunFactory.create_batch(3)
     organizations = OrganizationFactory.create_batch(3)
     return {
         "title": "Test Program",
         "type": "XSeries",
         "status": "active",
         "marketing_slug": "edX-test-program",
         "course_runs": [course_run.key for course_run in course_runs],
         "min_hours_effort_per_week": 10,
         "max_hours_effort_per_week": 20,
         "authoring_organizations": [organization.key for organization in organizations],
         "credit_backing_organizations": [organization.key for organization in organizations],
     }
Ejemplo n.º 29
0
    def create_program(self):
        organizations = OrganizationFactory.create_batch(2)
        person = PersonFactory()

        courses = CourseFactory.create_batch(3)
        for course in courses:
            CourseRunFactory.create_batch(2,
                                          course=course,
                                          staff=[person],
                                          start=datetime.now())

        return ProgramFactory(
            courses=courses,
            authoring_organizations=organizations,
            credit_backing_organizations=organizations,
            corporate_endorsements=CorporateEndorsementFactory.create_batch(1),
            individual_endorsements=EndorsementFactory.create_batch(1),
            expected_learning_items=ExpectedLearningItemFactory.create_batch(
                1),
            job_outlook_items=JobOutlookItemFactory.create_batch(1),
            banner_image=make_image_file('test_banner.jpg'),
            video=VideoFactory(),
            order_courses_by_start_date=False,
        )
Ejemplo n.º 30
0
    def test_with_exclusions(self):
        """
        Test serializer with course_run exclusions within program
        """
        request = make_request()
        course = CourseFactory()
        excluded_runs = []
        course_runs = CourseRunFactory.create_batch(2, course=course)
        excluded_runs.append(course_runs[0])
        program = ProgramFactory(courses=[course], excluded_course_runs=excluded_runs)

        serializer_context = {'request': request, 'program': program, 'course_runs': list(program.course_runs)}
        serializer = MinimalProgramCourseSerializer(course, context=serializer_context)

        expected = MinimalCourseSerializer(course, context=serializer_context).data
        expected['course_runs'] = MinimalCourseRunSerializer(
            [course_runs[1]], many=True, context={'request': request}).data
        self.assertDictEqual(serializer.data, expected)
Ejemplo n.º 31
0
    def test_ensure_draft_world_not_draft_course_given(self):
        course = CourseFactory()
        entitlement = CourseEntitlementFactory(course=course)
        course.entitlements.add(entitlement)
        course_runs = CourseRunFactory.create_batch(3, course=course)
        for run in course_runs:
            course.course_runs.add(run)
        course.canonical_course_run = course_runs[0]
        course.save()
        org = OrganizationFactory()
        course.authoring_organizations.add(org)  # pylint: disable=no-member

        ensured_draft_course = utils.ensure_draft_world(course)
        not_draft_course = Course.objects.get(uuid=course.uuid)

        self.assertNotEqual(ensured_draft_course, not_draft_course)
        self.assertEqual(ensured_draft_course.uuid, not_draft_course.uuid)
        self.assertTrue(ensured_draft_course.draft)

        # Check slugs are equal
        self.assertEqual(ensured_draft_course.slug, not_draft_course.slug)

        # Check authoring orgs are equal
        self.assertEqual(
            list(ensured_draft_course.authoring_organizations.all()),
            list(not_draft_course.authoring_organizations.all()))

        # Check canonical course run was updated
        self.assertNotEqual(ensured_draft_course.canonical_course_run,
                            not_draft_course.canonical_course_run)
        self.assertTrue(ensured_draft_course.canonical_course_run.draft)
        self.assertEqual(ensured_draft_course.canonical_course_run.uuid,
                         not_draft_course.canonical_course_run.uuid)

        # Check course runs all share the same UUIDs, but are now all drafts
        not_draft_course_runs_uuids = [run.uuid for run in course_runs]
        draft_course_runs_uuids = [
            run.uuid for run in ensured_draft_course.course_runs.all()
        ]
        self.assertListEqual(draft_course_runs_uuids,
                             not_draft_course_runs_uuids)

        # Entitlement checks
        draft_entitlement = ensured_draft_course.entitlements.first()
        not_draft_entitlement = not_draft_course.entitlements.first()
        self.assertNotEqual(draft_entitlement, not_draft_entitlement)
        self.assertEqual(draft_entitlement.price, not_draft_entitlement.price)
        self.assertEqual(draft_entitlement.sku, not_draft_entitlement.sku)
        self.assertNotEqual(draft_entitlement.course,
                            not_draft_entitlement.course)
        self.assertEqual(draft_entitlement.course.uuid,
                         not_draft_entitlement.course.uuid)

        # Check official and draft versions match up
        self.assertEqual(ensured_draft_course.official_version,
                         not_draft_course)
        self.assertEqual(not_draft_course.draft_version, ensured_draft_course)

        self.assertEqual(draft_entitlement.official_version,
                         not_draft_entitlement)
        self.assertEqual(not_draft_entitlement.draft_version,
                         draft_entitlement)