diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py
index ca5ea3e95424..94194502be38 100644
--- a/cms/djangoapps/contentstore/tests/test_contentstore.py
+++ b/cms/djangoapps/contentstore/tests/test_contentstore.py
@@ -2,6 +2,7 @@
import copy
+import re
import shutil
from datetime import timedelta
from functools import wraps
@@ -34,6 +35,8 @@
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.modulestore.inheritance import own_metadata
+from xmodule.modulestore.split_mongo import BlockKey
+from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls
from xmodule.modulestore.xml_exporter import export_course_to_xml
from xmodule.modulestore.xml_importer import import_course_from_xml, perform_xlint
@@ -83,6 +86,7 @@ class ContentStoreTestCase(CourseTestCase):
"""
Base class for Content Store Test Cases
"""
+ MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
class ImportRequiredTestCases(ContentStoreTestCase):
@@ -212,7 +216,7 @@ def test_asset_import(self):
all_thumbnails = content_store.get_all_content_thumbnails_for_course(course.id)
self.assertGreater(len(all_thumbnails), 0)
- location = AssetKey.from_string('/c4x/edX/toy/asset/just_a_test.jpg')
+ location = AssetKey.from_string('asset-v1:edX+toy+2012_Fall+type@asset+block@just_a_test.jpg')
content = content_store.find(location)
self.assertIsNotNone(content)
@@ -282,7 +286,7 @@ def test_rewrite_nonportable_links_on_import(self):
)
# first check a static asset link
- course_key = self.store.make_course_key('edX', 'toy', 'run')
+ course_key = self.store.make_course_key('edX', 'toy', '2012_Fall')
html_block_location = course_key.make_usage_key('html', 'nonportable')
html_block = self.store.get_item(html_block_location)
self.assertIn('/static/foo.jpg', html_block.data)
@@ -302,101 +306,6 @@ def verify_content_existence(self, store, root_dir, course_id, dirname, category
filesystem = OSFS(root_dir / ('test_export/' + dirname))
self.assertTrue(filesystem.exists(item.location.block_id + filename_suffix))
- @mock.patch('xmodule.course_block.requests.get')
- def test_export_course_roundtrip(self, mock_get):
- mock_get.return_value.text = dedent("""
-
-
-
- """).strip()
-
- content_store = contentstore()
- course_id = self.import_and_populate_course()
-
- root_dir = path(mkdtemp_clean())
- print(f'Exporting to tempdir = {root_dir}')
-
- # export out to a tempdir
- export_course_to_xml(self.store, content_store, course_id, root_dir, 'test_export')
-
- # check for static tabs
- self.verify_content_existence(self.store, root_dir, course_id, 'tabs', 'static_tab', '.html')
-
- # check for about content
- self.verify_content_existence(self.store, root_dir, course_id, 'about', 'about', '.html')
-
- # assert that there is an html and video directory in drafts:
- draft_dir = OSFS(root_dir / 'test_export/drafts')
- self.assertTrue(draft_dir.exists('html'))
- self.assertTrue(draft_dir.exists('video'))
- # and assert that they contain the created modules
- self.assertIn(self.DRAFT_HTML + ".xml", draft_dir.listdir('html'))
- self.assertIn(self.DRAFT_VIDEO + ".xml", draft_dir.listdir('video'))
- # and assert the child of the orphaned draft wasn't exported
- self.assertNotIn(self.ORPHAN_DRAFT_HTML + ".xml", draft_dir.listdir('html'))
-
- # check for grading_policy.json
- filesystem = OSFS(root_dir / 'test_export/policies/2012_Fall')
- self.assertTrue(filesystem.exists('grading_policy.json'))
-
- course = self.store.get_course(course_id)
- # compare what's on disk compared to what we have in our course
- with filesystem.open('grading_policy.json', 'r') as grading_policy:
- on_disk = loads(grading_policy.read())
- self.assertEqual(on_disk, course.grading_policy)
-
- # check for policy.json
- self.assertTrue(filesystem.exists('policy.json'))
-
- # compare what's on disk to what we have in the course block
- with filesystem.open('policy.json', 'r') as course_policy:
- on_disk = loads(course_policy.read())
- self.assertIn('course/2012_Fall', on_disk)
- self.assertEqual(on_disk['course/2012_Fall'], own_metadata(course))
-
- # remove old course
- self.store.delete_course(course_id, self.user.id)
-
- # reimport over old course
- self.check_import(root_dir, content_store, course_id)
-
- # import to different course id
- new_course_id = self.store.make_course_key('anotherX', 'anotherToy', 'Someday')
- self.check_import(root_dir, content_store, new_course_id)
- self.assertCoursesEqual(course_id, new_course_id)
-
- shutil.rmtree(root_dir)
-
- def check_import(self, root_dir, content_store, course_id):
- """Imports the course in root_dir into the given course_id and verifies its content"""
- # reimport
- import_course_from_xml(
- self.store,
- self.user.id,
- root_dir,
- ['test_export'],
- static_content_store=content_store,
- target_id=course_id,
- )
-
- # verify content of the course
- self.check_populated_course(course_id)
-
- # verify additional export attributes
- def verify_export_attrs_removed(attributes):
- """Verifies all temporary attributes added during export are removed"""
- self.assertNotIn('index_in_children_list', attributes)
- self.assertNotIn('parent_sequential_url', attributes)
- self.assertNotIn('parent_url', attributes)
-
- vertical = self.store.get_item(course_id.make_usage_key('vertical', self.TEST_VERTICAL))
- verify_export_attrs_removed(vertical.xml_attributes)
-
- for child in vertical.get_children():
- verify_export_attrs_removed(child.xml_attributes)
- if hasattr(child, 'data'):
- verify_export_attrs_removed(child.data)
-
def test_export_course_with_metadata_only_video(self):
content_store = contentstore()
@@ -552,7 +461,8 @@ def test_export_course_without_content_store(self):
import_course_from_xml(
self.store, self.user.id, root_dir, ['test_export_no_content_store'],
static_content_store=None,
- target_id=course_id
+ target_id=course_id,
+ create_if_not_present=True
)
# Verify reimported course
@@ -560,7 +470,6 @@ def test_export_course_without_content_store(self):
items = self.store.get_items(
course_id,
qualifiers={
- 'category': 'sequential',
'name': 'vertical_sequential',
}
)
@@ -734,7 +643,7 @@ def test_export_with_orphan_vertical(self):
information but the draft child xblock has parent information.
"""
# Make an existing unit a draft
- self.store.convert_to_draft(self.problem.location, self.user.id)
+ self.problem = self.store.unpublish(self.problem.location, self.user.id)
root_dir = path(mkdtemp_clean())
export_course_to_xml(self.store, None, self.course.id, root_dir, 'test_export')
@@ -786,19 +695,12 @@ def test_assets_overwrite(self):
def test_advanced_components_require_two_clicks(self):
self.check_components_on_page(['word_cloud'], ['Word cloud'])
- def test_malformed_edit_unit_request(self):
- # just pick one vertical
- usage_key = self.course.id.make_usage_key('vertical', None)
-
- resp = self.client.get_html(get_url('container_handler', usage_key))
- self.assertEqual(resp.status_code, 400)
-
def test_edit_unit(self):
"""Verifies rendering the editor in all the verticals in the given test course"""
self._check_verticals([self.vert_loc])
def _get_draft_counts(self, item): # lint-amnesty, pylint: disable=missing-function-docstring
- cnt = 1 if getattr(item, 'is_draft', False) else 0
+ cnt = 1 if not self.store.has_published_version(item) else 0
for child in item.get_children():
cnt = cnt + self._get_draft_counts(child)
@@ -810,15 +712,14 @@ def test_get_items(self):
Unfortunately, None = published for the revision field, so get_items() would return
both draft and non-draft copies.
"""
- self.store.convert_to_draft(self.problem.location, self.user.id)
+ self.problem = self.store.unpublish(self.problem.location, self.user.id)
# Query get_items() and find the html item. This should just return back a single item (not 2).
direct_store_items = self.store.get_items(
self.course.id, revision=ModuleStoreEnum.RevisionOption.published_only
)
items_from_direct_store = [item for item in direct_store_items if item.location == self.problem.location]
- self.assertEqual(len(items_from_direct_store), 1)
- self.assertFalse(getattr(items_from_direct_store[0], 'is_draft', False))
+ self.assertEqual(len(items_from_direct_store), 0)
# Fetch from the draft store.
draft_store_items = self.store.get_items(
@@ -826,8 +727,6 @@ def test_get_items(self):
)
items_from_draft_store = [item for item in draft_store_items if item.location == self.problem.location]
self.assertEqual(len(items_from_draft_store), 1)
- # TODO the below won't work for split mongo
- self.assertTrue(getattr(items_from_draft_store[0], 'is_draft', False))
def test_draft_metadata(self):
"""
@@ -899,11 +798,11 @@ def test_get_depth_with_drafts(self):
self.assertEqual(num_drafts, 0)
# put into draft
- self.store.convert_to_draft(self.problem.location, self.user.id)
+ self.problem = self.store.unpublish(self.problem.location, self.user.id)
# make sure we can query that item and verify that it is a draft
draft_problem = self.store.get_item(self.problem.location)
- self.assertTrue(getattr(draft_problem, 'is_draft', False))
+ self.assertEqual(self.store.has_published_version(draft_problem), False)
# now requery with depth
course = self.store.get_course(self.course.id, depth=None)
@@ -1025,15 +924,9 @@ def test_empty_trashcan(self):
self.assertEqual(count, 0)
def test_illegal_draft_crud_ops(self):
- # this test presumes old mongo and split_draft not full split
- with self.assertRaises(InvalidVersionError):
- self.store.convert_to_draft(self.chapter_loc, self.user.id)
-
chapter = self.store.get_item(self.chapter_loc)
chapter.data = 'chapter data'
self.store.update_item(chapter, self.user.id)
- newobject = self.store.get_item(self.chapter_loc)
- self.assertFalse(getattr(newobject, 'is_draft', False))
with self.assertRaises(InvalidVersionError):
self.store.unpublish(self.chapter_loc, self.user.id)
@@ -1043,17 +936,11 @@ def test_bad_contentstore_request(self):
Test that user get proper responses for urls with invalid url or
asset/course key
"""
- resp = self.client.get_html('/c4x/CDX/123123/asset/&invalid.png')
- self.assertEqual(resp.status_code, 400)
-
- resp = self.client.get_html('/c4x/CDX/123123/asset/invalid.png')
+ resp = self.client.get_html('asset-v1:CDX+123123+2012_Fall+type@asset+block@&invalid.png')
self.assertEqual(resp.status_code, 404)
- # Now test that 404 response is returned when user tries to access
- # asset of some invalid course from split ModuleStore
- with self.store.default_store(ModuleStoreEnum.Type.split):
- resp = self.client.get_html('/c4x/InvalidOrg/InvalidCourse/asset/invalid.png')
- self.assertEqual(resp.status_code, 404)
+ resp = self.client.get_html('asset-v1:CDX+123123+2012_Fall+type@asset+block@invalid.png')
+ self.assertEqual(resp.status_code, 404)
@override_waffle_switch(waffle.ENABLE_ACCESSIBILITY_POLICY_PAGE, active=False)
def test_disabled_accessibility_page(self):
@@ -1078,20 +965,21 @@ def test_delete_course(self):
self.assertGreater(len(assets), 0)
self.assertGreater(count, 0)
- self.store.convert_to_draft(self.vert_loc, self.user.id)
+ self.store.unpublish(self.vert_loc, self.user.id)
# delete the course
self.store.delete_course(self.course.id, self.user.id)
# assert that there's absolutely no non-draft modules in the course
# this should also include all draft items
- items = self.store.get_items(self.course.id)
- self.assertEqual(len(items), 0)
+ with self.assertRaises(ItemNotFoundError):
+ self.store.get_items(self.course.id)
- # assert that all content in the asset library is also deleted
+ # assert that all content in the asset library is keeped
+ # in case the course is later restored.
assets, count = contentstore().get_all_content_for_course(self.course.id)
- self.assertEqual(len(assets), 0)
- self.assertEqual(count, 0)
+ self.assertGreater(len(assets), 0)
+ self.assertGreater(count, 0)
def test_course_handouts_rewrites(self):
"""
@@ -1111,7 +999,8 @@ def test_course_handouts_rewrites(self):
# check that /static/ has been converted to the full path
# note, we know the link it should be because that's what in the 'toy' course in the test data
asset_key = self.course.id.make_asset_key('asset', 'handouts_sample_handout.txt')
- self.assertContains(resp, str(asset_key))
+ asset_url = '/'.join(str(asset_key).rsplit('@', 1))
+ self.assertContains(resp, asset_url)
def test_prefetch_children(self):
# make sure we haven't done too many round trips to DB:
@@ -1121,19 +1010,19 @@ def test_prefetch_children(self):
# so we don't need to make an extra query to compute it.
# set the branch to 'publish' in order to prevent extra lookups of draft versions
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only, self.course.id):
- with check_mongo_calls(4):
- course = self.store.get_course(self.course.id, depth=2)
+ with check_mongo_calls(2):
+ course = self.store.get_course(self.course.id, depth=2, lazy=False)
# make sure we pre-fetched a known sequential which should be at depth=2
- self.assertIn(self.seq_loc, course.system.module_data)
+ self.assertIn(BlockKey.from_usage_key(self.seq_loc), course.system.module_data)
# make sure we don't have a specific vertical which should be at depth=3
- self.assertNotIn(self.vert_loc, course.system.module_data)
+ self.assertNotIn(BlockKey.from_usage_key(self.vert_loc), course.system.module_data)
# Now, test with the branch set to draft. No extra round trips b/c it doesn't go deep enough to get
# beyond direct only categories
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred, self.course.id):
- with check_mongo_calls(4):
+ with check_mongo_calls(2):
self.store.get_course(self.course.id, depth=2)
def _check_verticals(self, locations):
@@ -1205,21 +1094,19 @@ def test_create_course_with_dots(self):
self.course_data['run'] = 'run.name'
self.assert_created_course()
- @ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo)
- def test_course_with_different_cases(self, default_store):
+ def test_course_with_different_cases(self):
"""
Tests that course can not be created with different case using an AJAX request to
course handler.
"""
course_number = '99x'
- with self.store.default_store(default_store):
- # Verify create a course passes with lower case.
- self.course_data['number'] = course_number.lower()
- self.assert_created_course()
+ # Verify create a course passes with lower case.
+ self.course_data['number'] = course_number.lower()
+ self.assert_created_course()
- # Verify create a course fail when same course number is provided with different case.
- self.course_data['number'] = course_number.upper()
- self.assert_course_creation_failed(self.duplicate_course_error)
+ # Verify create a course fail when same course number is provided with different case.
+ self.course_data['number'] = course_number.upper()
+ self.assert_course_creation_failed(self.duplicate_course_error)
def test_create_course_check_forum_seeding(self):
"""Test new course creation and verify forum seeding """
@@ -1356,38 +1243,35 @@ def test_create_course_duplicate_number(self):
self.course_data['display_name'] = 'Robot Super Course Two'
self.course_data['run'] = '2013_Summer'
- self.assert_course_creation_failed(self.duplicate_course_error)
+ self.assert_created_course()
- @ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo)
- def test_create_course_case_change(self, default_store):
+ def test_create_course_case_change(self):
"""Test new course creation - error path due to case insensitive name equality"""
self.course_data['number'] = '99x'
- with self.store.default_store(default_store):
-
- # Verify that the course was created properly.
- self.assert_created_course()
+ # Verify that the course was created properly.
+ self.assert_created_course()
- # Keep the copy of original org
- cache_current = self.course_data['org']
+ # Keep the copy of original org
+ cache_current = self.course_data['org']
- # Change `org` to lower case and verify that course did not get created
- self.course_data['org'] = self.course_data['org'].lower()
- self.assert_course_creation_failed(self.duplicate_course_error)
+ # Change `org` to lower case and verify that course did not get created
+ self.course_data['org'] = self.course_data['org'].lower()
+ self.assert_course_creation_failed(self.duplicate_course_error)
- # Replace the org with its actual value, and keep the copy of course number.
- self.course_data['org'] = cache_current
- cache_current = self.course_data['number']
+ # Replace the org with its actual value, and keep the copy of course number.
+ self.course_data['org'] = cache_current
+ cache_current = self.course_data['number']
- self.course_data['number'] = self.course_data['number'].upper()
- self.assert_course_creation_failed(self.duplicate_course_error)
+ self.course_data['number'] = self.course_data['number'].upper()
+ self.assert_course_creation_failed(self.duplicate_course_error)
- # Replace the org with its actual value, and keep the copy of course number.
- self.course_data['number'] = cache_current
- __ = self.course_data['run']
+ # Replace the org with its actual value, and keep the copy of course number.
+ self.course_data['number'] = cache_current
+ __ = self.course_data['run']
- self.course_data['run'] = self.course_data['run'].upper()
- self.assert_course_creation_failed(self.duplicate_course_error)
+ self.course_data['run'] = self.course_data['run'].upper()
+ self.assert_course_creation_failed(self.duplicate_course_error)
def test_course_substring(self):
"""
@@ -1515,7 +1399,9 @@ def test_create_item(self):
self.assertEqual(resp.status_code, 200)
data = parse_json(resp)
- retarget = str(course.id.make_usage_key('chapter', 'REPLACE')).replace('REPLACE', r'([0-9]|[a-f]){3,}')
+ retarget = re.escape(
+ str(course.id.make_usage_key('chapter', 'REPLACE'))
+ ).replace('REPLACE', r'([0-9]|[a-f]){3,}')
self.assertRegex(data['locator'], retarget)
def test_capa_block(self):
@@ -1625,7 +1511,7 @@ def test_import_into_new_course_id(self):
self.assertEqual(course_block.pdf_textbooks[0]["chapters"][1]["url"], '/static/Chapter2.pdf')
def test_import_into_new_course_id_wiki_slug_renamespacing(self):
- # If reimporting into the same course do not change the wiki_slug.
+ # If reimporting into the same course change the wiki_slug.
target_id = self.store.make_course_key('edX', 'toy', '2012_Fall')
course_data = {
'org': target_id.org,
@@ -1641,7 +1527,7 @@ def test_import_into_new_course_id_wiki_slug_renamespacing(self):
# Import a course with wiki_slug == location.course
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['toy'], target_id=target_id)
course_block = self.store.get_course(target_id)
- self.assertEqual(course_block.wiki_slug, 'toy')
+ self.assertEqual(course_block.wiki_slug, 'edX.toy.2012_Fall')
# But change the wiki_slug if it is a different course.
target_id = self.store.make_course_key('MITx', '111', '2013_Spring')
@@ -1667,7 +1553,7 @@ def test_import_metadata_with_attempts_empty_string(self):
import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['simple'], create_if_not_present=True)
did_load_item = False
try:
- course_key = self.store.make_course_key('edX', 'simple', 'problem')
+ course_key = self.store.make_course_key('edX', 'simple', '2012_Fall')
usage_key = course_key.make_usage_key('problem', 'ps01-simple')
self.store.get_item(usage_key)
did_load_item = True
@@ -1677,13 +1563,12 @@ def test_import_metadata_with_attempts_empty_string(self):
# make sure we found the item (e.g. it didn't error while loading)
self.assertTrue(did_load_item)
- @ddt.data(ModuleStoreEnum.Type.split, ModuleStoreEnum.Type.mongo)
- def test_forum_id_generation(self, default_store):
+ def test_forum_id_generation(self):
"""
Test that a discussion item, even if it doesn't set its discussion_id,
consistently generates the same one
"""
- course = CourseFactory.create(default_store=default_store)
+ course = CourseFactory.create()
# create a discussion item
discussion_item = self.store.create_item(self.user.id, course.id, 'discussion', 'new_component')
@@ -1825,9 +1710,11 @@ def setUp(self):
"""
+ video_data = VideoBlock.parse_video_xml(video_sample_xml)
+ video_data.pop('source')
self.video_descriptor = ItemFactory.create(
parent_location=course.location, category='video',
- **VideoBlock.parse_video_xml(video_sample_xml)
+ **video_data
)
def test_metadata_not_persistence(self):
@@ -1891,10 +1778,6 @@ def post_rerun_request(
rerun_course_data.update(destination_course_data)
destination_course_key = _get_course_id(self.store, destination_course_data)
- # course_handler raise 404 for old mongo course
- if destination_course_key.deprecated:
- raise SkipTest('OldMongo Deprecation')
-
# post the request
course_url = get_url('course_handler', destination_course_key, 'course_key_string')
response = self.client.ajax_post(course_url, rerun_course_data)
@@ -2154,7 +2037,7 @@ def test_course_license_export(self):
self.course.license = "creative-commons: BY SA"
self.store.update_item(self.course, None)
export_course_to_xml(self.store, content_store, self.course.id, root_dir, 'test_license')
- fname = f"{self.course.scope_ids.usage_id.block_id}.xml"
+ fname = f"{self.course.id.run}.xml"
run_file_path = root_dir / "test_license" / "course" / fname
with run_file_path.open() as f:
run_xml = etree.parse(f)
@@ -2221,10 +2104,6 @@ def _create_course(test, course_key, course_data):
"""
Creates a course via an AJAX request and verifies the URL returned in the response.
"""
- # course_handler raise 404 for old mongo course
- if course_key.deprecated:
- raise SkipTest('OldMongo Deprecation')
-
course_url = get_url('course_handler', course_key, 'course_key_string')
response = test.client.ajax_post(course_url, course_data)
test.assertEqual(response.status_code, 200)
diff --git a/cms/djangoapps/contentstore/tests/test_users_default_role.py b/cms/djangoapps/contentstore/tests/test_users_default_role.py
index 82bd4e960b9e..590efc0bff67 100644
--- a/cms/djangoapps/contentstore/tests/test_users_default_role.py
+++ b/cms/djangoapps/contentstore/tests/test_users_default_role.py
@@ -3,7 +3,9 @@
after deleting it creates same course again
"""
-from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_AMNESTY_MODULESTORE, ModuleStoreTestCase
+from unittest import skip
+
+from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase
from cms.djangoapps.contentstore.tests.utils import AjaxEnabledTestClient
from cms.djangoapps.contentstore.utils import delete_course, reverse_url
@@ -15,7 +17,7 @@ class TestUsersDefaultRole(ModuleStoreTestCase):
"""
Unit tests for checking enrollment and default forum role "Student" of a logged in user
"""
- MODULESTORE = TEST_DATA_MONGO_AMNESTY_MODULESTORE
+ MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
def setUp(self):
"""
@@ -92,6 +94,8 @@ def test_user_role_on_course_recreate(self):
# check that user has his default "Student" forum role for this course
self.assertTrue(self.user.roles.filter(name="Student", course_id=self.course_key))
+ @skip("OldMongo Deprecation")
+ # Issue with case-insensitive course keys
def test_user_role_on_course_recreate_with_change_name_case(self):
"""
Test that creating same course again with different name case after deleting it gives user
diff --git a/cms/djangoapps/contentstore/tests/utils.py b/cms/djangoapps/contentstore/tests/utils.py
index cae265f5abc2..b58ec17502b8 100644
--- a/cms/djangoapps/contentstore/tests/utils.py
+++ b/cms/djangoapps/contentstore/tests/utils.py
@@ -8,15 +8,13 @@
from django.conf import settings
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.test.client import Client
-from opaque_keys.edx.keys import AssetKey, CourseKey
+from opaque_keys.edx.keys import AssetKey
from xmodule.contentstore.django import contentstore
-from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.inheritance import own_metadata
from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore
from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_MODULESTORE, ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.tests.utils import ProceduralCourseTestMixin
-from xmodule.modulestore.xml_importer import import_course_from_xml
from xmodule.tests.test_transcripts_utils import YoutubeVideoHTMLResponse
from cms.djangoapps.contentstore.utils import reverse_url
@@ -125,158 +123,6 @@ def save_course(self):
DRAFT_VIDEO = 'draft_video'
LOCKED_ASSET_KEY = AssetKey.from_string('/c4x/edX/toy/asset/sample_static.html')
- def import_and_populate_course(self):
- """
- Imports the test toy course and populates it with additional test data
- """
- content_store = contentstore()
- import_course_from_xml(self.store, self.user.id, TEST_DATA_DIR, ['toy'], static_content_store=content_store)
- course_id = CourseKey.from_string('/'.join(['edX', 'toy', '2012_Fall']))
-
- # create an Orphan
- # We had a bug where orphaned draft nodes caused export to fail. This is here to cover that case.
- vertical = self.store.get_item(course_id.make_usage_key('vertical', self.TEST_VERTICAL), depth=1)
- vertical.location = vertical.location.replace(name='no_references')
- self.store.update_item(vertical, self.user.id, allow_not_found=True)
- orphan_vertical = self.store.get_item(vertical.location)
- self.assertEqual(orphan_vertical.location.block_id, 'no_references')
- self.assertEqual(len(orphan_vertical.children), len(vertical.children))
-
- # create an orphan vertical and html; we already don't try to import
- # the orphaned vertical, but we should make sure we don't import
- # the orphaned vertical's child html, too
- orphan_draft_vertical = self.store.create_item(
- self.user.id, course_id, 'vertical', self.ORPHAN_DRAFT_VERTICAL
- )
- orphan_draft_html = self.store.create_item(
- self.user.id, course_id, 'html', self.ORPHAN_DRAFT_HTML
- )
- orphan_draft_vertical.children.append(orphan_draft_html.location)
- self.store.update_item(orphan_draft_vertical, self.user.id)
-
- # create a Draft vertical
- vertical = self.store.get_item(course_id.make_usage_key('vertical', self.TEST_VERTICAL), depth=1)
- draft_vertical = self.store.convert_to_draft(vertical.location, self.user.id)
- self.assertTrue(self.store.has_published_version(draft_vertical))
-
- # create a Private (draft only) vertical
- private_vertical = self.store.create_item(self.user.id, course_id, 'vertical', self.PRIVATE_VERTICAL)
- self.assertFalse(self.store.has_published_version(private_vertical))
-
- # create a Published (no draft) vertical
- public_vertical = self.store.create_item(self.user.id, course_id, 'vertical', self.PUBLISHED_VERTICAL)
- public_vertical = self.store.publish(public_vertical.location, self.user.id)
- self.assertTrue(self.store.has_published_version(public_vertical))
-
- # add the new private and new public as children of the sequential
- sequential = self.store.get_item(course_id.make_usage_key('sequential', self.SEQUENTIAL))
- sequential.children.append(private_vertical.location)
- sequential.children.append(public_vertical.location)
- self.store.update_item(sequential, self.user.id)
-
- # create an html and video component to make drafts:
- draft_html = self.store.create_item(self.user.id, course_id, 'html', self.DRAFT_HTML)
- draft_video = self.store.create_item(self.user.id, course_id, 'video', self.DRAFT_VIDEO)
-
- # add them as children to the public_vertical
- public_vertical.children.append(draft_html.location)
- public_vertical.children.append(draft_video.location)
- self.store.update_item(public_vertical, self.user.id)
- # publish changes to vertical
- self.store.publish(public_vertical.location, self.user.id)
- # convert html/video to draft
- self.store.convert_to_draft(draft_html.location, self.user.id)
- self.store.convert_to_draft(draft_video.location, self.user.id)
-
- # lock an asset
- content_store.set_attr(self.LOCKED_ASSET_KEY, 'locked', True)
-
- # create a non-portable link - should be rewritten in new courses
- html_block = self.store.get_item(course_id.make_usage_key('html', 'nonportable'))
- new_data = html_block.data = html_block.data.replace(
- '/static/',
- f'/c4x/{course_id.org}/{course_id.course}/asset/'
- )
- self.store.update_item(html_block, self.user.id)
-
- html_block = self.store.get_item(html_block.location)
- self.assertEqual(new_data, html_block.data)
-
- return course_id
-
- def check_populated_course(self, course_id):
- """
- Verifies the content of the given course, per data that was populated in import_and_populate_course
- """
- items = self.store.get_items(
- course_id,
- qualifiers={'category': 'vertical'},
- revision=ModuleStoreEnum.RevisionOption.published_only
- )
- self.check_verticals(items)
-
- def verify_item_publish_state(item, publish_state):
- """Verifies the publish state of the item is as expected."""
- self.assertEqual(self.store.has_published_version(item), publish_state)
-
- def get_and_verify_publish_state(item_type, item_name, publish_state):
- """
- Gets the given item from the store and verifies the publish state
- of the item is as expected.
- """
- item = self.store.get_item(course_id.make_usage_key(item_type, item_name))
- verify_item_publish_state(item, publish_state)
- return item
-
- # verify draft vertical has a published version with published children
- vertical = get_and_verify_publish_state('vertical', self.TEST_VERTICAL, True)
- for child in vertical.get_children():
- verify_item_publish_state(child, True)
-
- # verify that it has a draft too
- self.assertTrue(getattr(vertical, "is_draft", False))
-
- # make sure that we don't have a sequential that is in draft mode
- sequential = get_and_verify_publish_state('sequential', self.SEQUENTIAL, True)
- self.assertFalse(getattr(sequential, "is_draft", False))
-
- # verify that we have the private vertical
- private_vertical = get_and_verify_publish_state('vertical', self.PRIVATE_VERTICAL, False)
-
- # verify that we have the public vertical
- public_vertical = get_and_verify_publish_state('vertical', self.PUBLISHED_VERTICAL, True)
-
- # verify that we have the draft html
- draft_html = self.store.get_item(course_id.make_usage_key('html', self.DRAFT_HTML))
- self.assertTrue(getattr(draft_html, 'is_draft', False))
-
- # verify that we have the draft video
- draft_video = self.store.get_item(course_id.make_usage_key('video', self.DRAFT_VIDEO))
- self.assertTrue(getattr(draft_video, 'is_draft', False))
-
- # verify verticals are children of sequential
- for vert in [vertical, private_vertical, public_vertical]:
- self.assertIn(vert.location, sequential.children)
-
- # verify draft html is the child of the public vertical
- self.assertIn(draft_html.location, public_vertical.children)
-
- # verify draft video is the child of the public vertical
- self.assertIn(draft_video.location, public_vertical.children)
-
- # verify textbook exists
- course = self.store.get_course(course_id)
- self.assertGreater(len(course.textbooks), 0)
-
- # verify asset attributes of locked asset key
- self.assertAssetsEqual(self.LOCKED_ASSET_KEY, self.LOCKED_ASSET_KEY.course_key, course_id)
-
- # verify non-portable links are rewritten
- html_block = self.store.get_item(course_id.make_usage_key('html', 'nonportable'))
- self.assertIn('/static/foo.jpg', html_block.data)
-
- return course
-
def assertCoursesEqual(self, course1_id, course2_id):
"""
Verifies the content of the two given courses are equal
diff --git a/cms/djangoapps/contentstore/views/tests/test_assets.py b/cms/djangoapps/contentstore/views/tests/test_assets.py
index 6ee861888809..3f468e3f39cf 100644
--- a/cms/djangoapps/contentstore/views/tests/test_assets.py
+++ b/cms/djangoapps/contentstore/views/tests/test_assets.py
@@ -27,6 +27,7 @@
from xmodule.modulestore import ModuleStoreEnum # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.xml_importer import import_course_from_xml # lint-amnesty, pylint: disable=wrong-import-order
+from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE
TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT
@@ -41,6 +42,9 @@ class AssetsTestCase(CourseTestCase):
"""
Parent class for all asset tests.
"""
+
+ MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
+
def setUp(self):
super().setUp()
self.url = reverse_course_url('assets_handler', self.course.id)
@@ -96,6 +100,7 @@ def test_pdf_asset(self):
TEST_DATA_DIR,
['toy'],
static_content_store=contentstore(),
+ create_if_not_present=True,
verbose=True
)
course = course_items[0]
@@ -103,8 +108,8 @@ def test_pdf_asset(self):
# Test valid contentType for pdf asset (textbook.pdf)
resp = self.client.get(url, HTTP_ACCEPT='application/json')
- self.assertContains(resp, "/c4x/edX/toy/asset/textbook.pdf")
- asset_location = AssetKey.from_string('/c4x/edX/toy/asset/textbook.pdf')
+ self.assertContains(resp, "/asset-v1:edX+toy+2012_Fall+type@asset+block@textbook.pdf")
+ asset_location = AssetKey.from_string('asset-v1:edX+toy+2012_Fall+type@asset+block@textbook.pdf')
content = contentstore().find(asset_location)
# Check after import textbook.pdf has valid contentType ('application/pdf')
@@ -450,7 +455,8 @@ def test_locking(self):
"""
def verify_asset_locked_state(locked):
""" Helper method to verify lock state in the contentstore """
- asset_location = StaticContent.get_location_from_path('/c4x/edX/toy/asset/sample_static.html')
+ asset_location = StaticContent.get_location_from_path(
+ 'asset-v1:edX+toy+2012_Fall+type@asset+block@sample_static.html')
content = contentstore().find(asset_location)
self.assertEqual(content.locked, locked)
@@ -483,6 +489,7 @@ def post_asset_update(lock, course):
TEST_DATA_DIR,
['toy'],
static_content_store=contentstore(),
+ create_if_not_present=True,
verbose=True
)
course = course_items[0]
@@ -513,15 +520,15 @@ def setUp(self):
response = self.client.post(self.url, {"name": self.asset_name, "file": self.asset})
self.assertEqual(response.status_code, 200)
- self.uploaded_url = json.loads(response.content.decode('utf-8'))['asset']['url']
+ self.uploaded_id = json.loads(response.content.decode('utf-8'))['asset']['id']
- self.asset_location = AssetKey.from_string(self.uploaded_url)
+ self.asset_location = AssetKey.from_string(self.uploaded_id)
self.content = contentstore().find(self.asset_location)
def test_delete_asset(self):
""" Tests the happy path :) """
test_url = reverse_course_url(
- 'assets_handler', self.course.id, kwargs={'asset_key_string': str(self.uploaded_url)})
+ 'assets_handler', self.course.id, kwargs={'asset_key_string': self.uploaded_id})
resp = self.client.delete(test_url, HTTP_ACCEPT="application/json")
self.assertEqual(resp.status_code, 204)
@@ -533,7 +540,7 @@ def test_delete_image_type_asset(self):
# upload image
response = self.client.post(self.url, {"name": "delete_image_test", "file": image_asset})
self.assertEqual(response.status_code, 200)
- uploaded_image_url = json.loads(response.content.decode('utf-8'))['asset']['url']
+ uploaded_image_url = json.loads(response.content.decode('utf-8'))['asset']['id']
# upload image thumbnail
response = self.client.post(self.url, {"name": "delete_image_thumb_test", "file": thumbnail_image_asset})
@@ -558,7 +565,7 @@ def test_delete_asset_with_invalid_asset(self):
""" Tests the sad path :( """
test_url = reverse_course_url(
'assets_handler',
- self.course.id, kwargs={'asset_key_string': "/c4x/edX/toy/asset/invalid.pdf"}
+ self.course.id, kwargs={'asset_key_string': "asset-v1:edX+toy+2012_Fall+type@asset+block@invalid.pdf"}
)
resp = self.client.delete(test_url, HTTP_ACCEPT="application/json")
self.assertEqual(resp.status_code, 404)
@@ -566,8 +573,9 @@ def test_delete_asset_with_invalid_asset(self):
def test_delete_asset_with_invalid_thumbnail(self):
""" Tests the sad path :( """
test_url = reverse_course_url(
- 'assets_handler', self.course.id, kwargs={'asset_key_string': str(self.uploaded_url)})
- self.content.thumbnail_location = StaticContent.get_location_from_path('/c4x/edX/toy/asset/invalid')
+ 'assets_handler', self.course.id, kwargs={'asset_key_string': self.uploaded_id})
+ self.content.thumbnail_location = StaticContent.get_location_from_path(
+ '/asset-v1:edX+toy+2012_Fall+type@asset+block@invalid.pdf')
contentstore().save(self.content)
resp = self.client.delete(test_url, HTTP_ACCEPT="application/json")
self.assertEqual(resp.status_code, 204)
diff --git a/cms/lib/xblock/test/test_authoring_mixin.py b/cms/lib/xblock/test/test_authoring_mixin.py
index 6028f39614a2..5bbcdae3c298 100644
--- a/cms/lib/xblock/test/test_authoring_mixin.py
+++ b/cms/lib/xblock/test/test_authoring_mixin.py
@@ -6,7 +6,7 @@
from django.conf import settings
from django.test.utils import override_settings
from xblock.core import XBlock
-from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_AMNESTY_MODULESTORE, ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.partitions.partitions import (
ENROLLMENT_TRACK_PARTITION_ID,
@@ -23,7 +23,7 @@ class AuthoringMixinTestCase(ModuleStoreTestCase):
"""
Tests the studio authoring XBlock mixin.
"""
- MODULESTORE = TEST_DATA_MONGO_AMNESTY_MODULESTORE
+ MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
GROUP_NO_LONGER_EXISTS = "This group no longer exists"
NO_CONTENT_OR_ENROLLMENT_GROUPS = "Access to this component is not restricted"
NO_CONTENT_ENROLLMENT_TRACK_ENABLED = "You can restrict access to this component to learners in specific enrollment tracks or content groups" # lint-amnesty, pylint: disable=line-too-long
@@ -44,27 +44,27 @@ def setUp(self):
self.course = CourseFactory.create()
chapter = ItemFactory.create(
category='chapter',
- parent_location=self.course.location,
+ parent=self.course,
display_name='Test Chapter'
)
sequential = ItemFactory.create(
category='sequential',
- parent_location=chapter.location,
+ parent=chapter,
display_name='Test Sequential'
)
vertical = ItemFactory.create(
category='vertical',
- parent_location=sequential.location,
+ parent=sequential,
display_name='Test Vertical'
)
video = ItemFactory.create(
category='video',
- parent_location=vertical.location,
+ parent=vertical,
display_name='Test Vertical'
)
pure = ItemFactory.create(
category='pure',
- parent_location=vertical.location,
+ parent=vertical,
display_name='Test Pure'
)
self.vertical_location = vertical.location
diff --git a/lms/djangoapps/support/tests/test_views.py b/lms/djangoapps/support/tests/test_views.py
index bf31b23398e9..51d847d21802 100644
--- a/lms/djangoapps/support/tests/test_views.py
+++ b/lms/djangoapps/support/tests/test_views.py
@@ -31,7 +31,7 @@
from rest_framework import status
from social_django.models import UserSocialAuth
from xmodule.modulestore.tests.django_utils import (
- TEST_DATA_MONGO_AMNESTY_MODULESTORE, ModuleStoreTestCase, SharedModuleStoreTestCase,
+ TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase, SharedModuleStoreTestCase,
)
from xmodule.modulestore.tests.factories import CourseFactory
@@ -267,7 +267,7 @@ class SupportViewCertificatesTests(SupportViewTestCase):
"""
Tests for the certificates support view.
"""
- MODULESTORE = TEST_DATA_MONGO_AMNESTY_MODULESTORE
+ MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
def setUp(self):
"""Make the user support staff. """
@@ -290,7 +290,9 @@ def test_certificates_along_with_course_filter(self):
url = reverse("support:certificates") + "?user=student@example.com&course_id=" + quote(str(self.course.id))
response = self.client.get(url)
self.assertContains(response, "userFilter: 'student@example.com'")
- self.assertContains(response, "courseFilter: '" + str(self.course.id) + "'")
+ # use replase due to escaping course id:
+ # https://docs.djangoproject.com/en/dev/ref/templates/builtins/#escapejs
+ self.assertContains(response, "courseFilter: '" + str(self.course.id).replace('-', '\\u002D') + "'")
@ddt.ddt
@@ -1859,12 +1861,15 @@ class TestOnboardingView(SupportViewTestCase, ProctoredExamTestCase):
"""
Tests for OnboardingView
"""
- MODULESTORE = TEST_DATA_MONGO_AMNESTY_MODULESTORE
+ MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
def setUp(self):
super().setUp()
SupportStaffRole().add_users(self.user)
+ # update default course key
+ self.course_id = 'course-v1:a+b+c'
+
self.proctored_exam_id = self._create_proctored_exam()
self.onboarding_exam_id = self._create_onboarding_exam()
@@ -1904,7 +1909,7 @@ def _url(self, username):
def _create_enrollment(self):
""" Create enrollment in default course """
- # default course key = 'a/b/c'
+ # updated course key = 'course-v1:a+b+c'
self.course = CourseFactory.create(
org='a',
course='b',
@@ -2024,7 +2029,7 @@ def test_verified_in_another_course(self):
update_attempt_status(attempt_id, ProctoredExamStudentAttemptStatus.submitted)
# Create an attempt in the other course that has been verified
- other_course_id = 'x/y/z'
+ other_course_id = 'course-v1:x+y+z'
other_course_onboarding_exam = ProctoredExam.objects.create(
course_id=other_course_id,
content_id=self.other_course_content,
@@ -2057,8 +2062,8 @@ def test_verified_in_another_course(self):
# assert that originally verified enrollment is reflected correctly
self.assertEqual(response_data['verified_in']['onboarding_status'], 'verified')
- self.assertEqual(response_data['verified_in']['course_id'], 'x/y/z')
+ self.assertEqual(response_data['verified_in']['course_id'], other_course_id)
# assert that most recent enrollment (current status) has other_course_approved status
self.assertEqual(response_data['current_status']['onboarding_status'], 'other_course_approved')
- self.assertEqual(response_data['current_status']['course_id'], 'a/b/c')
+ self.assertEqual(response_data['current_status']['course_id'], self.course_id)
diff --git a/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py b/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py
index 0f98eb26b7cc..8c4fb25c8a73 100644
--- a/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py
+++ b/openedx/core/djangoapps/content/course_overviews/tests/test_signals.py
@@ -6,10 +6,11 @@
import pytest
import ddt
+from pytz import UTC
from xmodule.data import CertificatesDisplayBehaviors
from xmodule.modulestore import ModuleStoreEnum
-from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_AMNESTY_MODULESTORE, ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import TEST_DATA_ONLY_SPLIT_MODULESTORE_DRAFT_PREFERRED, ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, check_mongo_calls
from ..models import CourseOverview
@@ -23,13 +24,12 @@ class CourseOverviewSignalsTestCase(ModuleStoreTestCase):
"""
Tests for CourseOverview signals.
"""
- MODULESTORE = TEST_DATA_MONGO_AMNESTY_MODULESTORE
+ MODULESTORE = TEST_DATA_ONLY_SPLIT_MODULESTORE_DRAFT_PREFERRED
ENABLED_SIGNALS = ['course_deleted', 'course_published']
- TODAY = datetime.datetime.utcnow()
+ TODAY = datetime.datetime.utcnow().replace(tzinfo=UTC)
NEXT_WEEK = TODAY + datetime.timedelta(days=7)
- @ddt.data(ModuleStoreEnum.Type.split)
- def test_caching(self, modulestore_type):
+ def test_caching(self):
"""
Tests that CourseOverview structures are actually getting cached.
@@ -38,14 +38,13 @@ def test_caching(self, modulestore_type):
course in.
"""
# Creating a new course will trigger a publish event and the course will be cached
- course = CourseFactory.create(default_store=modulestore_type, emit_signals=True)
+ course = CourseFactory.create(emit_signals=True)
# The cache will be hit and mongo will not be queried
with check_mongo_calls(0):
CourseOverview.get_from_id(course.id)
- @ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
- def test_cache_invalidation(self, modulestore_type):
+ def test_cache_invalidation(self):
"""
Tests that when a course is published or deleted, the corresponding
course_overview is removed from the cache.
@@ -54,28 +53,26 @@ def test_cache_invalidation(self, modulestore_type):
modulestore_type (ModuleStoreEnum.Type): type of store to create the
course in.
"""
- with self.store.default_store(modulestore_type):
-
- # Create a course where mobile_available is True.
- course = CourseFactory.create(mobile_available=True, default_store=modulestore_type)
- course_overview_1 = CourseOverview.get_from_id(course.id)
- assert course_overview_1.mobile_available
-
- # Set mobile_available to False and update the course.
- # This fires a course_published signal, which should be caught in signals.py, which should in turn
- # delete the corresponding CourseOverview from the cache.
- course.mobile_available = False
- with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
- self.store.update_item(course, ModuleStoreEnum.UserID.test)
+ # Create a course where mobile_available is True.
+ course = CourseFactory.create(mobile_available=True)
+ course_overview_1 = CourseOverview.get_from_id(course.id)
+ assert course_overview_1.mobile_available
+
+ # Set mobile_available to False and update the course.
+ # This fires a course_published signal, which should be caught in signals.py, which should in turn
+ # delete the corresponding CourseOverview from the cache.
+ course.mobile_available = False
+ with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
+ self.store.update_item(course, ModuleStoreEnum.UserID.test)
- # Make sure that when we load the CourseOverview again, mobile_available is updated.
- course_overview_2 = CourseOverview.get_from_id(course.id)
- assert not course_overview_2.mobile_available
+ # Make sure that when we load the CourseOverview again, mobile_available is updated.
+ course_overview_2 = CourseOverview.get_from_id(course.id)
+ assert not course_overview_2.mobile_available
- # Verify that when the course is deleted, the corresponding CourseOverview is deleted as well.
- with pytest.raises(CourseOverview.DoesNotExist):
- self.store.delete_course(course.id, ModuleStoreEnum.UserID.test)
- CourseOverview.get_from_id(course.id)
+ # Verify that when the course is deleted, the corresponding CourseOverview is deleted as well.
+ with pytest.raises(CourseOverview.DoesNotExist):
+ self.store.delete_course(course.id, ModuleStoreEnum.UserID.test)
+ CourseOverview.get_from_id(course.id)
def assert_changed_signal_sent(self, changes, mock_signal): # lint-amnesty, pylint: disable=missing-function-docstring
course = CourseFactory.create(
@@ -86,7 +83,7 @@ def assert_changed_signal_sent(self, changes, mock_signal): # lint-amnesty, pyl
# changing display name doesn't fire the signal
with self.captureOnCommitCallbacks(execute=True) as callbacks:
course.display_name = course.display_name + 'changed'
- self.store.update_item(course, ModuleStoreEnum.UserID.test)
+ course = self.store.update_item(course, ModuleStoreEnum.UserID.test)
assert not mock_signal.called
# changing the given field fires the signal
diff --git a/openedx/core/lib/tests/test_xblock_utils.py b/openedx/core/lib/tests/test_xblock_utils.py
index 6671267133c6..20dcaa1f02b7 100644
--- a/openedx/core/lib/tests/test_xblock_utils.py
+++ b/openedx/core/lib/tests/test_xblock_utils.py
@@ -13,7 +13,7 @@
from web_fragments.fragment import Fragment
from xblock.core import XBlockAside
from xmodule.modulestore import ModuleStoreEnum
-from xmodule.modulestore.tests.django_utils import TEST_DATA_MONGO_AMNESTY_MODULESTORE, SharedModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.tests.test_asides import AsideTestType
@@ -38,13 +38,7 @@ class TestXblockUtils(SharedModuleStoreTestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- cls.course_mongo = CourseFactory.create(
- default_store=ModuleStoreEnum.Type.mongo,
- org='TestX',
- number='TS01',
- run='2015'
- )
- cls.course_split = CourseFactory.create(
+ cls.course = CourseFactory.create(
default_store=ModuleStoreEnum.Type.split,
org='TestX',
number='TS02',
@@ -86,21 +80,15 @@ def test_request_token(self):
test_uuid = uuid.UUID(token, version=1)
assert token == test_uuid.hex
- @ddt.data(
- ('course_mongo', 'data-usage-id="i4x:;_;_TestX;_TS01;_course;_2015"'),
- ('course_split', 'data-usage-id="block-v1:TestX+TS02+2015+type@course+block@course"')
- )
- @ddt.unpack
- def test_wrap_xblock(self, course_id, data_usage_id):
+ def test_wrap_xblock(self):
"""
Verify that new content is added and the resources are the same.
"""
fragment = self.create_fragment("
Test!
")
fragment.initialize_js('BlockMain') # wrap_block() sets some attributes only if there is JS.
- course = getattr(self, course_id)
test_wrap_output = wrap_xblock(
runtime_class='TestRuntime',
- block=course,
+ block=self.course,
view='baseview',
frag=fragment,
context={"wrap_xblock_data": {"custom-attribute": "custom-value"}},
@@ -110,7 +98,7 @@ def test_wrap_xblock(self, course_id, data_usage_id):
assert isinstance(test_wrap_output, Fragment)
assert 'xblock-baseview' in test_wrap_output.content
assert 'data-runtime-class="TestRuntime"' in test_wrap_output.content
- assert data_usage_id in test_wrap_output.content
+ assert 'data-usage-id="block-v1:TestX+TS02+2015+type@course+block@course"' in test_wrap_output.content
assert 'Test!
' in test_wrap_output.content
assert 'data-custom-attribute="custom-value"' in test_wrap_output.content
assert test_wrap_output.resources[0].data == 'body {background-color:red;}'
@@ -170,13 +158,13 @@ def test_get_js_dependencies(self, pipeline_enabled, expected_js_dependencies):
class TestXBlockAside(SharedModuleStoreTestCase):
"""Test the xblock aside function."""
- MODULESTORE = TEST_DATA_MONGO_AMNESTY_MODULESTORE
+ MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.course = CourseFactory.create()
- cls.block = ItemFactory.create(category='aside', parent=cls.course)
+ cls.block = ItemFactory.create(parent=cls.course)
cls.aside_v2 = AsideUsageKeyV2(cls.block.scope_ids.usage_id, "aside")
cls.aside_v1 = AsideUsageKeyV1(cls.block.scope_ids.usage_id, "aside")