Skip to content

Commit 650ebb5

Browse files
ChrisChVUsamaSadiq
authored andcommitted
fix: Transcripts in downstream creation [FC-0076] (#36509)
* Fix the issue described in openedx/frontend-app-authoring#1352 (comment)
1 parent 2284dc8 commit 650ebb5

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

cms/djangoapps/contentstore/helpers.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ def _insert_static_files_into_downstream_xblock(
298298
static_files=static_files,
299299
usage_key=downstream_xblock.usage_key,
300300
)
301+
# FIXME: This code shouldn't have any special cases for specific block types like video
302+
# in the future.
301303
if downstream_xblock.usage_key.block_type == 'video':
302304
_import_transcripts(
303305
downstream_xblock,
@@ -390,6 +392,14 @@ def import_static_assets_for_library_sync(downstream_xblock: XBlock, lib_block:
390392
store = modulestore()
391393
try:
392394
with store.bulk_operations(downstream_xblock.context_key):
395+
# FIXME: This code shouldn't have any special cases for specific block types like video
396+
# in the future.
397+
if downstream_xblock.usage_key.block_type == 'video' and not downstream_xblock.edx_video_id:
398+
# If the `downstream_xblock` is a new created block, we need to create
399+
# a new `edx_video_id` to import the transcripts.
400+
downstream_xblock.edx_video_id = create_external_video(display_name='external video')
401+
store.update_item(downstream_xblock, request.user.id)
402+
393403
# Now handle static files that need to go into Files & Uploads.
394404
# If the required files already exist, nothing will happen besides updating the olx.
395405
notices = _insert_static_files_into_downstream_xblock(downstream_xblock, staged_content.id, request)

cms/djangoapps/contentstore/rest_api/v2/views/tests/test_downstreams.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@
33
"""
44
import json
55
from datetime import datetime, timezone
6-
from unittest.mock import patch
6+
from unittest.mock import patch, MagicMock
77

88
from django.conf import settings
9+
from django.urls import reverse
910
from freezegun import freeze_time
1011
from organizations.models import Organization
1112

1213
from cms.djangoapps.contentstore.helpers import StaticFileNotices
1314
from cms.lib.xblock.upstream_sync import BadUpstream, UpstreamLink
15+
from cms.djangoapps.contentstore.tests.utils import CourseTestCase
16+
from opaque_keys.edx.keys import UsageKey
1417
from common.djangoapps.student.tests.factories import UserFactory
1518
from xmodule.modulestore.django import modulestore
1619
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
@@ -329,6 +332,60 @@ def test_400_no_upstream(self):
329332
assert "is not linked" in response.data["developer_message"][0]
330333

331334

335+
class CreateDownstreamViewTest(CourseTestCase, _BaseDownstreamViewTestMixin, SharedModuleStoreTestCase):
336+
"""
337+
Tests create new downstream blocks
338+
"""
339+
def call_api_post(self, library_content_key, category):
340+
"""
341+
Call the api to create a downstream block using
342+
`library_content_key` as upstream
343+
"""
344+
data = {
345+
"parent_locator": str(self.course.location),
346+
"display_name": "Test block",
347+
"library_content_key": library_content_key,
348+
"category": category,
349+
}
350+
return self.client.post(
351+
reverse("xblock_handler"),
352+
data=json.dumps(data),
353+
content_type="application/json",
354+
)
355+
356+
def test_200(self):
357+
response = self.call_api_post(self.html_lib_id, "html")
358+
359+
assert response.status_code == 200
360+
data = response.json()
361+
assert data["upstreamRef"] == self.html_lib_id
362+
363+
usage_key = UsageKey.from_string(data["locator"])
364+
item = modulestore().get_item(usage_key)
365+
assert item.upstream == self.html_lib_id
366+
367+
@patch("cms.djangoapps.contentstore.helpers._insert_static_files_into_downstream_xblock")
368+
@patch("cms.djangoapps.contentstore.helpers.content_staging_api.stage_xblock_temporarily")
369+
@patch("cms.djangoapps.contentstore.xblock_storage_handlers.view_handlers.sync_from_upstream")
370+
def test_200_video(self, mock_sync, mock_stage, mock_insert):
371+
mock_lib_block = MagicMock()
372+
mock_lib_block.runtime.get_block_assets.return_value = ['mocked_asset']
373+
mock_sync.return_value = mock_lib_block
374+
mock_stage.return_value = MagicMock()
375+
mock_insert.return_value = StaticFileNotices()
376+
377+
response = self.call_api_post(self.video_lib_id, "video")
378+
379+
assert response.status_code == 200
380+
data = response.json()
381+
assert data["upstreamRef"] == self.video_lib_id
382+
383+
usage_key = UsageKey.from_string(data["locator"])
384+
item = modulestore().get_item(usage_key)
385+
assert item.upstream == self.video_lib_id
386+
assert item.edx_video_id is not None
387+
388+
332389
class PostDownstreamSyncViewTest(_DownstreamSyncViewTestMixin, SharedModuleStoreTestCase):
333390
"""
334391
Test that `POST /api/v2/contentstore/downstreams/.../sync` initiates a sync from the linked upstream.

0 commit comments

Comments
 (0)