Commit ac507c3d by Calen Pennington

Upgrade AboutItemSemantics test to verify for all direct-only categories

parent a7c7ceb9
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
Tests of modulestore semantics: How do the interfaces methods of ModuleStore relate to each other? Tests of modulestore semantics: How do the interfaces methods of ModuleStore relate to each other?
""" """
import ddt
from collections import namedtuple
from xmodule.modulestore.tests.utils import ( from xmodule.modulestore.tests.utils import (
PureModulestoreTestCase, MongoModulestoreBuilder, PureModulestoreTestCase, MongoModulestoreBuilder,
SPLIT_MODULESTORE_SETUP SPLIT_MODULESTORE_SETUP
...@@ -9,17 +12,37 @@ from xmodule.modulestore.tests.utils import ( ...@@ -9,17 +12,37 @@ from xmodule.modulestore.tests.utils import (
from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES
from xblock.core import XBlock
DETACHED_BLOCK_TYPES = dict(XBlock.load_tagged_classes('detached'))
# These tests won't work with courses, since they're creating blocks inside courses
TESTABLE_BLOCK_TYPES = set(DIRECT_ONLY_CATEGORIES)
TESTABLE_BLOCK_TYPES.discard('course')
TestField = namedtuple('TestField', ['field_name', 'initial', 'updated'])
class AboutItemSemantics(PureModulestoreTestCase):
@ddt.ddt
class DirectOnlyCategorySemantics(PureModulestoreTestCase):
""" """
Verify the behavior of About items (which are intentionally orphaned, DIRECT_ONLY/autopublished) Verify the behavior of Direct Only items
blocks intended to store snippets of course content. blocks intended to store snippets of course content.
""" """
__test__ = False __test__ = False
DATA_FIELDS = {
'about': TestField('data', '<div>test data</div>', '<div>different test data</div>'),
'chapter': TestField('is_entrance_exam', True, False),
'sequential': TestField('is_entrance_exam', True, False),
'static_tab': TestField('data', '<div>test data</div>', '<div>different test data</div>'),
'course_info': TestField('data', '<div>test data</div>', '<div>different test data</div>'),
}
def setUp(self): def setUp(self):
super(AboutItemSemantics, self).setUp() super(DirectOnlyCategorySemantics, self).setUp()
self.course = CourseFactory.create( self.course = CourseFactory.create(
org='test_org', org='test_org',
number='999', number='999',
...@@ -28,100 +51,132 @@ class AboutItemSemantics(PureModulestoreTestCase): ...@@ -28,100 +51,132 @@ class AboutItemSemantics(PureModulestoreTestCase):
modulestore=self.store modulestore=self.store
) )
self.about_usage_key = self.course.id.make_usage_key('about', 'video') def assertBlockDoesntExist(self):
def assertAboutDoesntExist(self):
with self.assertRaises(ItemNotFoundError): with self.assertRaises(ItemNotFoundError):
self.store.get_item(self.about_usage_key, revision=ModuleStoreEnum.RevisionOption.published_only) self.store.get_item(self.block_usage_key, revision=ModuleStoreEnum.RevisionOption.published_only)
with self.assertRaises(ItemNotFoundError): with self.assertRaises(ItemNotFoundError):
self.store.get_item(self.about_usage_key, revision=ModuleStoreEnum.RevisionOption.draft_only) self.store.get_item(self.block_usage_key, revision=ModuleStoreEnum.RevisionOption.draft_only)
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
with self.assertRaises(ItemNotFoundError): with self.assertRaises(ItemNotFoundError):
self.store.get_item(self.about_usage_key) self.store.get_item(self.block_usage_key)
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only): with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
with self.assertRaises(ItemNotFoundError): with self.assertRaises(ItemNotFoundError):
self.store.get_item(self.about_usage_key) self.store.get_item(self.block_usage_key)
def assertAboutHasContent(self, content): def assertBlockHasContent(self, test_data, content):
self.assertEquals( target_block = self.store.get_item(
content, self.block_usage_key,
self.store.get_item(
self.about_usage_key,
revision=ModuleStoreEnum.RevisionOption.published_only revision=ModuleStoreEnum.RevisionOption.published_only
).data
) )
self.assertEquals(
content, self.assertEquals(content, target_block.fields[test_data.field_name].read_from(target_block))
self.store.get_item(
self.about_usage_key, target_block = self.store.get_item(
self.block_usage_key,
revision=ModuleStoreEnum.RevisionOption.draft_only revision=ModuleStoreEnum.RevisionOption.draft_only
).data
) )
self.assertEquals(content, target_block.fields[test_data.field_name].read_from(target_block))
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
self.assertEquals( target_block = self.store.get_item(
content, self.block_usage_key,
self.store.get_item(
self.about_usage_key,
).data
) )
self.assertEquals(content, target_block.fields[test_data.field_name].read_from(target_block))
with self.store.branch_setting(ModuleStoreEnum.Branch.published_only): with self.store.branch_setting(ModuleStoreEnum.Branch.published_only):
self.assertEquals( target_block = self.store.get_item(
content, self.block_usage_key,
self.store.get_item(
self.about_usage_key,
).data
) )
self.assertEquals(content, target_block.fields[test_data.field_name].read_from(target_block))
def test_create(self): def is_detached(self, block_type):
self.assertAboutDoesntExist() """
Return True if ``block_type`` is a detached block.
"""
return block_type in DETACHED_BLOCK_TYPES
data_string = '<div>test data</div>' @ddt.data(*TESTABLE_BLOCK_TYPES)
def test_create(self, block_type):
self._do_create(block_type)
# This function is split out from the test_create method so that it can be called
# by other tests
def _do_create(self, block_type):
"""
Create a block of block_type (which should be a DIRECT_ONLY_CATEGORY),
and then verify that it was created successfully, and is visible in
both published and draft branches.
"""
self.block_usage_key = self.course.id.make_usage_key(block_type, 'test_block')
self.assertBlockDoesntExist()
test_data = self.DATA_FIELDS[block_type]
initial_field_value = test_data.initial
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
about_item = self.store.create_xblock( if self.is_detached(block_type):
block = self.store.create_xblock(
self.course.runtime, self.course.runtime,
self.course.id, self.course.id,
self.about_usage_key.block_type, self.block_usage_key.block_type,
block_id=self.about_usage_key.block_id block_id=self.block_usage_key.block_id
)
block.fields[test_data.field_name].write_to(block, initial_field_value)
self.store.update_item(block, ModuleStoreEnum.UserID.test, allow_not_found=True)
else:
block = self.store.create_child(
user_id=ModuleStoreEnum.UserID.test,
parent_usage_key=self.course.scope_ids.usage_id,
block_type=block_type,
block_id=self.block_usage_key.block_id,
fields={test_data.field_name: initial_field_value},
) )
about_item.data = data_string self.assertBlockHasContent(test_data, initial_field_value)
self.store.update_item(about_item, ModuleStoreEnum.UserID.test, allow_not_found=True)
self.assertAboutHasContent(data_string)
def test_update(self): @ddt.data(*TESTABLE_BLOCK_TYPES)
self.test_create() def test_update(self, block_type):
self._do_create(block_type)
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
about_item = self.store.get_item(self.about_usage_key) block = self.store.get_item(self.block_usage_key)
data_string = "<div>different test data</div>" test_data = self.DATA_FIELDS[block_type]
self.assertNotEquals(data_string, about_item.data)
about_item.data = data_string updated_field_value = test_data.updated
self.assertNotEquals(updated_field_value, block.fields[test_data.field_name].read_from(block))
self.store.update_item(about_item, ModuleStoreEnum.UserID.test, allow_not_found=True) block.fields[test_data.field_name].write_to(block, updated_field_value)
self.assertAboutHasContent(data_string) self.store.update_item(block, ModuleStoreEnum.UserID.test, allow_not_found=True)
def test_delete(self): self.assertBlockHasContent(test_data, updated_field_value)
self.test_create()
@ddt.data(*TESTABLE_BLOCK_TYPES)
def test_delete(self, block_type):
self._do_create(block_type)
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
self.store.delete_item(self.about_usage_key, ModuleStoreEnum.UserID.test) self.store.delete_item(self.block_usage_key, ModuleStoreEnum.UserID.test)
self.assertBlockDoesntExist()
self.assertAboutDoesntExist()
class TestSplitAboutItemSemantics(AboutItemSemantics): class TestSplitDirectOnlyCategorySemantics(DirectOnlyCategorySemantics):
"""
Verify DIRECT_ONLY_CATEGORY semantics against the SplitMongoModulestore.
"""
MODULESTORE = SPLIT_MODULESTORE_SETUP MODULESTORE = SPLIT_MODULESTORE_SETUP
__test__ = True __test__ = True
class TestMongoAboutItemSemantics(AboutItemSemantics): class TestMongoDirectOnlyCategorySemantics(DirectOnlyCategorySemantics):
"""
Verify DIRECT_ONLY_CATEGORY semantics against the MongoModulestore
"""
MODULESTORE = MongoModulestoreBuilder() MODULESTORE = MongoModulestoreBuilder()
__test__ = True __test__ = True
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment