|
3 | 3 | """ |
4 | 4 | import json |
5 | 5 | from datetime import datetime, timezone |
6 | | -from unittest.mock import patch |
| 6 | +from unittest.mock import patch, MagicMock |
7 | 7 |
|
8 | 8 | from django.conf import settings |
| 9 | +from django.urls import reverse |
9 | 10 | from freezegun import freeze_time |
10 | 11 | from organizations.models import Organization |
11 | 12 |
|
12 | 13 | from cms.djangoapps.contentstore.helpers import StaticFileNotices |
13 | 14 | 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 |
14 | 17 | from common.djangoapps.student.tests.factories import UserFactory |
15 | 18 | from xmodule.modulestore.django import modulestore |
16 | 19 | from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase |
@@ -329,6 +332,60 @@ def test_400_no_upstream(self): |
329 | 332 | assert "is not linked" in response.data["developer_message"][0] |
330 | 333 |
|
331 | 334 |
|
| 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 | + |
332 | 389 | class PostDownstreamSyncViewTest(_DownstreamSyncViewTestMixin, SharedModuleStoreTestCase): |
333 | 390 | """ |
334 | 391 | Test that `POST /api/v2/contentstore/downstreams/.../sync` initiates a sync from the linked upstream. |
|
0 commit comments