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) }
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
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)
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 ]
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)
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])
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)
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)
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)}
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 == []
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)
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()
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)