Skip to content

Commit

Permalink
feat: allow clients of customer content_metadata view to skip ent cus…
Browse files Browse the repository at this point in the history
…tomer fetches.

ENT-7864 | Allows clients of the EnterpriseCustomerViewSet.content_metadata
view to include an optional `skip_customer_fetch` query param.
If present and truthy, including this param will cause
the serialized content metadata to not fetch related enterprise customer
details from the edx-enterprise REST API.  Thus the presence of this
query param means that the serialized 'content_last_modified' time
will not take into account the *customer* modified time.  Additionally,
it means that no 'enrollment_url' fields will be present in the serialied
response.
  • Loading branch information
iloveagent57 committed Oct 25, 2023
1 parent 93bd52a commit e4c43c8
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
11 changes: 8 additions & 3 deletions enterprise_catalog/apps/api/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,11 @@ def to_representation(self, instance):
"""
catalog_modified = None
customer_modified = None
if enterprise_catalog := self.context.get('enterprise_catalog'):
enterprise_catalog = self.context.get('enterprise_catalog')

if enterprise_catalog:
catalog_modified = enterprise_catalog.modified
if enterprise_catalog and not self.context.get('skip_customer_fetch'):
customer_modified = enterprise_catalog.enterprise_customer.last_modified_date

content_type = instance.content_type
Expand Down Expand Up @@ -255,7 +258,9 @@ def to_representation(self, instance):

if content_type in (COURSE, COURSE_RUN):
if enterprise_catalog:
json_metadata['enrollment_url'] = enterprise_catalog.get_content_enrollment_url(instance)
json_metadata['enrollment_url'] = None
if not self.context.get('skip_customer_fetch'):
json_metadata['enrollment_url'] = enterprise_catalog.get_content_enrollment_url(instance)
json_metadata['xapi_activity_id'] = enterprise_catalog.get_xapi_activity_id(
content_resource=content_type,
content_key=content_key,
Expand All @@ -267,7 +272,7 @@ def to_representation(self, instance):
# for exec-ed-2u content, because enrollment fulfillment for such content
# is controlled via Entitlements, which are tied directly to Courses
# (as opposed to Seats, which are tied to Course Runs).
if not instance.is_exec_ed_2u_course:
if not instance.is_exec_ed_2u_course and not self.context.get('skip_customer_fetch'):
self._add_course_run_enrollment_urls(instance, serialized_course_runs)
elif content_type == PROGRAM:
# We want this to be null, because we have no notion
Expand Down
19 changes: 16 additions & 3 deletions enterprise_catalog/apps/api/v1/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2175,20 +2175,33 @@ def setUp(self):

self.addCleanup(self.customer_details_patcher.stop)

def test_content_metadata_get_item_with_content_key(self):
@ddt.data(True, False)
def test_content_metadata_get_item_with_content_key(self, skip_customer_fetch):
"""
Test the base success case for the `content-metadata` view using a content key as an identifier
"""
response = self.client.get(urljoin(self.url, f"{self.content_key_1}/"))
self.mock_customer_details.reset_mock()
query_params = ''
if skip_customer_fetch:
query_params = '?skip_customer_fetch=1'
response = self.client.get(urljoin(self.url, f"{self.content_key_1}/") + query_params)
assert response.status_code == 200
expected_data = ContentMetadataSerializer(
self.first_content_metadata,
context={'enterprise_catalog': self.enterprise_catalog},
context={
'enterprise_catalog': self.enterprise_catalog,
'skip_customer_fetch': skip_customer_fetch,
},
).data
actual_data = response.json()
for payload_key in ['key', 'uuid']:
assert actual_data[payload_key] == expected_data[payload_key]

if skip_customer_fetch:
self.assertFalse(self.mock_customer_details.called)
else:
self.assertTrue(self.mock_customer_details.called)

def test_content_metadata_get_item_with_content_key_in_multiple_catalogs(self):
"""
Test the base success case for the `content-metadata` view using a content key as an identifier
Expand Down
18 changes: 15 additions & 3 deletions enterprise_catalog/apps/api/v1/views/enterprise_customer.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ def get_metadata_item_serializer(self):
enterprise_uuid=self.kwargs.get('enterprise_uuid')
))
content_identifier = self.kwargs.get('content_identifier')
serializer_context = {
'skip_customer_fetch': bool(self.request.query_params.get('skip_customer_fetch', '').lower()),
}

try:
# Search for matching metadata if the value of the requested
Expand All @@ -164,7 +167,7 @@ def get_metadata_item_serializer(self):
if content_with_uuid:
return ContentMetadataSerializer(
content_with_uuid.first(),
context={'enterprise_catalog': catalog},
context={'enterprise_catalog': catalog, **serializer_context},
)
except ValueError:
# Otherwise, search for matching metadata as a content key
Expand All @@ -173,7 +176,7 @@ def get_metadata_item_serializer(self):
if content_with_key:
return ContentMetadataSerializer(
content_with_key.first(),
context={'enterprise_catalog': catalog},
context={'enterprise_catalog': catalog, **serializer_context},
)
# If we've made it here without finding a matching ContentMetadata record,
# assume no matching record exists and raise a 404.
Expand All @@ -183,7 +186,16 @@ def get_metadata_item_serializer(self):
def content_metadata(self, customer_uuid, content_identifier, **kwargs): # pylint: disable=unused-argument
"""
Get endpoint for `/api/v1/enterprise-customer/{customer uuid}/content-metadata/{content identifier}`.
Accepts both content uuids and content keys for the specific content metadata record requested
Accepts both content uuids and content keys for the specific content metadata record requested.
Accepts an optional `skip_customer_fetch` query parameter.
If present and truthy, including this param will cause
the serialized content metadata to not fetch related enterprise customer
details from the edx-enterprise REST API. Thus the presence of this
query param means that the serialized 'content_last_modified' time
will not take into account the *customer* modified time. Additionally,
it means that no 'enrollment_url' fields will be present in the serialied
response.
"""
serializer = self.get_metadata_item_serializer()
return Response(serializer.data)

0 comments on commit e4c43c8

Please sign in to comment.