def test_contains_catalog_list_parent_key(self):
        """
        Verify the contains_content_items endpoint returns a list of catalogs the course is in
        """
        content_metadata = ContentMetadataFactory()
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [content_metadata])

        # Create a two catalogs that have the content we're looking for
        parent_content_key = 'fake-parent-key+105x'
        content_key = 'fake-key+101x'
        second_catalog = EnterpriseCatalogFactory(
            enterprise_uuid=self.enterprise_uuid)
        relevant_content = ContentMetadataFactory(
            content_key=content_key, parent_content_key=parent_content_key)
        self.add_metadata_to_catalog(second_catalog, [relevant_content])
        content_key_2 = 'fake-key+102x'
        third_catalog = EnterpriseCatalogFactory(
            enterprise_uuid=self.enterprise_uuid)
        relevant_content = ContentMetadataFactory(
            content_key=content_key_2, parent_content_key=parent_content_key)
        self.add_metadata_to_catalog(third_catalog, [relevant_content])

        url = self._get_contains_content_base_url(
        ) + '?course_run_ids=' + parent_content_key + '&get_catalog_list=True'
        response = self.client.get(url).json()
        assert response['contains_content_items'] is True
        catalog_list = response['catalog_list']
        assert set(catalog_list) == {
            str(second_catalog.uuid),
            str(third_catalog.uuid)
        }
Beispiel #2
0
    def test_update_full_metadata(self, mock_oauth_client,
                                  mock_partition_course_keys,
                                  mock_task_recently_run):
        """
        Assert that full course metadata is merged with original json_metadata for all ContentMetadata records.
        """
        course_key_1 = 'fakeX'
        course_data_1 = {
            'key': course_key_1,
            'full_course_only_field': 'test_1'
        }
        course_key_2 = 'testX'
        course_data_2 = {
            'key': course_key_2,
            'full_course_only_field': 'test_2'
        }
        non_course_key = 'course-runX'

        # Mock out the data that should be returned from discovery's /api/v1/courses endpoint
        mock_oauth_client.return_value.get.return_value.json.return_value = {
            'results': [course_data_1, course_data_2],
        }
        mock_partition_course_keys.return_value = (
            [],
            [],
        )

        metadata_1 = ContentMetadataFactory(content_type=COURSE,
                                            content_key=course_key_1)
        metadata_1.catalog_queries.set([self.catalog_query])
        metadata_2 = ContentMetadataFactory(content_type=COURSE,
                                            content_key=course_key_2)
        metadata_2.catalog_queries.set([self.catalog_query])
        non_course_metadata = ContentMetadataFactory(
            content_type=COURSE_RUN, content_key=non_course_key)
        non_course_metadata.catalog_queries.set([self.catalog_query])

        assert metadata_1.json_metadata != course_data_1
        assert metadata_2.json_metadata != course_data_2

        tasks.update_full_content_metadata_task.apply().get()

        actual_course_keys_args = mock_partition_course_keys.call_args_list[0][
            0][0]
        self.assertEqual(set(actual_course_keys_args),
                         set([metadata_1, metadata_2]))

        metadata_1 = ContentMetadata.objects.get(content_key='fakeX')
        metadata_2 = ContentMetadata.objects.get(content_key='testX')

        # add aggregation_key and uuid to course objects since they should now exist
        # after merging the original json_metadata with the course metadata
        course_data_1.update(metadata_1.json_metadata)
        course_data_2.update(metadata_2.json_metadata)
        course_data_1.update({'aggregation_key': 'course:fakeX'})
        course_data_2.update({'aggregation_key': 'course:testX'})

        assert metadata_1.json_metadata == course_data_1
        assert metadata_2.json_metadata == course_data_2
Beispiel #3
0
    def setUpTestData(cls):
        super().setUpTestData()
        cls.catalog_query_a = CatalogQueryFactory()
        cls.catalog_query_b = CatalogQueryFactory()
        cls.enterprise_catalog_a = EnterpriseCatalogFactory(
            catalog_query=cls.catalog_query_a)
        cls.enterprise_catalog_b = EnterpriseCatalogFactory(
            catalog_query=cls.catalog_query_b)

        ContentMetadataFactory.create_batch(3)
    def test_contains_content_items_parent_keys_in_catalog(self):
        """
        Verify the contains_content_items endpoint returns True if the parent's key is in the catalog
        """
        parent_metadata = ContentMetadataFactory(content_key='parent-key')
        associated_metadata = ContentMetadataFactory(
            content_key='child-key+101x',
            parent_content_key=parent_metadata.content_key)
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [associated_metadata])

        query_string = '?course_run_ids=' + parent_metadata.content_key
        url = self._get_contains_content_base_url(
            self.enterprise_catalog) + query_string
        self.assert_correct_contains_response(url, True)
Beispiel #5
0
 def test_should_index_course(
     self,
     expected_result,
     has_advertised_course_run=True,
     has_owners=True,
     has_url_slug=True,
     advertised_course_run_hidden=False,
 ):
     """
     Verify that only a course that has a non-hidden advertised course run, at least one owner, and a marketing slug
     is marked as indexable.
     """
     advertised_course_run_uuid = uuid4()
     course_run_uuid = advertised_course_run_uuid if has_advertised_course_run else uuid4()
     owners = [{'name': 'edX'}] if has_owners else []
     url_slug = 'test-slug' if has_url_slug else ''
     json_metadata = {
         'advertised_course_run_uuid': advertised_course_run_uuid,
         'course_runs': [
             {
                 'hidden': advertised_course_run_hidden,
                 'uuid': course_run_uuid,
             },
         ],
         'owners': owners,
         'url_slug': url_slug,
     }
     course_metadata = ContentMetadataFactory.create(
         content_type=COURSE,
         json_metadata=json_metadata,
     )
     assert _should_index_course(course_metadata) is expected_result
    def test_get_content_metadata_traverse_pagination(self,
                                                      learner_portal_enabled,
                                                      mock_api_client):
        """
        Verify the get_content_metadata endpoint returns all metadata on one page if the traverse pagination query
        parameter is added.
        """
        mock_api_client.return_value.get_enterprise_customer.return_value = {
            'slug': self.enterprise_slug,
            'enable_learner_portal': learner_portal_enabled,
        }
        # Create enough metadata to force pagination (if the query parameter wasn't sent)
        metadata = ContentMetadataFactory.create_batch(api_settings.PAGE_SIZE +
                                                       1)
        self.add_metadata_to_catalog(self.enterprise_catalog, metadata)
        url = self._get_content_metadata_url(
            self.enterprise_catalog) + '?traverse_pagination=1'
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        response_data = response.json()
        self.assertEqual((response_data['count']), api_settings.PAGE_SIZE + 1)
        self.assertEqual(uuid.UUID(response_data['uuid']),
                         self.enterprise_catalog.uuid)
        self.assertEqual(response_data['title'], self.enterprise_catalog.title)
        self.assertEqual(uuid.UUID(response_data['enterprise_customer']),
                         self.enterprise_catalog.enterprise_uuid)

        # Check that the page contains all the metadata
        expected_metadata = [
            self._get_expected_json_metadata(item, learner_portal_enabled)
            for item in metadata
        ]
        actual_metadata = response_data['results']
        self.assertCountEqual(actual_metadata, expected_metadata)
    def test_get_content_metadata(self, learner_portal_enabled,
                                  mock_api_client):
        """
        Verify the get_content_metadata endpoint returns all the metadata associated with a particular catalog
        """
        mock_api_client.return_value.get_enterprise_customer.return_value = {
            'slug': self.enterprise_slug,
            'enable_learner_portal': learner_portal_enabled,
        }
        # The ContentMetadataFactory creates content with keys that are generated using a string builder with a
        # factory sequence (index is appended onto each content key). The results are sorted by key which creates
        # an unexpected sorting of [key0, key1, key10, key2, ...] so the test fails on
        # self.assertEqual(actual_metadata, expected_metadata[:-1]). By resetting the factory sequence to start at
        # 10 we avoid that sorting issue.
        ContentMetadataFactory.reset_sequence(10)
        # Create enough metadata to force pagination
        metadata = ContentMetadataFactory.create_batch(api_settings.PAGE_SIZE +
                                                       1)
        self.add_metadata_to_catalog(self.enterprise_catalog, metadata)
        url = self._get_content_metadata_url(self.enterprise_catalog)
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        response_data = response.json()
        self.assertEqual((response_data['count']), api_settings.PAGE_SIZE + 1)
        self.assertEqual(uuid.UUID(response_data['uuid']),
                         self.enterprise_catalog.uuid)
        self.assertEqual(response_data['title'], self.enterprise_catalog.title)
        self.assertEqual(uuid.UUID(response_data['enterprise_customer']),
                         self.enterprise_catalog.enterprise_uuid)

        # Check that the first page contains all but the last metadata
        expected_metadata = sorted([
            self._get_expected_json_metadata(item, learner_portal_enabled)
            for item in metadata
        ],
                                   key=itemgetter('key'))
        actual_metadata = sorted(response_data['results'],
                                 key=itemgetter('key'))
        self.assertEqual(actual_metadata, expected_metadata[:-1])

        # Check that the second page contains the last metadata
        second_page_response = self.client.get(response_data['next'])
        self.assertEqual(second_page_response.status_code, status.HTTP_200_OK)
        self.assertEqual(second_page_response.json()['results'],
                         [expected_metadata[-1]])
    def test_contains_content_items_in_catalogs(self):
        """
        Verify the contains_content_items endpoint returns True if the content is in any associated catalog
        """
        content_metadata = ContentMetadataFactory()
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [content_metadata])

        # Create a second catalog that has the content we're looking for
        content_key = 'fake-key+101x'
        second_catalog = EnterpriseCatalogFactory(
            enterprise_uuid=self.enterprise_uuid)
        relevant_content = ContentMetadataFactory(content_key=content_key)
        self.add_metadata_to_catalog(second_catalog, [relevant_content])

        url = self._get_contains_content_base_url(
        ) + '?course_run_ids=' + content_key
        self.assert_correct_contains_response(url, True)
    def test_no_catalog_list_given_without_get_catalog_list_query(self):
        """
        Verify that the contains_content_items endpoint does not return a list of catalogs without a querystring
        """
        content_metadata = ContentMetadataFactory()
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [content_metadata])

        # Create a second catalog that has the content we're looking for
        content_key = 'fake-key+101x'
        second_catalog = EnterpriseCatalogFactory(
            enterprise_uuid=self.enterprise_uuid)
        relevant_content = ContentMetadataFactory(content_key=content_key)
        self.add_metadata_to_catalog(second_catalog, [relevant_content])
        url = self._get_contains_content_base_url(
        ) + '?course_run_ids=' + content_key
        response = self.client.get(url)
        assert 'catalog_list' not in response.json().keys()
    def setUpTestData(cls):
        super().setUpTestData()

        cls.number_of_metadata_items = 3
        cls.content_metadata = ContentMetadataFactory.create_batch(
            cls.number_of_metadata_items, content_type=COURSE)
        cls.content_keys = [
            metadata.content_key for metadata in cls.content_metadata
        ]
Beispiel #11
0
    def test_contains_content_items_not_in_catalogs(self):
        """
        Verify the contains_content_items endpoint returns False if the content is not in any associated catalog
        """
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [ContentMetadataFactory()])

        url = self._get_contains_content_base_url(
        ) + '?program_uuids=this-is-not-the-uuid-youre-looking-for'
        self.assert_correct_contains_response(url, False)
Beispiel #12
0
    def setUpTestData(cls):
        super().setUpTestData()
        cls.ALGOLIA_FIELDS = [
            'key', 'objectID', 'enterprise_customer_uuids',
            'enterprise_catalog_uuids'
        ]

        # Set up a catalog, query, and metadata for a course
        cls.enterprise_catalog_courses = EnterpriseCatalogFactory()
        courses_catalog_query = cls.enterprise_catalog_courses.catalog_query
        cls.course_metadata = ContentMetadataFactory(content_type=COURSE,
                                                     content_key='fakeX')
        cls.course_metadata.catalog_queries.set([courses_catalog_query])

        # Set up new catalog, query, and metadata for a course run
        cls.enterprise_catalog_course_runs = EnterpriseCatalogFactory()
        course_runs_catalog_query = cls.enterprise_catalog_course_runs.catalog_query
        course_run_metadata = ContentMetadataFactory(
            content_type=COURSE_RUN, parent_content_key='fakeX')
        course_run_metadata.catalog_queries.set([course_runs_catalog_query])
Beispiel #13
0
    def test_contains_content_items_keys_in_catalog(self):
        """
        Verify the contains_content_items endpoint returns True if the keys are explicitly in the catalog
        """
        content_key = 'test-key'
        associated_metadata = ContentMetadataFactory(content_key=content_key)
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [associated_metadata])

        url = self._get_contains_content_base_url(
            self.enterprise_catalog) + '?course_run_ids=' + content_key
        self.assert_correct_contains_response(url, True)
Beispiel #14
0
    def test_contains_content_items_keys_not_in_catalog(self):
        """
        Verify the contains_content_items endpoint returns False if neither it or its parent's keys are in the catalog
        """
        associated_metadata = ContentMetadataFactory(
            content_key='some-unrelated-key')
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [associated_metadata])

        url = self._get_contains_content_base_url(
            self.enterprise_catalog) + '?course_run_ids=' + 'test-key'
        self.assert_correct_contains_response(url, False)
Beispiel #15
0
    def test_contains_catalog_list(self):
        """
        Verify the contains_content_items endpoint returns a list of catalogs the course is in if the correct
        parameter is passed
        """
        content_metadata = ContentMetadataFactory()
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [content_metadata])

        # Create a two catalogs that have the content we're looking for
        content_key = 'fake-key+101x'
        second_catalog = EnterpriseCatalogFactory(
            enterprise_uuid=self.enterprise_uuid)
        relevant_content = ContentMetadataFactory(content_key=content_key)
        self.add_metadata_to_catalog(second_catalog, [relevant_content])
        url = self._get_contains_content_base_url(
        ) + '?course_run_ids=' + content_key + '&get_catalog_list=True'
        self.assert_correct_contains_response(url, True)

        response = self.client.get(url)
        catalog_list = response.json()['catalog_list']
        assert set(catalog_list) == {str(second_catalog.uuid)}
Beispiel #16
0
    def test_contains_catalog_list_content_items_not_in_catalog(self):
        """
        Verify the contains_content_items endpoint returns a list of catalogs the course is in for multiple catalogs
        """
        content_metadata = ContentMetadataFactory()
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [content_metadata])

        content_key = 'fake-key+101x'

        url = self._get_contains_content_base_url(
        ) + '?course_run_ids=' + content_key + '&get_catalog_list=True'
        response = self.client.get(url)
        catalog_list = response.json()['catalog_list']
        assert catalog_list == []
Beispiel #17
0
    def test_contains_content_items_course_run_keys_in_catalog(self):
        """
        Verify the contains_content_items endpoint returns True if a course run's key is in the catalog
        """
        content_key = 'course-content-key'
        course_run_content_key = 'course-run-content-key'
        associated_course_metadata = ContentMetadataFactory(
            content_key=content_key,
            json_metadata={
                'key': content_key,
                'course_runs': [{
                    'key': course_run_content_key
                }],
            })
        # create content metadata for course run associated with above course
        ContentMetadataFactory(content_key=course_run_content_key,
                               parent_content_key=content_key)
        self.add_metadata_to_catalog(self.enterprise_catalog,
                                     [associated_course_metadata])

        url = self._get_contains_content_base_url(
            self.enterprise_catalog
        ) + '?course_run_ids=' + course_run_content_key
        self.assert_correct_contains_response(url, True)
Beispiel #18
0
    def setUpTestData(cls):
        super().setUpTestData()
        cls.ALGOLIA_FIELDS = [
            'key', 'objectID', 'enterprise_customer_uuids',
            'enterprise_catalog_uuids', 'enterprise_catalog_query_uuids'
        ]

        # Set up a catalog, query, and metadata for a course
        cls.enterprise_catalog_courses = EnterpriseCatalogFactory()
        courses_catalog_query = cls.enterprise_catalog_courses.catalog_query
        cls.course_metadata_published = ContentMetadataFactory(
            content_type=COURSE, content_key='fakeX')
        cls.course_metadata_published.catalog_queries.set(
            [courses_catalog_query])
        cls.course_metadata_unpublished = ContentMetadataFactory(
            content_type=COURSE, content_key='testX')
        cls.course_metadata_unpublished.json_metadata.get(
            'course_runs')[0].update({
                'status': 'unpublished',
            })
        cls.course_metadata_unpublished.catalog_queries.set(
            [courses_catalog_query])
        cls.course_metadata_unpublished.save()

        # Set up new catalog, query, and metadata for a course run
        cls.enterprise_catalog_course_runs = EnterpriseCatalogFactory()
        course_runs_catalog_query = cls.enterprise_catalog_course_runs.catalog_query
        course_run_metadata_published = ContentMetadataFactory(
            content_type=COURSE_RUN, parent_content_key='fakeX')
        course_run_metadata_published.catalog_queries.set(
            [course_runs_catalog_query])
        course_run_metadata_unpublished = ContentMetadataFactory(
            content_type=COURSE_RUN, parent_content_key='testX')
        course_run_metadata_unpublished.json_metadata.update({
            'status':
            'unpublished',
        })
        course_run_metadata_unpublished.catalog_queries.set(
            [course_runs_catalog_query])
        course_run_metadata_unpublished.save()
Beispiel #19
0
    def test_update_full_metadata(self, mock_oauth_client,
                                  mock_get_indexable_course_keys):
        """
        Assert that full course metadata is merged with original json_metadata for all ContentMetadata records.
        """
        course_key_1 = 'fakeX'
        course_data_1 = {
            'key': course_key_1,
            'full_course_only_field': 'test_1'
        }
        course_key_2 = 'testX'
        course_data_2 = {
            'key': course_key_2,
            'full_course_only_field': 'test_2'
        }
        non_course_key = 'course-runX'

        # Mock out the data that should be returned from discovery's /api/v1/courses endpoint
        mock_oauth_client.return_value.get.return_value.json.return_value = {
            'results': [course_data_1, course_data_2],
        }

        metadata_1 = ContentMetadataFactory(content_type=COURSE,
                                            content_key=course_key_1)
        metadata_1.catalog_queries.set([self.catalog_query])
        metadata_2 = ContentMetadataFactory(content_type=COURSE,
                                            content_key=course_key_2)
        metadata_2.catalog_queries.set([self.catalog_query])
        non_course_metadata = ContentMetadataFactory(
            content_type=COURSE_RUN, content_key=non_course_key)
        non_course_metadata.catalog_queries.set([self.catalog_query])

        assert metadata_1.json_metadata != course_data_1
        assert metadata_2.json_metadata != course_data_2

        mock_get_indexable_course_keys.return_value = [
            course_key_1, course_key_2
        ]
        indexable_course_keys = tasks.update_full_content_metadata_task(
            [course_key_1, course_key_2, non_course_key])
        # Verify the task returns the course keys that are indexable as those keys are passed to the
        # `index_enterprise_catalog_courses_in_algolia_task` from the `EnterpriseCatalogRefreshDataFromDiscovery` view.
        assert indexable_course_keys == mock_get_indexable_course_keys.return_value

        metadata_1 = ContentMetadata.objects.get(content_key='fakeX')
        metadata_2 = ContentMetadata.objects.get(content_key='testX')

        # add aggregation_key and uuid to course objects since they should now exist
        # after merging the original json_metadata with the course metadata
        course_data_1.update({
            'uuid':
            metadata_1.json_metadata.get('uuid'),
            'aggregation_key':
            'course:fakeX',
            'marketing_url':
            metadata_1.json_metadata.get('marketing_url'),
            'original_image':
            metadata_1.json_metadata.get('original_image'),
            'owners':
            metadata_1.json_metadata.get('owners'),
        })
        course_data_2.update({
            'uuid':
            metadata_2.json_metadata.get('uuid'),
            'aggregation_key':
            'course:testX',
            'marketing_url':
            metadata_2.json_metadata.get('marketing_url'),
            'original_image':
            metadata_2.json_metadata.get('original_image'),
            'owners':
            metadata_2.json_metadata.get('owners'),
        })

        assert metadata_1.json_metadata == course_data_1
        assert metadata_2.json_metadata == course_data_2
 def setUpTestData(cls):
     super().setUpTestData()
     cls.content_metadata = ContentMetadataFactory.create_batch(
         3, content_type=COURSE)
 def setUpTestData(cls):
     super().setUpTestData()
     ContentMetadataFactory.create_batch(3)