def setUp(self):
     self.content = Mock()
     self.settings = Mock()
     self.split = SplitFieldData({
         Scope.content: self.content,
         Scope.settings: self.settings
     })
     self.runtime = TestRuntime(services={'field-data': self.split})
     self.block = TestingBlock(
         runtime=self.runtime,
         scope_ids=Mock(),
     )
Beispiel #2
0
 def setUp(self):
     self.content = Mock()
     self.settings = Mock()
     self.split = SplitFieldData({
         Scope.content: self.content,
         Scope.settings: self.settings
     })
     self.block = TestingBlock(
         runtime=Mock(),
         field_data=self.split,
         scope_ids=Mock(),
     )
Beispiel #3
0
 def setup_method(self):
     """
     Setup for each test case in this class.
     """
     self.content = Mock()
     self.settings = Mock()
     self.split = SplitFieldData({
         Scope.content: self.content,
         Scope.settings: self.settings
     })
     self.runtime = TestRuntime(services={'field-data': self.split})
     self.block = TestingBlock(
         runtime=self.runtime,
         scope_ids=Mock(),
     )
 def setUp(self):
     self.content = Mock()
     self.settings = Mock()
     self.split = SplitFieldData({
         Scope.content: self.content,
         Scope.settings: self.settings
     })
     self.block = TestingBlock(
         runtime=Mock(),
         field_data=self.split,
         scope_ids=Mock(),
     )
Beispiel #5
0
 def setUp(self):
     self.content = Mock()
     self.settings = Mock()
     self.split = SplitFieldData({
         Scope.content: self.content,
         Scope.settings: self.settings
     })
     self.runtime = TestRuntime(services={'field-data': self.split})
     self.block = TestingBlock(
         runtime=self.runtime,
         scope_ids=Mock(),
     )
Beispiel #6
0
 def setup_method(self):
     """
     Setup for each test case in this class.
     """
     self.content = Mock()
     self.settings = Mock()
     self.split = SplitFieldData({
         Scope.content: self.content,
         Scope.settings: self.settings
     })
     self.runtime = TestRuntime(services={'field-data': self.split})
     self.block = TestingBlock(
         runtime=self.runtime,
         scope_ids=Mock(),
     )
Beispiel #7
0
    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,
        })
Beispiel #8
0
    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:
            # This is an anonymous (non-registered) user:
            assert self.user_id.startswith("anon")
            kvs = EphemeralKeyValueStore()
            student_data_store = KvsFieldData(kvs)
        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.
            kvs = EphemeralKeyValueStore()
            student_data_store = KvsFieldData(kvs)
        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.children_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,
        })
Beispiel #9
0
    def __init__(
            self,
            handler_url,  # type: (Callable[[XBlock, string, string, string, bool], string]
            authored_data_kvs,  # type: KeyValueStore
            student_data_kvs,  # type: KeyValueStore
            runtime_class,  # type: XBlockRuntime
    ):
        """
        args:
            handler_url: A method that implements the XBlock runtime
                handler_url interface.
            authored_data_kvs: An KeyValueStore used to retrieve
                any fields with UserScope.NONE
            student_data_kvs: An KeyValueStore used to retrieve
                any fields with UserScope.ONE or UserScope.ALL
        """
        self.handler_url = handler_url
        # TODO: new ID manager:
        self.id_reader = OpaqueKeyReader()
        self.id_generator = MemoryIdManager(
        )  # We don't really use id_generator until we need to support asides
        self.runtime_class = runtime_class

        # Field data storage/retrieval:
        authored_data = KvsFieldData(kvs=authored_data_kvs)
        student_data = KvsFieldData(kvs=student_data_kvs)
        #if authored_data_readonly:
        #    authored_data = ReadOnlyFieldData(authored_data)

        self.field_data = SplitFieldData({
            Scope.content: authored_data,
            Scope.settings: authored_data,
            Scope.parent: authored_data,
            Scope.children: authored_data,
            Scope.user_state_summary: student_data,
            Scope.user_state: student_data,
            Scope.user_info: student_data,
            Scope.preferences: student_data,
        })

        self._error_trackers = {}
Beispiel #10
0
    def __init__(
            self,
            handler_url,  # type: (Callable[[UsageKey, str, Union[int, ANONYMOUS_USER]], str]
            authored_data_store,  # type: FieldData
            student_data_store,  # type: FieldData
            runtime_class,  # type: XBlockRuntime
    ):
        """
        args:
            handler_url: A method to get URLs to call XBlock handlers. It must
                implement this signature:
                handler_url(
                    usage_key: UsageKey,
                    handler_name: str,
                    user_id: Union[int, ANONYMOUS_USER],
                )
                If user_id is ANONYMOUS_USER, the handler should execute without
                any user-scoped fields.
            authored_data_store: A FieldData instance used to retrieve/write
                any fields with UserScope.NONE
            student_data_store: A FieldData instance used to retrieve/write
                any fields with UserScope.ONE or UserScope.ALL
        """
        self.handler_url = handler_url
        self.id_reader = OpaqueKeyReader()
        self.id_generator = MemoryIdManager(
        )  # We don't really use id_generator until we need to support asides
        self.runtime_class = runtime_class
        self.authored_data_store = authored_data_store
        self.field_data = SplitFieldData({
            Scope.content: authored_data_store,
            Scope.settings: authored_data_store,
            Scope.parent: authored_data_store,
            Scope.children: 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,
        })

        self._error_trackers = {}
Beispiel #11
0
class TestSplitFieldData:
    """
    Tests of :ref:`SplitFieldData`.
    """

    # pylint: disable=attribute-defined-outside-init
    def setup_method(self):
        """
        Setup for each test case in this class.
        """
        self.content = Mock()
        self.settings = Mock()
        self.split = SplitFieldData({
            Scope.content: self.content,
            Scope.settings: self.settings
        })
        self.runtime = TestRuntime(services={'field-data': self.split})
        self.block = TestingBlock(
            runtime=self.runtime,
            scope_ids=Mock(),
        )

    # pylint: enable=attribute-defined-outside-init

    def test_get(self):
        self.split.get(self.block, 'content')
        self.content.get.assert_called_once_with(self.block, 'content')
        assert not self.settings.get.called

    def test_set(self):
        self.split.set(self.block, 'content', 'foo')
        self.content.set.assert_called_once_with(self.block, 'content', 'foo')
        assert not self.settings.set.called

    def test_delete(self):
        self.split.delete(self.block, 'content')
        self.content.delete.assert_called_once_with(self.block, 'content')
        assert not self.settings.delete.called

    def test_has(self):
        self.split.has(self.block, 'content')
        self.content.has.assert_called_once_with(self.block, 'content')
        assert not self.settings.has.called

    def test_set_many(self):
        self.split.set_many(self.block, {
            'content': 'new content',
            'settings': 'new settings'
        })
        self.content.set_many.assert_called_once_with(
            self.block, {'content': 'new content'})
        self.settings.set_many.assert_called_once_with(
            self.block, {'settings': 'new settings'})

    def test_invalid_scope(self):
        with pytest.raises(InvalidScopeError):
            self.split.get(self.block, 'user_state')

    def test_default(self):
        self.split.default(self.block, 'content')
        self.content.default.assert_called_once_with(self.block, 'content')
        assert not self.settings.default.called
Beispiel #12
0
class TestSplitFieldData(object):
    """
    Tests of :ref:`SplitFieldData`.
    """
    def setUp(self):
        self.content = Mock()
        self.settings = Mock()
        self.split = SplitFieldData({
            Scope.content: self.content,
            Scope.settings: self.settings
        })
        self.block = TestingBlock(
            runtime=Mock(),
            field_data=self.split,
            scope_ids=Mock(),
        )

    def test_get(self):
        self.split.get(self.block, 'content')
        self.content.get.assert_called_once_with(self.block, 'content')
        assert_false(self.settings.get.called)

    def test_set(self):
        self.split.set(self.block, 'content', 'foo')
        self.content.set.assert_called_once_with(self.block, 'content', 'foo')
        assert_false(self.settings.set.called)

    def test_delete(self):
        self.split.delete(self.block, 'content')
        self.content.delete.assert_called_once_with(self.block, 'content')
        assert_false(self.settings.delete.called)

    def test_has(self):
        self.split.has(self.block, 'content')
        self.content.has.assert_called_once_with(self.block, 'content')
        assert_false(self.settings.has.called)

    def test_set_many(self):
        self.split.set_many(self.block, {'content': 'new content', 'settings': 'new settings'})
        self.content.set_many.assert_called_once_with(self.block, {'content': 'new content'})
        self.settings.set_many.assert_called_once_with(self.block, {'settings': 'new settings'})

    def test_invalid_scope(self):
        with assert_raises(InvalidScopeError):
            self.split.get(self.block, 'user_state')

    def test_default(self):
        self.split.default(self.block, 'content')
        self.content.default.assert_called_once_with(self.block, 'content')
        assert_false(self.settings.default.called)
Beispiel #13
0
class TestSplitFieldData(object):
    """
    Tests of :ref:`SplitFieldData`.
    """
    def setUp(self):
        self.content = Mock()
        self.settings = Mock()
        self.split = SplitFieldData({
            Scope.content: self.content,
            Scope.settings: self.settings
        })
        self.block = TestingBlock(
            runtime=Mock(),
            field_data=self.split,
            scope_ids=Mock(),
        )

    def test_get(self):
        self.split.get(self.block, 'content')
        self.content.get.assert_called_once_with(self.block, 'content')
        assert_false(self.settings.get.called)

    def test_set(self):
        self.split.set(self.block, 'content', 'foo')
        self.content.set.assert_called_once_with(self.block, 'content', 'foo')
        assert_false(self.settings.set.called)

    def test_delete(self):
        self.split.delete(self.block, 'content')
        self.content.delete.assert_called_once_with(self.block, 'content')
        assert_false(self.settings.delete.called)

    def test_has(self):
        self.split.has(self.block, 'content')
        self.content.has.assert_called_once_with(self.block, 'content')
        assert_false(self.settings.has.called)

    def test_set_many(self):
        self.split.set_many(self.block, {
            'content': 'new content',
            'settings': 'new settings'
        })
        self.content.set_many.assert_called_once_with(
            self.block, {'content': 'new content'})
        self.settings.set_many.assert_called_once_with(
            self.block, {'settings': 'new settings'})

    def test_invalid_scope(self):
        with assert_raises(InvalidScopeError):
            self.split.get(self.block, 'user_state')

    def test_default(self):
        self.split.default(self.block, 'content')
        self.content.default.assert_called_once_with(self.block, 'content')
        assert_false(self.settings.default.called)
Beispiel #14
0
class TestSplitFieldData(object):
    """
    Tests of :ref:`SplitFieldData`.
    """
    # pylint: disable=attribute-defined-outside-init
    def setup_method(self):
        """
        Setup for each test case in this class.
        """
        self.content = Mock()
        self.settings = Mock()
        self.split = SplitFieldData({
            Scope.content: self.content,
            Scope.settings: self.settings
        })
        self.runtime = TestRuntime(services={'field-data': self.split})
        self.block = TestingBlock(
            runtime=self.runtime,
            scope_ids=Mock(),
        )
    # pylint: enable=attribute-defined-outside-init

    def test_get(self):
        self.split.get(self.block, 'content')
        self.content.get.assert_called_once_with(self.block, 'content')
        assert not self.settings.get.called

    def test_set(self):
        self.split.set(self.block, 'content', 'foo')
        self.content.set.assert_called_once_with(self.block, 'content', 'foo')
        assert not self.settings.set.called

    def test_delete(self):
        self.split.delete(self.block, 'content')
        self.content.delete.assert_called_once_with(self.block, 'content')
        assert not self.settings.delete.called

    def test_has(self):
        self.split.has(self.block, 'content')
        self.content.has.assert_called_once_with(self.block, 'content')
        assert not self.settings.has.called

    def test_set_many(self):
        self.split.set_many(self.block, {'content': 'new content', 'settings': 'new settings'})
        self.content.set_many.assert_called_once_with(self.block, {'content': 'new content'})
        self.settings.set_many.assert_called_once_with(self.block, {'settings': 'new settings'})

    def test_invalid_scope(self):
        with pytest.raises(InvalidScopeError):
            self.split.get(self.block, 'user_state')

    def test_default(self):
        self.split.default(self.block, 'content')
        self.content.default.assert_called_once_with(self.block, 'content')
        assert not self.settings.default.called