Skip to content

Commit

Permalink
test: add some tests around the library asset view
Browse files Browse the repository at this point in the history
  • Loading branch information
ormsbee committed Oct 13, 2024
1 parent ad808f1 commit b173150
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 16 deletions.
5 changes: 5 additions & 0 deletions openedx/core/djangoapps/content_libraries/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,11 @@ def add_library_block_static_asset_file(usage_key, file_path, file_content, user
component = get_component_from_usage_key(usage_key)

media_type_str, _encoding = mimetypes.guess_type(file_path)
# We use "application/octet-stream" as a generic fallback media type, per
# RFC 2046: https://datatracker.ietf.org/doc/html/rfc2046
# TODO: This probably makes sense to push down to openedx-learning?
media_type_str = media_type_str or "application/octet-stream"

now = datetime.now(tz=timezone.utc)

with transaction.atomic():
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
"""
Tests for static asset files in Learning-Core-based Content Libraries
"""
from uuid import UUID
from unittest import skip

from opaque_keys.edx.keys import UsageKey

from openedx.core.djangoapps.content_libraries.tests.base import (
ContentLibrariesRestApiTest,
)
from openedx.core.djangoapps.xblock.api import get_component_from_usage_key
from openedx.core.djangolib.testing.utils import skip_unless_cms

# Binary data representing an SVG image file
SVG_DATA = """<svg xmlns="http://www.w3.org/2000/svg" height="30" width="100">
Expand All @@ -22,7 +27,7 @@
I'm Anant Agarwal, I'm the president of edX,
"""


@skip_unless_cms
class ContentLibrariesStaticAssetsTest(ContentLibrariesRestApiTest):
"""
Tests for static asset files in Learning-Core-based Content Libraries
Expand Down Expand Up @@ -102,3 +107,66 @@ def check_download():
self._commit_library_changes(library["id"])
check_sjson()
check_download()


@skip_unless_cms
class ContentLibrariesComponentVersionAssetTest(ContentLibrariesRestApiTest):
"""
Tests for the view that actually delivers the Library asset in Studio.
"""

def setUp(self):
super().setUp()

library = self._create_library(slug="asset-lib2", title="Static Assets Test Library")
block = self._add_block_to_library(library["id"], "html", "html1")
self._set_library_block_asset(block["id"], "static/test.svg", SVG_DATA)
usage_key = UsageKey.from_string(block["id"])
self.component = get_component_from_usage_key(usage_key)
self.draft_component_version = self.component.versioning.draft


def test_good_responses(self):
get_response = self.client.get(
f"/library_assets/{self.draft_component_version.uuid}/static/test.svg"
)
assert get_response.status_code == 200
content = b''.join(chunk for chunk in get_response.streaming_content)
assert content == SVG_DATA

good_head_response = self.client.head(
f"/library_assets/{self.draft_component_version.uuid}/static/test.svg"
)
assert good_head_response.headers == get_response.headers


def test_missing(self):
"""Test asset requests that should 404."""
# Non-existent version...
wrong_version_uuid = UUID('11111111-1111-1111-1111-111111111111')
response = self.client.get(
f"/library_assets/{wrong_version_uuid}/static/test.svg"
)
assert response.status_code == 404

# Non-existent file...
response = self.client.get(
f"/library_assets/{self.draft_component_version.uuid}/static/missing.svg"
)
assert response.status_code == 404

# File-like ComponenVersionContent entry that isn't an actually
# downloadable file...
response = self.client.get(
f"/library_assets/{self.draft_component_version.uuid}/block.xml"
)
assert response.status_code == 404


def test_anonymous_user(self):
"""Anonymous users shouldn't get access to library assets."""
self.client.logout()
response = self.client.get(
f"/library_assets/{self.draft_component_version.uuid}/static/test.svg"
)
assert response.status_code == 403
42 changes: 27 additions & 15 deletions xmodule/video_block/transcripts_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import requests
import simplejson as json
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from lxml import etree
from opaque_keys.edx.keys import UsageKeyV2
from openedx_learning.api import authoring
Expand Down Expand Up @@ -1098,27 +1099,34 @@ def get_transcript_from_learning_core(video_block, language, output_format, tran
component_version = component.versioning.draft
if not component_version:
raise NotFoundError(
f"No transcript for {usage_key}: Component {component.uuid} was soft-deleted."
f"No transcript for {usage_key} because Component {component.uuid} "
"was soft-deleted."
)

file_path = pathlib.Path(f"static/{transcripts[language]}")
if file_path.suffix != '.srt':
# We want to standardize on .srt
raise NotFoundError("Video XBlocks in Content Libraries only support .srt transcript files.")
raise NotFoundError(
"Video XBlocks in Content Libraries only support storing .srt "
f"transcript files, but we tried to look up {path_file} for {usage_key}"
)

# TODO: There should be a Learning Core API call for this:
print(
[(cvc.key, cvc.content.has_file) for cvc in component_version.componentversioncontent_set.all()]
)
content = (
component_version
.componentversioncontent_set
.filter(content__has_file=True)
.select_related('content')
.get(key=file_path)
.content
)
data = content.read_file().read()
try:
content = (
component_version
.componentversioncontent_set
.filter(content__has_file=True)
.select_related('content')
.get(key=file_path)
.content
)
data = content.read_file().read()
except ObjectDoesNotExist:
raise NotFoundError(
f"No file {file_path} found for {usage_key} "
f"(ComponentVersion {component_version.uuid})"
)

# Now convert the transcript data to the requested format:
output_filename = f'{file_path.stem}.{output_format}'
Expand All @@ -1128,7 +1136,11 @@ def get_transcript_from_learning_core(video_block, language, output_format, tran
output_format=output_format,
)
if not output_transcript.strip():
raise NotFoundError('No transcript content')
raise NotFoundError(
f"Transcript file {file_path} found for {usage_key} "
f"(ComponentVersion {component_version.uuid}), but it has no "
"content or is malformed."
)

return output_transcript, output_filename, Transcript.mime_types[output_format]

Expand Down

0 comments on commit b173150

Please sign in to comment.