From 1f7082ebfea531b4a6ca34e6390ca14beca173fe Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Thu, 24 Sep 2015 15:20:21 -0400 Subject: [PATCH] Add a test of the semantics of About items These are XBlocks that are detached (not part of the course content hierarchy), and are also DIRECT_ONLY_CATEGORIES (meaning they are always autopublished). https://openedx.atlassian.net/browse/PLAT-858 identifies a bug where an About item isn't correctly deleted in SplitDraft, and this test reproduces that case. --- .../modulestore/tests/test_semantics.py | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 common/lib/xmodule/xmodule/modulestore/tests/test_semantics.py diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_semantics.py b/common/lib/xmodule/xmodule/modulestore/tests/test_semantics.py new file mode 100644 index 0000000000..a8ca56559a --- /dev/null +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_semantics.py @@ -0,0 +1,127 @@ +""" +Tests of modulestore semantics: How do the interfaces methods of ModuleStore relate to each other? +""" + +from xmodule.modulestore.tests.utils import ( + PureModulestoreTestCase, MongoModulestoreBuilder, + SPLIT_MODULESTORE_SETUP +) +from xmodule.modulestore.exceptions import ItemNotFoundError +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.tests.factories import CourseFactory + +class AboutItemSemantics(PureModulestoreTestCase): + """ + Verify the behavior of About items (which are intentionally orphaned, DIRECT_ONLY/autopublished) + blocks intended to store snippets of course content. + """ + + __test__ = False + + def setUp(self): + super(AboutItemSemantics, self).setUp() + self.course = CourseFactory.create( + org='test_org', + number='999', + run='test_run', + display_name='My Test Course', + modulestore=self.store + ) + + self.about_usage_key = self.course.id.make_usage_key('about', 'video') + + def assertAboutDoesntExist(self): + with self.assertRaises(ItemNotFoundError): + self.store.get_item(self.about_usage_key, revision=ModuleStoreEnum.RevisionOption.published_only) + with self.assertRaises(ItemNotFoundError): + self.store.get_item(self.about_usage_key, revision=ModuleStoreEnum.RevisionOption.draft_only) + + with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): + with self.assertRaises(ItemNotFoundError): + self.store.get_item(self.about_usage_key) + + with self.store.branch_setting(ModuleStoreEnum.Branch.published_only): + with self.assertRaises(ItemNotFoundError): + self.store.get_item(self.about_usage_key) + + def assertAboutHasContent(self, content): + self.assertEquals( + content, + self.store.get_item( + self.about_usage_key, + revision=ModuleStoreEnum.RevisionOption.published_only + ).data + ) + self.assertEquals( + content, + self.store.get_item( + self.about_usage_key, + revision=ModuleStoreEnum.RevisionOption.draft_only + ).data + ) + + with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): + self.assertEquals( + content, + self.store.get_item( + self.about_usage_key, + ).data + ) + + with self.store.branch_setting(ModuleStoreEnum.Branch.published_only): + self.assertEquals( + content, + self.store.get_item( + self.about_usage_key, + ).data + ) + + def test_create(self): + self.assertAboutDoesntExist() + + data_string = '
test data
' + + with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): + about_item = self.store.create_xblock( + self.course.runtime, + self.course.id, + self.about_usage_key.block_type, + block_id=self.about_usage_key.block_id + ) + + about_item.data = data_string + self.store.update_item(about_item, ModuleStoreEnum.UserID.test, allow_not_found=True) + + self.assertAboutHasContent(data_string) + + def test_update(self): + self.test_create() + + with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): + about_item = self.store.get_item(self.about_usage_key) + + data_string = "
different test data
" + self.assertNotEquals(data_string, about_item.data) + + about_item.data = data_string + + self.store.update_item(about_item, ModuleStoreEnum.UserID.test, allow_not_found=True) + + self.assertAboutHasContent(data_string) + + def test_delete(self): + self.test_create() + + with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): + self.store.delete_item(self.about_usage_key, ModuleStoreEnum.UserID.test) + + self.assertAboutDoesntExist() + +class TestSplitAboutItemSemantics(AboutItemSemantics): + MODULESTORE = SPLIT_MODULESTORE_SETUP + __test__ = True + + +class TestMongoAboutItemSemantics(AboutItemSemantics): + MODULESTORE = MongoModulestoreBuilder() + __test__ = True