Skip to content

Commit

Permalink
Merge pull request #731 from openedx/asheehan-edx/get-catalogs-for-co…
Browse files Browse the repository at this point in the history
…ntent

feat: adding ability to fetch all catalogs that contain a piece of content
  • Loading branch information
alex-sheehan-edx authored Jan 5, 2024
2 parents f225ab0 + 0e673eb commit 59a4fa4
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
45 changes: 45 additions & 0 deletions enterprise_catalog/apps/api_client/algolia.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,48 @@ def replace_all_objects(self, algolia_objects): # pragma: no cover
self.ALGOLIA_INDEX_NAME,
)
raise exc

def get_all_objects_associated_with_aggregation_key(self, aggregation_key):
"""
Returns an array of Algolia object IDs associated with the given aggregation key.
"""
objects = []
if not self.index_exists():
# index must exist to continue, nothing left to do
return objects
try:
index_browse_iterator = self.algolia_index.browse_objects({
"attributesToRetrieve": ["objectID"],
"filters": f"aggregation_key:'{aggregation_key}'",
})
for hit in index_browse_iterator:
objects.append(hit['objectID'])
except AlgoliaException as exc:
logger.exception(
'Could not retrieve objects associated with aggregation key %s due to an exception.',
aggregation_key,
)
raise exc
return objects

def remove_objects(self, object_ids):
"""
Removes objects from the Algolia index.
"""
if not self.index_exists():
# index must exist to continue, nothing left to do
return

try:
self.algolia_index.delete_objects(object_ids)
logger.info(
'The following objects were successfully removed from the %s Algolia index: %s',
self.ALGOLIA_INDEX_NAME,
object_ids,
)
except AlgoliaException as exc:
logger.exception(
'Could not remove objects from the %s Algolia index due to an exception.',
self.ALGOLIA_INDEX_NAME,
)
raise exc
26 changes: 26 additions & 0 deletions enterprise_catalog/apps/catalog/algolia_content_indexing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from enterprise_catalog.apps.catalog.filters import does_query_match_content
from enterprise_catalog.apps.catalog.models import (
ContentMetadata,
EnterpriseCatalog,
)


def get_catalogs_for_content(course_key, catalog_filter=None):
"""
Retrieve all catalogs that contain the given course_key.
Arguments:
course_key (str): Course key to lookup the content metadata object for comparison against the catalog query
filters
catalog_filter (dict): Optional filter to apply to the catalogs queryset
"""
content_object = ContentMetadata.objects.get(content_key=course_key)
if catalog_filter is None:
catalog_filter = {}
included_catalogs = []
for catalog in EnterpriseCatalog.objects.filter(**catalog_filter):
if does_query_match_content(catalog.catalog_query.content_filter, content_object.json_metadata):
included_catalogs.append(catalog)

return included_catalogs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
""" Tests for catalog query filtering. """
import logging

import ddt
from django.test import TestCase

from enterprise_catalog.apps.catalog.algolia_content_indexing import (
get_catalogs_for_content,
)
from enterprise_catalog.apps.catalog.tests.factories import (
CatalogQueryFactory,
ContentMetadataFactory,
EnterpriseCatalogFactory,
)


logger = logging.getLogger(__name__)


@ddt.ddt
class AlgoliaContentIndexingTests(TestCase):
""" Tests for catalog query filtering. """

def test_does_content_belong_in_catalog(self):
""" Test that `get_catalogs_for_content_metadata` matches content to correct catalog. """
content_metadata = ContentMetadataFactory(content_type='course')
content_key = content_metadata.json_metadata.get('key')
status = content_metadata.json_metadata.get('status')

included_query = CatalogQueryFactory(
content_filter={'content_type': 'course', 'status': status, 'key': content_key}
)
excluded_query = CatalogQueryFactory(
content_filter={'content_type': 'course', 'status': status, 'key__exclude': [content_key]}
)
included_catalog = EnterpriseCatalogFactory(
catalog_query=included_query
)
EnterpriseCatalogFactory(
catalog_query=excluded_query
)
found_catalogs = get_catalogs_for_content(content_key)
assert len(found_catalogs) == 1
assert found_catalogs[0] == included_catalog

0 comments on commit 59a4fa4

Please sign in to comment.