diff --git a/openedx/core/djangoapps/content_libraries/tests/test_embed_block.py b/openedx/core/djangoapps/content_libraries/tests/test_embed_block.py
index a554e6157e..e9909b7d60 100644
--- a/openedx/core/djangoapps/content_libraries/tests/test_embed_block.py
+++ b/openedx/core/djangoapps/content_libraries/tests/test_embed_block.py
@@ -219,8 +219,8 @@ class LibrariesEmbedViewTestCase(ContentLibrariesRestApiTest, OpenEdxEventsTestM
# show up.
html = self._embed_block(block_id, version='published')
# This is the pattern we're looking for:
- #
- assert re.search(r'/library_assets/[0-9a-f-]*/static/deer.jpg', html)
+ #
+ assert re.search(r'/library_assets/component_versions/[0-9a-f-]*/static/deer.jpg', html)
# Now grab the draft version (4), which is going to once again not have
# the asset (because we deleted it).
diff --git a/openedx/core/djangoapps/content_libraries/tests/test_static_assets.py b/openedx/core/djangoapps/content_libraries/tests/test_static_assets.py
index a5f69f94b1..b903a0ca97 100644
--- a/openedx/core/djangoapps/content_libraries/tests/test_static_assets.py
+++ b/openedx/core/djangoapps/content_libraries/tests/test_static_assets.py
@@ -123,19 +123,20 @@ class ContentLibrariesComponentVersionAssetTest(ContentLibrariesRestApiTest):
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.usage_key = usage_key
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"
+ f"/library_assets/component_versions/{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"
+ f"/library_assets/component_versions/{self.draft_component_version.uuid}/static/test.svg"
)
assert good_head_response.headers == get_response.headers
@@ -144,20 +145,20 @@ class ContentLibrariesComponentVersionAssetTest(ContentLibrariesRestApiTest):
# 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"
+ f"/library_assets/component_versions/{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"
+ f"/library_assets/component_versions/{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"
+ f"/library_assets/component_versions/{self.draft_component_version.uuid}/block.xml"
)
assert response.status_code == 404
@@ -165,7 +166,7 @@ class ContentLibrariesComponentVersionAssetTest(ContentLibrariesRestApiTest):
"""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"
+ f"/library_assets/component_versions/{self.draft_component_version.uuid}/static/test.svg"
)
assert response.status_code == 403
@@ -181,6 +182,32 @@ class ContentLibrariesComponentVersionAssetTest(ContentLibrariesRestApiTest):
)
self.client.login(username="student", password="student-pass")
get_response = self.client.get(
- f"/library_assets/{self.draft_component_version.uuid}/static/test.svg"
+ f"/library_assets/component_versions/{self.draft_component_version.uuid}/static/test.svg"
)
assert get_response.status_code == 403
+
+ def test_draft_version(self):
+ """Get draft version of asset"""
+ get_response = self.client.get(
+ f"/library_assets/blocks/{self.usage_key}/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/blocks/{self.usage_key}/static/test.svg"
+ )
+ assert good_head_response.headers == get_response.headers
+
+ def test_draft_version_404(self):
+ """Get draft version of asset"""
+ get_response = self.client.get(
+ f"/library_assets/blocks/{self.usage_key}@/static/test.svg"
+ )
+ assert get_response.status_code == 404
+
+ get_response = self.client.get(
+ f"/library_assets/blocks/{self.usage_key}/static/test2.svg"
+ )
+ assert get_response.status_code == 404
diff --git a/openedx/core/djangoapps/content_libraries/urls.py b/openedx/core/djangoapps/content_libraries/urls.py
index 7806c75500..5bf36162d5 100644
--- a/openedx/core/djangoapps/content_libraries/urls.py
+++ b/openedx/core/djangoapps/content_libraries/urls.py
@@ -76,9 +76,17 @@ urlpatterns = [
path('pub/jwks/', views.LtiToolJwksView.as_view(), name='lti-pub-jwks'),
])),
])),
- path(
- 'library_assets//',
- views.component_version_asset,
- name='library-assets',
+ path('library_assets/', include([
+ path(
+ 'component_versions//',
+ views.component_version_asset,
+ name='library-assets',
+ ),
+ path(
+ 'blocks//',
+ views.component_draft_asset,
+ name='library-draft-assets',
+ ),
+ ])
),
]
diff --git a/openedx/core/djangoapps/content_libraries/views.py b/openedx/core/djangoapps/content_libraries/views.py
index 585b08535d..50b532f25b 100644
--- a/openedx/core/djangoapps/content_libraries/views.py
+++ b/openedx/core/djangoapps/content_libraries/views.py
@@ -1237,3 +1237,18 @@ def component_version_asset(request, component_version_uuid, asset_path):
content.read_file().chunks(),
headers=redirect_response.headers,
)
+
+
+@require_safe
+def component_draft_asset(request, usage_key, asset_path):
+ """
+ Serves the draft version of static assets associated with a Library Component.
+
+ See `component_version_asset` for more details
+ """
+ try:
+ component_version_uuid = api.get_component_from_usage_key(usage_key).versioning.draft.uuid
+ except ObjectDoesNotExist as exc:
+ raise Http404() from exc
+
+ return component_version_asset(request, component_version_uuid, asset_path)
diff --git a/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py b/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py
index 0942a5a8b3..1d1df738ab 100644
--- a/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py
+++ b/openedx/core/djangoapps/xblock/runtime/learning_core_runtime.py
@@ -377,7 +377,7 @@ class LearningCoreXBlockRuntime(XBlockRuntime):
then this method will be called with asset_path="test.png" and should
return a URL like:
- http://studio.local.openedx.io:8001/library_assets/cd31871e-a342-4c3f-ba2f-a661bf630996/static/test.png
+ http://studio.local.openedx.io:8001/library_assets/component_versions/cd31871e-a342-4c3f-ba2f-a661bf630996/static/test.png
If the asset file is not recognized, return None