def make_oembed_block(cls): """ helper to construct a OEmbedBlock """ runtime = WorkbenchRuntime() key_store = DictKeyValueStore() db_model = KvsFieldData(key_store) ids = generate_scope_ids(runtime, 'oembed') return OEmbedXBlock(runtime, db_model, scope_ids=ids)
def test_lazy_translation(self): with warnings.catch_warnings(record=True) as caught_warnings: warnings.simplefilter('always', FailingEnforceTypeWarning) class XBlockTest(XBlock): """ Set up a class that contains a single string field with a translated default. """ STR_DEFAULT_ENG = 'ENG: String to be translated' str_field = String(scope=Scope.settings, default=_('ENG: String to be translated')) # No FailingEnforceTypeWarning should have been triggered assert not caught_warnings # Construct a runtime and an XBlock using it. key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = TestRuntime(Mock(), services={'field-data': field_data}) # Change language to 'de'. user_language = 'de' with translation.override(user_language): tester = runtime.construct_xblock_from_class(XBlockTest, ScopeIds('s0', 'XBlockTest', 'd0', 'u0')) # Assert instantiated XBlock str_field value is not yet evaluated. assert 'django.utils.functional.' in str(type(tester.str_field)) # Assert str_field *is* translated when the value is used. assert text_type(tester.str_field) == 'DEU: Translated string'
def test_runtime_render(): key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = MockRuntimeForQuerying(services={'field-data': field_data}) block_type = 'test' def_id = runtime.id_generator.create_definition(block_type) usage_id = runtime.id_generator.create_usage(def_id) tester = TestXBlock(runtime, scope_ids=ScopeIds('user', block_type, def_id, usage_id)) # string we want to update using the handler update_string = u"user state update" # test against the student view frag = runtime.render(tester, 'student_view', [update_string]) assert_in(update_string, frag.body_html()) assert_equals(tester.preferences, update_string) # test against the fallback view update_string = u"new update" frag = runtime.render(tester, 'test_fallback_view', [update_string]) assert_in(update_string, frag.body_html()) assert_equals(tester.preferences, update_string) # test block-first update_string = u"penultimate update" frag = tester.render('student_view', [update_string]) assert_in(update_string, frag.body_html()) assert_equals(tester.preferences, update_string) # test against the no-fallback XBlock update_string = u"ultimate update" tester = TestXBlockNoFallback(Mock(), scope_ids=Mock(spec=ScopeIds)) with assert_raises(NoSuchViewError): runtime.render(tester, 'test_nonexistent_view', [update_string])
def test_runtime_render(): key_store = DictKeyValueStore() db_model = KvsFieldData(key_store) runtime = MockRuntimeForQuerying() tester = TestXBlock(runtime, db_model, Mock()) # string we want to update using the handler update_string = u"user state update" # test against the student view frag = runtime.render(tester, 'student_view', [update_string]) assert_equals(frag.body_html(), update_string) assert_equals(tester.preferences, update_string) # test against the fallback view update_string = u"new update" frag = runtime.render(tester, 'test_fallback_view', [update_string]) assert_equals(frag.body_html(), update_string) assert_equals(tester.preferences, update_string) # test block-first update_string = u"penultimate update" frag = tester.render('student_view', [update_string]) assert_equals(frag.body_html(), update_string) assert_equals(tester.preferences, update_string) # test against the no-fallback XBlock update_string = u"ultimate update" tester = TestXBlockNoFallback(Mock(), db_model, Mock()) with assert_raises(NoSuchViewError): runtime.render(tester, 'test_nonexistant_view', [update_string])
def test_db_model_keys(): # Tests that updates to fields are properly recorded in the KeyValueStore, # and that the keys have been constructed correctly key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = TestRuntime(Mock(), mixins=[TestMixin], services={'field-data': field_data}) tester = runtime.construct_xblock_from_class(TestXBlock, ScopeIds('s0', 'TestXBlock', 'd0', 'u0')) assert not field_data.has(tester, 'not a field') for field in six.itervalues(tester.fields): new_value = 'new ' + field.name assert not field_data.has(tester, field.name) if isinstance(field, List): new_value = [new_value] setattr(tester, field.name, new_value) # Write out the values tester.save() # Make sure everything saved correctly for field in six.itervalues(tester.fields): assert field_data.has(tester, field.name) def get_key_value(scope, user_id, block_scope_id, field_name): """Gets the value, from `key_store`, of a Key with the given values.""" new_key = KeyValueStore.Key(scope, user_id, block_scope_id, field_name) return key_store.db_dict[new_key] # Examine each value in the database and ensure that keys were constructed correctly assert get_key_value(Scope.content, None, 'd0', 'content') == 'new content' assert get_key_value(Scope.settings, None, 'u0', 'settings') == 'new settings' assert get_key_value(Scope.user_state, 's0', 'u0', 'user_state') == 'new user_state' assert get_key_value(Scope.preferences, 's0', 'TestXBlock', 'preferences') == 'new preferences' assert get_key_value(Scope.user_info, 's0', None, 'user_info') == 'new user_info' assert get_key_value(Scope(UserScope.NONE, BlockScope.TYPE), None, 'TestXBlock', 'by_type') == 'new by_type' assert get_key_value(Scope(UserScope.NONE, BlockScope.ALL), None, None, 'for_all') == 'new for_all' assert get_key_value(Scope(UserScope.ONE, BlockScope.DEFINITION), 's0', 'd0', 'user_def') == 'new user_def' assert get_key_value(Scope(UserScope.ALL, BlockScope.ALL), None, None, 'agg_global') == 'new agg_global' assert get_key_value(Scope(UserScope.ALL, BlockScope.TYPE), None, 'TestXBlock', 'agg_type') == 'new agg_type' assert get_key_value(Scope(UserScope.ALL, BlockScope.DEFINITION), None, 'd0', 'agg_def') == 'new agg_def' assert get_key_value(Scope.user_state_summary, None, 'u0', 'agg_usage') == 'new agg_usage' assert get_key_value(Scope.content, None, 'd0', 'mixin_content') == 'new mixin_content' assert get_key_value(Scope.settings, None, 'u0', 'mixin_settings') == 'new mixin_settings' assert get_key_value(Scope.user_state, 's0', 'u0', 'mixin_user_state') == 'new mixin_user_state' assert get_key_value(Scope.preferences, 's0', 'TestXBlock', 'mixin_preferences') == 'new mixin_preferences' assert get_key_value(Scope.user_info, 's0', None, 'mixin_user_info') == 'new mixin_user_info' assert get_key_value(Scope(UserScope.NONE, BlockScope.TYPE), None, 'TestXBlock', 'mixin_by_type') == \ 'new mixin_by_type' assert get_key_value(Scope(UserScope.NONE, BlockScope.ALL), None, None, 'mixin_for_all') == \ 'new mixin_for_all' assert get_key_value(Scope(UserScope.ONE, BlockScope.DEFINITION), 's0', 'd0', 'mixin_user_def') == \ 'new mixin_user_def' assert get_key_value(Scope(UserScope.ALL, BlockScope.ALL), None, None, 'mixin_agg_global') == \ 'new mixin_agg_global' assert get_key_value(Scope(UserScope.ALL, BlockScope.TYPE), None, 'TestXBlock', 'mixin_agg_type') == \ 'new mixin_agg_type' assert get_key_value(Scope(UserScope.ALL, BlockScope.DEFINITION), None, 'd0', 'mixin_agg_def') == \ 'new mixin_agg_def' assert get_key_value(Scope.user_state_summary, None, 'u0', 'mixin_agg_usage') == 'new mixin_agg_usage'
def make_calendar_block(cls): """ helper to construct a GoogleCalendarBlock """ runtime = WorkbenchRuntime() key_store = DictKeyValueStore() db_model = KvsFieldData(key_store) ids = generate_scope_ids(runtime, 'google_calendar') return GoogleCalendarBlock(runtime, db_model, scope_ids=ids)
def _init_field_data_for_block(self, block): """ Initialize the FieldData implementation for the specified XBlock """ if self.user is None: # No user is specified, so we want to throw an error if anything attempts to read/write user-specific fields student_data_store = None elif self.user.is_anonymous: # The user is anonymous. Future work will support saving their state # in a cache or the django session but for now just use a highly # ephemeral dict. student_data_store = KvsFieldData(kvs=DictKeyValueStore()) elif self.system.student_data_mode == XBlockRuntimeSystem.STUDENT_DATA_EPHEMERAL: # We're in an environment like Studio where we want to let the # author test blocks out but not permanently save their state. # This in-memory dict will typically only persist for one # request-response cycle, so we need to soon replace it with a store # that puts the state into a cache or the django session. student_data_store = KvsFieldData(kvs=DictKeyValueStore()) else: # Use database-backed field data (i.e. store user_state in StudentModule) context_key = block.scope_ids.usage_id.context_key if context_key not in self.django_field_data_caches: field_data_cache = FieldDataCache( [block], course_id=context_key, user=self.user, asides=None, read_only=False, ) self.django_field_data_caches[context_key] = field_data_cache else: field_data_cache = self.django_field_data_caches[context_key] field_data_cache.add_descriptors_to_cache([block]) student_data_store = KvsFieldData( kvs=DjangoKeyValueStore(field_data_cache)) return SplitFieldData({ Scope.content: self.system.authored_data_store, Scope.settings: self.system.authored_data_store, Scope.parent: self.system.authored_data_store, Scope.children: self.system.authored_data_store, Scope.user_state_summary: student_data_store, Scope.user_state: student_data_store, Scope.user_info: student_data_store, Scope.preferences: student_data_store, })
def __init__(self): id_manager = MemoryIdManager() field_data = KvsFieldData(DictKeyValueStore()) super().__init__( id_reader=id_manager, id_generator=id_manager, field_data=field_data, )
def setUp(self): self.system = get_test_descriptor_system() self.all_blocks = {} self.system.get_block = self.all_blocks.get self.field_data = InheritingFieldData( inheritable_names=['inherited'], kvs=DictKeyValueStore({}), )
def setUp(self): """ Create a stub XBlock backed by in-memory storage. """ self.runtime = mock.MagicMock(Runtime) self.field_data = KvsFieldData(kvs=DictKeyValueStore()) self.scope_ids = ScopeIds('Bob', 'stubxblock', '123', 'import') self.xblock = StubXBlock(self.runtime, self.field_data, self.scope_ids)
def pdf_xblock(): """PDF XBlock pytest fixture.""" runtime = WorkbenchRuntime() key_store = DictKeyValueStore() db_model = KvsFieldData(key_store) ids = generate_scope_ids(runtime, 'pdf') pdf_xblock = PDFXBlock(runtime, db_model, scope_ids=ids) pdf_xblock.usage_id = Mock() return pdf_xblock
def __init__(self, data_dir, default_class=None, course_dirs=None, course_ids=None, load_error_modules=True, i18n_service=None, **kwargs): """ Initialize an XMLModuleStore from data_dir data_dir: path to data directory containing the course directories default_class: dot-separated string defining the default descriptor class to use if none is specified in entry_points course_dirs or course_ids: If specified, the list of course_dirs or course_ids to load. Otherwise, load all courses. Note, providing both """ super(XMLModuleStore, self).__init__(**kwargs) self.data_dir = path(data_dir) self.modules = defaultdict( dict) # course_id -> dict(location -> XBlock) self.courses = {} # course_dir -> XBlock for the course self.errored_courses = { } # course_dir -> errorlog, for dirs that failed to load self.load_error_modules = load_error_modules if default_class is None: self.default_class = None else: module_path, _, class_name = default_class.rpartition('.') class_ = getattr(import_module(module_path), class_name) self.default_class = class_ self.parent_trackers = defaultdict(ParentTracker) self.reference_type = Location # All field data will be stored in an inheriting field data. self.field_data = inheriting_field_data(kvs=DictKeyValueStore()) self.i18n_service = i18n_service # If we are specifically asked for missing courses, that should # be an error. If we are asked for "all" courses, find the ones # that have a course.xml. We sort the dirs in alpha order so we always # read things in the same order (OS differences in load order have # bitten us in the past.) if course_dirs is None: course_dirs = sorted([ d for d in os.listdir(self.data_dir) if os.path.exists(self.data_dir / d / "course.xml") ]) for course_dir in course_dirs: self.try_load_course(course_dir, course_ids)
def get_runtime_system_params(self): """ Get the XBlockRuntimeSystem parameters appropriate for viewing and/or editing XBlock content in Studio """ return dict( authored_data_store=BlockstoreFieldData(), student_data_store=KvsFieldData(kvs=DictKeyValueStore()), )
def feedback_xblock(): """Feedback XBlock pytest fixture.""" runtime = WorkbenchRuntime() key_store = DictKeyValueStore() db_model = KvsFieldData(key_store) ids = generate_scope_ids(runtime, 'feedback') feedback_xblock = FeedbackXBlock(runtime, db_model, scope_ids=ids) feedback_xblock.usage_id = Mock() return feedback_xblock
def test_invideoquiz_model(): """Tests for the default fields value of invideoquiz""" key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = Runtime(services={'field-data': field_data}) instance = InVideoQuizXBlock(runtime, scope_ids=Mock()) assert instance.display_name == 'In-Video Quiz XBlock' assert instance.timemap == '{}' assert instance.video_id == ''
def setUp(self): """ Create a stub XBlock backed by in-memory storage. """ self.runtime = mock.MagicMock(Runtime) self.field_data = KvsFieldData(kvs=DictKeyValueStore()) self.scope_ids = ScopeIds('Bob', 'stubxblock', '123', 'import') self.xblock = StubXBlock(self.runtime, self.field_data, self.scope_ids) super(RemapNamespaceTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
def make_block(): """ Instantiate a DragAndDropBlock XBlock inside a WorkbenchRuntime """ block_type = 'drag_and_drop_v2' key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = WorkbenchRuntime() def_id = runtime.id_generator.create_definition(block_type) usage_id = runtime.id_generator.create_usage(def_id) scope_ids = ScopeIds('user', block_type, def_id, usage_id) return drag_and_drop_v2.DragAndDropBlock(runtime, field_data, scope_ids=scope_ids)
def setUp(self): block_type = 'hastexo' key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = WorkbenchRuntime() def_id = runtime.id_generator.create_definition(block_type) usage_id = runtime.id_generator.create_usage(def_id) scope_ids = ScopeIds('user', block_type, def_id, usage_id) self.block = HastexoXBlock(runtime, field_data, scope_ids=scope_ids)
def make_xblock(self, **kwargs): key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = TestRuntime(services={'field-data': field_data}) xblock = WistiaVideoXBlock(runtime, scope_ids=Mock()) for attr, val in kwargs.items(): setattr(xblock, attr, val) return xblock
def setUp(self): super(InheritingFieldDataTest, self).setUp() self.dummy_course_key = CourseLocator('test_org', 'test_123', 'test_run') self.system = get_test_descriptor_system() self.all_blocks = {} self.system.get_block = self.all_blocks.get self.field_data = InheritingFieldData( inheritable_names=['inherited'], kvs=DictKeyValueStore({}), )
def _prepare_asides(self, scope_ids): """ Return list with connected aside xblocks """ key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) aside = AsideTest(scope_ids=scope_ids, runtime=TestRuntime(services={'field-data': field_data})) # pylint: disable=abstract-class-instantiated aside.fields[self.ASIDE_DATA_FIELD.field_name].write_to(aside, self.ASIDE_DATA_FIELD.initial) return [aside]
def get_user_state_kvs(): """ Get the key-value store used by the XBlock runtime's SplitFieldData class to hold user state. This user state is not persisted anywhere. """ # pylint: disable=protected-access if not hasattr(get_user_state_kvs, '_kvs'): get_user_state_kvs._kvs = DictKeyValueStore() return get_user_state_kvs._kvs
def make_block(self): block_type = 'diagnostic_feedback' key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = WorkbenchRuntime() def_id = runtime.id_generator.create_definition(block_type) usage_id = runtime.id_generator.create_usage(def_id) scope_ids = ScopeIds('user', block_type, def_id, usage_id) return diagnostic_feedback.QuizBlock(runtime, field_data, scope_ids=scope_ids)
def setUp(self): field_data = KvsFieldData(DictKeyValueStore()) runtime = TestRuntime(services={ 'settings': MockService(OoyalaPlayerBlock, self.XBLOCK_SETTINGS) }) self.player = OoyalaPlayerBlock(runtime, field_data, scope_ids=Mock(spec=ScopeIds)) self.player.DEFAULT_ATTRIBUTE_SETTINGS = { self.REAL_ATTRIBUTE: self.DEFAULT_SETTING_NAME }
def test_view_counter_state(): key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = Runtime(services={'field-data': field_data}) tester = ViewCounter(runtime, scope_ids=Mock()) assert tester.views == 0 # View the XBlock five times for i in range(5): generated_html = tester.student_view({}) # Make sure the html fragment we're expecting appears in the body_html assert f'<span class="views">{i + 1}</span>' in generated_html.body_html() assert tester.views == (i + 1)
def test_aside_contains_tags(self): """ Checks that available_tags list is not empty """ sids = ScopeIds(user_id="bob", block_type="bobs-type", def_id="definition-id", usage_id="usage-id") key_store = DictKeyValueStore() field_data = KvsFieldData(key_store) runtime = TestRuntime(services={'field-data': field_data}) # pylint: disable=abstract-class-instantiated xblock_aside = StructuredTagsAside(scope_ids=sids, runtime=runtime) available_tags = xblock_aside.get_available_tags() self.assertEquals(len(available_tags), 2, "StructuredTagsAside should contains two tag categories")
def test_view_counter_state(): key_store = DictKeyValueStore() db_model = KvsFieldData(key_store) tester = ViewCounter(Mock(), db_model, Mock()) assert_equals(tester.views, 0) # View the XBlock five times for i in xrange(5): generated_html = tester.student_view({}) # Make sure the html fragment we're expecting appears in the body_html assert_in('<span class="views">{0}</span>'.format(i + 1), generated_html.body_html()) assert_equals(tester.views, i + 1)
def setUp(self): """ Create a stub XBlock backed by in-memory storage. """ self.runtime = mock.MagicMock(Runtime) self.field_data = KvsFieldData(kvs=DictKeyValueStore()) self.scope_ids = ScopeIds('Bob', 'mutablestubxblock', '123', 'import') self.xblock = StubXBlockWithMutableFields(self.runtime, self.field_data, self.scope_ids) self.fake_children_locations = [ BlockUsageLocator(CourseLocator('org', 'course', 'run'), 'mutablestubxblock', 'child1'), BlockUsageLocator(CourseLocator('org', 'course', 'run'), 'mutablestubxblock', 'child2'), ] super(UpdateLocationTest, self).setUp()
def __init__(self, load_error_modules): xmlstore = XMLModuleStore("data_dir", source_dirs=[], load_error_modules=load_error_modules) course_id = CourseKey.from_string('/'.join([ORG, COURSE, 'test_run'])) course_dir = "test_dir" error_tracker = Mock() super(DummySystem, self).__init__( xmlstore=xmlstore, course_id=course_id, course_dir=course_dir, error_tracker=error_tracker, load_error_modules=load_error_modules, field_data=KvsFieldData(DictKeyValueStore()), )
def make_xblock(xblock_name, xblock_cls, attributes): """ Helper to construct XBlock objects """ runtime = WorkbenchRuntime() key_store = DictKeyValueStore() db_model = KvsFieldData(key_store) ids = generate_scope_ids(runtime, xblock_name) xblock = xblock_cls(runtime, db_model, scope_ids=ids) xblock.category = Mock() xblock.location = Mock(html_id=Mock(return_value='sample_element_id'), ) xblock.runtime = Mock(hostname='localhost', ) xblock.course_id = 'course-v1:edX+DemoX+Demo_Course' for key, value in attributes.items(): setattr(xblock, key, value) return xblock