Esempio n. 1
0
def test_field_serialization():
    # Some Fields can define their own serialization mechanisms.
    # This test ensures that we are using them properly.

    class CustomField(Field):
        """
        Specifiy a custom field that defines its own serialization
        """
        def from_json(self, value):
            return value['value']

        def to_json(self, value):
            return {'value': value}

    class FieldTester(XBlock):
        """Test XBlock for field serialization testing"""
        field = CustomField()

    field_data = DictFieldData({
        'field': {'value': 4}
    })

    field_tester = FieldTester(
        TestRuntime(services={'field-data': field_data}),
        None,
        Mock(),
    )

    assert_equals(4, field_tester.field)
    field_tester.field = 5
    field_tester.save()
    assert_equals({'value': 5}, field_data.get(field_tester, 'field'))
Esempio n. 2
0
 def test_set_save_mutate_save(self):
     pointer = self.new_value
     self.set(pointer)
     self.block.save()
     self.mutate(pointer)
     self.block.save()
     assert_equals(pointer, self.field_data.get(self.block, 'field'))
Esempio n. 3
0
def test_get_mutable_mark_dirty():
    """
    Ensure that accessing a mutable field type does not mark it dirty
    if the field has never been set. If the field has been set, ensure
    that it is set to dirty.
    """
    class MutableTester(XBlock):
        """Test class with mutable fields."""
        list_field = List(default=[])

    mutable_test = MutableTester(TestRuntime(services={'field-data': DictFieldData({})}), scope_ids=Mock(spec=ScopeIds))

    # Test get/set with a default value.
    assert_equals(len(mutable_test._dirty_fields), 0)
    _test_get = mutable_test.list_field
    assert_equals(len(mutable_test._dirty_fields), 1)

    mutable_test.list_field = []
    assert_equals(len(mutable_test._dirty_fields), 1)

    # Now test after having explicitly set the field.
    mutable_test.save()
    assert_equals(len(mutable_test._dirty_fields), 0)
    _test_get = mutable_test.list_field
    assert_equals(len(mutable_test._dirty_fields), 1)
Esempio n. 4
0
    def student_view(self, _context):
        """Try out some services."""
        # i18n is available, and works.
        def assert_equals_unicode(str1, str2):
            """`str1` equals `str2`, and both are Unicode strings."""
            assert_equals(str1, str2)
            assert isinstance(str1, unicode)
            assert isinstance(str2, unicode)

        i18n = self.runtime.service(self, "i18n")
        assert_equals_unicode(u"Welcome!", i18n.ugettext("Welcome!"))

        assert_equals_unicode(u"Plural", i18n.ungettext("Singular", "Plural", 0))
        assert_equals_unicode(u"Singular", i18n.ungettext("Singular", "Plural", 1))
        assert_equals_unicode(u"Plural", i18n.ungettext("Singular", "Plural", 2))

        # secret_service is available.
        assert_equals(self.runtime.service(self, "secret_service"), 17)

        # no_such_service is not available, and raises an exception, because we
        # said we needed it.
        with assert_raises(NoSuchServiceError):
            self.runtime.service(self, "no_such_service")

        # another_not_service is not available, and returns None, because we
        # didn't need it, we only wanted it.
        assert_is(self.runtime.service(self, "another_not_service"), None)
Esempio n. 5
0
def test_scope_key():
    # Tests field display name default values
    class TestBlock(XBlock):
        """
        Block for testing
        """
        field_x = List(scope=Scope.settings, name='')
        settings_lst = List(scope=Scope.settings, name='')
        uss_lst = List(scope=Scope.user_state_summary, name='')
        user_lst = List(scope=Scope.user_state, name='')
        pref_lst = List(scope=Scope.preferences, name='')
        user_info_lst = List(scope=Scope.user_info, name='')

    sids = ScopeIds(user_id="_bob",
                    block_type="b.12#ob",
                    def_id="..",
                    usage_id="..")

    field_data = DictFieldData({})

    runtime = TestRuntime(Mock(), services={'field-data': field_data})
    block = TestBlock(runtime, None, sids)

    # Format: usage or block ID/field_name/user_id
    for item, correct_key in [[TestBlock.field_x, "__..../field__x/NONE.NONE"],
                              [TestBlock.user_info_lst, "NONE.NONE/user__info__lst/____bob"],
                              [TestBlock.pref_lst, "b..12_35_ob/pref__lst/____bob"],
                              [TestBlock.user_lst, "__..../user__lst/____bob"],
                              [TestBlock.uss_lst, "__..../uss__lst/NONE.NONE"],
                              [TestBlock.settings_lst, "__..../settings__lst/NONE.NONE"]]:
        key = scope_key(item, block)
        assert_equals(key, correct_key)
Esempio n. 6
0
def test_change_mutable_default():
    """
    Ensure that mutating the default value for a field causes
    the changes to be saved, and doesn't corrupt other instances
    """

    class MutableTester(XBlock):
        """Test class with mutable fields."""
        list_field = List()

    mutable_test_a = MutableTester(MagicMock(), DictFieldData({}), Mock())
    mutable_test_b = MutableTester(MagicMock(), DictFieldData({}), Mock())

    # Saving without changing the default value shouldn't write to _field_data
    mutable_test_a.list_field  # pylint: disable=W0104
    mutable_test_a.save()
    with assert_raises(KeyError):
        mutable_test_a._field_data.get(mutable_test_a, 'list_field')

    mutable_test_a.list_field.append(1)
    mutable_test_a.save()

    assert_equals([1], mutable_test_a._field_data.get(mutable_test_a, 'list_field'))
    with assert_raises(KeyError):
        mutable_test_b._field_data.get(mutable_test_b, 'list_field')
Esempio n. 7
0
def test_setting_the_same_value_marks_field_as_dirty():
    """
    Check that setting field to the same value marks mutable fields as dirty.
    However, since the value hasn't changed, these fields won't be saved.
    """
    class FieldTester(XBlock):
        """Test block for set - get test."""
        non_mutable = String(scope=Scope.settings)
        list_field = List(scope=Scope.settings)
        dict_field = Dict(scope=Scope.settings)

    runtime = TestRuntime(services={'field-data': DictFieldData({})})
    field_tester = FieldTester(runtime, scope_ids=Mock(spec=ScopeIds))

    # precondition checks
    assert_equals(len(field_tester._dirty_fields), 0)
    assert_false(field_tester.fields['list_field'].is_set_on(field_tester))
    assert_false(field_tester.fields['dict_field'].is_set_on(field_tester))
    assert_false(field_tester.fields['non_mutable'].is_set_on(field_tester))

    field_tester.non_mutable = field_tester.non_mutable
    field_tester.list_field = field_tester.list_field
    field_tester.dict_field = field_tester.dict_field

    assert_not_in(field_tester.fields['non_mutable'], field_tester._dirty_fields)
    assert_in(field_tester.fields['list_field'], field_tester._dirty_fields)
    assert_in(field_tester.fields['dict_field'], field_tester._dirty_fields)

    assert_false(field_tester.fields['non_mutable'].is_set_on(field_tester))
    assert_false(field_tester.fields['list_field'].is_set_on(field_tester))
    assert_false(field_tester.fields['dict_field'].is_set_on(field_tester))
Esempio n. 8
0
    def test_all_scenarios(self):
        """
        Load the home page, examine the scenarios displayed.
        """
        client = Client()
        response = client.get("/")
        assert response.status_code == 200
        html = lxml.html.fromstring(response.content)
        a_tags = list(html.xpath('//a'))

        # Load the loaded_scenarios from the classes.
        loaded_scenarios = list(scenarios.get_scenarios().values())

        # We should have an <a> tag for each scenario.
        assert_equals(len(a_tags), len(loaded_scenarios))

        # We should have at least one scenario with a vertical tag, since we use
        # empty verticals as our canary in the coal mine that something has gone
        # horribly wrong with loading the loaded_scenarios.
        assert any("<vertical_demo>" in scen.xml for scen in loaded_scenarios)

        # Since we are claiming in try_scenario that no vertical is empty, let's
        # eliminate the possibility that a scenario has an actual empty vertical.
        assert all("<vertical_demo></vertical_demo>" not in scen.xml for scen in loaded_scenarios)
        assert all("<vertical_demo/>" not in scen.xml for scen in loaded_scenarios)
Esempio n. 9
0
def test_all_scenarios():
    """Load the home page, get every URL, make a test from it."""
    client = Client()
    response = client.get("/")
    assert response.status_code == 200
    html = lxml.html.fromstring(response.content)
    a_tags = list(html.xpath('//a'))
    for a_tag in a_tags:
        yield try_scenario, a_tag.get('href'), a_tag.text

    # Load the scenarios from the classes.
    scenarios = []
    for _, cls in XBlock.load_classes():
        if hasattr(cls, "workbench_scenarios"):
            for _, xml in cls.workbench_scenarios():
                scenarios.append(xml)

    # We should have an <a> tag for each scenario.
    assert_equals(len(a_tags), len(scenarios))

    # We should have at least one scenario with a vertical tag, since we use
    # empty verticals as our canary in the coal mine that something has gone
    # horribly wrong with loading the scenarios.
    assert any("<vertical>" in xml for xml in scenarios)

    # Since we are claiming in try_scenario that no vertical is empty, let's
    # eliminate the possibility that a scenario has an actual empty vertical.
    assert all("<vertical></vertical>" not in xml for xml in scenarios)
    assert all("<vertical/>" not in xml for xml in scenarios)
Esempio n. 10
0
    def test_get_with_save_doesnt_write(self):
        initial_value = self.field_data.get(self.block, 'field')
        self.get()
        self.block.save()
        final_value = self.field_data.get(self.block, 'field')

        assert_equals(initial_value, final_value)
Esempio n. 11
0
def test_cached_parent():
    class HasParent(XBlock):
        """
        Dummy empty class
        """
        pass

    runtime = TestRuntime(services={'field-data': DictFieldData({})})
    runtime.get_block = Mock()
    block = HasParent(runtime, scope_ids=Mock(spec=ScopeIds))

    # block has no parent yet, and we don't need to call the runtime to find
    # that out.
    assert_equals(block.get_parent(), None)
    assert not runtime.get_block.called

    # Set a parent id for the block.  Get the parent.  Now we have one, and we
    # used runtime.get_block to get it.
    block.parent = "some_parent_id"
    parent = block.get_parent()
    assert_not_equals(parent, None)
    assert runtime.get_block.called_with("some_parent_id")

    # Get the parent again.  It will be the same parent, and we didn't call the
    # runtime.
    runtime.get_block.reset_mock()
    parent2 = block.get_parent()
    assert parent2 is parent
    assert not runtime.get_block.called
Esempio n. 12
0
def test_twofaced_field_access():
    # Check that a field with different to_json and from_json representations
    # persists and saves correctly.
    class TwoFacedField(Field):
        """A field that emits different 'json' than it parses."""
        def from_json(self, thestr):
            """Store an int, the length of the string parsed."""
            return len(thestr)

        def to_json(self, value):
            """Emit some number of X's."""
            return "X" * value

    class FieldTester(XBlock):
        """Test block for TwoFacedField."""
        how_many = TwoFacedField(scope=Scope.settings)

    original_json = "YYY"
    runtime = TestRuntime(services={'field-data': DictFieldData({'how_many': original_json})})
    field_tester = FieldTester(runtime, scope_ids=Mock(spec=ScopeIds))

    # Test that the native value isn't equal to the original json we specified.
    assert_not_equals(field_tester.how_many, original_json)
    # Test that the native -> json value isn't equal to the original json we specified.
    assert_not_equals(TwoFacedField().to_json(field_tester.how_many), original_json)

    # The previous accesses will mark the field as dirty (via __get__)
    assert_equals(len(field_tester._dirty_fields), 1)
    # However, the field should not ACTUALLY be marked as a field that is needing to be saved.
    assert_not_in('how_many', field_tester._get_fields_to_save())   # pylint: disable=W0212
Esempio n. 13
0
def test_values_boolean():
    # Test Boolean, which has values defined
    test_field = Boolean()
    assert_equals(
        ({'display_name': "True", "value": True}, {'display_name': "False", "value": False}),
        test_field.values
    )
Esempio n. 14
0
def test_caching_is_per_instance():
    # Test that values cached for one instance do not appear on another
    class FieldTester(ScopedStorageMixin):
        """Toy class for ModelMetaclass and field access testing"""
        field_a = List(scope=Scope.settings)

    field_data = MagicMock(spec=FieldData)
    field_data.get = lambda block, name, default=None: [name]  # pylint: disable=C0322

    # Same field_data used in different objects should result
    # in separately-cached values, so that changing a value
    # in one instance doesn't affect values stored in others.
    field_tester_a = FieldTester(
        runtime=TestRuntime(services={'field-data': field_data}),
        scope_ids=MagicMock(spec=ScopeIds)
    )
    field_tester_b = FieldTester(
        runtime=TestRuntime(services={'field-data': field_data}),
        scope_ids=MagicMock(spec=ScopeIds)
    )
    value = field_tester_a.field_a
    assert_equals(value, field_tester_a.field_a)
    field_tester_a.field_a.append(1)
    assert_equals(value, field_tester_a.field_a)
    assert_not_equals(value, field_tester_b.field_a)
Esempio n. 15
0
    def student_view(self, _context):
        """Try out some services."""
        # i18n is available, and works.
        def assert_equals_unicode(str1, str2):
            """`str1` equals `str2`, and both are Unicode strings."""
            assert_equals(str1, str2)
            assert isinstance(str1, unicode)
            assert isinstance(str2, unicode)

        i18n = self.runtime.service(self, "i18n")
        assert_equals_unicode(u"Welcome!", i18n.ugettext("Welcome!"))

        assert_equals_unicode(u"Plural", i18n.ungettext("Singular", "Plural", 0))
        assert_equals_unicode(u"Singular", i18n.ungettext("Singular", "Plural", 1))
        assert_equals_unicode(u"Plural", i18n.ungettext("Singular", "Plural", 2))

        when = datetime(2013, 2, 14, 22, 30, 17)
        assert_equals_unicode(u"2013-02-14", i18n.strftime(when, "%Y-%m-%d"))
        assert_equals_unicode(u"Feb 14, 2013", i18n.strftime(when, "SHORT_DATE"))
        assert_equals_unicode(u"Thursday, February 14, 2013", i18n.strftime(when, "LONG_DATE"))
        assert_equals_unicode(u"Feb 14, 2013 at 22:30", i18n.strftime(when, "DATE_TIME"))
        assert_equals_unicode(u"10:30:17 PM", i18n.strftime(when, "TIME"))

        # secret_service is available.
        assert_equals(self.runtime.service(self, "secret_service"), 17)

        # no_such_service is not available, and raises an exception, because we
        # said we needed it.
        with assert_raises_regexp(NoSuchServiceError, "is not available"):
            self.runtime.service(self, "no_such_service")

        # another_not_service is not available, and returns None, because we
        # didn't need it, we only wanted it.
        assert_is(self.runtime.service(self, "another_not_service"), None)
Esempio n. 16
0
def test_mutable_none_values():
    # Check that fields with values intentionally set to None
    # save properly.
    class FieldTester(XBlock):
        """Test XBlock for field access testing"""
        field_a = List(scope=Scope.settings)
        field_b = List(scope=Scope.settings)
        field_c = List(scope=Scope.content, default=None)

    field_tester = FieldTester(
        TestRuntime(services={'field-data': DictFieldData({'field_a': None})}),
        scope_ids=Mock(spec=ScopeIds)
    )
    # Set fields b & c to None
    field_tester.field_b = None
    field_tester.field_c = None
    # Save our changes
    field_tester.save()

    # Access the fields without modifying them. Want to call `__get__`, not `__set__`,
    # because `__get__` marks only mutable fields as dirty.
    _test_get = field_tester.field_a
    _test_get = field_tester.field_b
    _test_get = field_tester.field_c

    # The previous accesses will mark the fields as dirty (via __get__)
    assert_equals(len(field_tester._dirty_fields), 3)  # pylint: disable=W0212

    # However, the fields should not ACTUALLY be marked as fields that need to be saved.
    assert_equals(len(field_tester._get_fields_to_save()), 0)  # pylint: disable=W0212
Esempio n. 17
0
def test_change_mutable_default():
    """
    Ensure that mutating the default value for a field causes
    the changes to be saved, and doesn't corrupt other instances
    """

    class MutableTester(XBlock):
        """Test class with mutable fields."""
        list_field = List()

    field_data_a = DictFieldData({})
    mutable_test_a = MutableTester(TestRuntime(services={'field-data': field_data_a}), scope_ids=Mock(spec=ScopeIds))
    field_data_b = DictFieldData({})
    mutable_test_b = MutableTester(TestRuntime(services={'field-data': field_data_b}), scope_ids=Mock(spec=ScopeIds))

    # Saving without changing the default value shouldn't write to field_data
    mutable_test_a.list_field  # pylint: disable=W0104
    mutable_test_a.save()
    with assert_raises(KeyError):
        field_data_a.get(mutable_test_a, 'list_field')

    mutable_test_a.list_field.append(1)
    mutable_test_a.save()

    assert_equals([1], field_data_a.get(mutable_test_a, 'list_field'))
    with assert_raises(KeyError):
        field_data_b.get(mutable_test_b, 'list_field')
Esempio n. 18
0
 def send_it_back_public(self, request, suffix=""):
     """Just return the data we got."""
     assert_equals(self.scope_ids.user_id, "none")
     response_json = json.dumps(
         {"suffix": suffix, "a": request.GET.get("a", "no-a"), "b": request.GET.get("b", "no-b")}
     )
     return Response(response_json, content_type="application/json")
Esempio n. 19
0
def test_cached_parent():
    class HasParent(XBlock):
        pass

    runtime = Mock()
    block = HasParent(runtime, DictFieldData({}), Mock())

    # block has no parent yet, and we don't need to call the runtime to find
    # that out.
    assert_equals(block.get_parent(), None)
    assert not runtime.get_block.called

    # Set a parent id for the block.  Get the parent.  Now we have one, and we
    # used runtime.get_block to get it.
    block.parent = "some_parent_id"
    parent = block.get_parent()
    assert_not_equals(parent, None)
    assert runtime.get_block.called_with("some_parent_id")

    # Get the parent again.  It will be the same parent, and we didn't call the
    # runtime.
    runtime.reset_mock()
    parent2 = block.get_parent()
    assert parent2 is parent
    assert not runtime.get_block.called
Esempio n. 20
0
def test_caching_is_per_instance():
    # Test that values cached for one instance do not appear on another
    class FieldTester(object):
        """Toy class for ModelMetaclass and field access testing"""
        __metaclass__ = ModelMetaclass

        field_a = List(scope=Scope.settings)

        def __init__(self, field_data):
            self._field_data = field_data
            self._dirty_fields = {}

    field_data = MagicMock(spec=FieldData)
    field_data.get = lambda block, name, default=None: [name]  # pylint: disable=C0322

    # Same field_data used in different objects should result
    # in separately-cached values, so that changing a value
    # in one instance doesn't affect values stored in others.
    field_tester_a = FieldTester(field_data)
    field_tester_b = FieldTester(field_data)
    value = field_tester_a.field_a
    assert_equals(value, field_tester_a.field_a)
    field_tester_a.field_a.append(1)
    assert_equals(value, field_tester_a.field_a)
    assert_not_equals(value, field_tester_b.field_a)
Esempio n. 21
0
def test_children_metaclass():

    class HasChildren(object):
        """Toy class for ChildrenModelMetaclass testing"""
        __metaclass__ = ChildrenModelMetaclass

        has_children = True

    class WithoutChildren(object):
        """Toy class for ChildrenModelMetaclass testing"""
        __metaclass__ = ChildrenModelMetaclass

    class InheritedChildren(HasChildren):
        """Toy class for ChildrenModelMetaclass testing"""
        pass

    # `HasChildren` and `WithoutChildren` both obtain the `children` attribute and
    # the `has_children` method from the `ChildrenModelMetaclass`. Since this is not
    # understood by static analysis, silence this error for the duration of this test.
    # pylint: disable=E1101

    assert HasChildren.has_children
    assert not WithoutChildren.has_children
    assert InheritedChildren.has_children

    assert hasattr(HasChildren, 'children')
    assert not hasattr(WithoutChildren, 'children')
    assert hasattr(InheritedChildren, 'children')

    assert isinstance(HasChildren.children, List)
    assert_equals(Scope.children, HasChildren.children.scope)
    assert isinstance(InheritedChildren.children, List)
    assert_equals(Scope.children, InheritedChildren.children.scope)
Esempio n. 22
0
 def test_set(self):
     self.block.field_b = set([5, 6, 5])
     self.block.save()
     assert_is_instance(self.block.field_b, set)
     assert_equals(
         {'$type': 'set', '$vals': [5, 6]},
         self.block._field_data.get(self.block, 'field_b')
     )
Esempio n. 23
0
def test_xblock_invalid_handler_url():
    # Test that providing an invalid handler url will give a 404
    # when we try to hit a handler on it
    client = Client()

    handler_url = "/handler/obviously/a/fake/handler"
    result = client.post(handler_url, "{}", "text/json")
    assert_equals(result.status_code, 404)
Esempio n. 24
0
    def test_delete(self):
        assert_equals(1, self.agg.first)
        del self.agg.first
        assert_false(hasattr(self.first, 'first'))
        with assert_raises(AttributeError):
            self.agg.first  # pylint: disable=W0104

        with assert_raises(AttributeError):
            del self.agg.other
Esempio n. 25
0
def test_dummy_user_service_current_user():
    """
    Tests that get_current_user() works on a dummy user service.
    """
    user = XBlockUser(username="******")
    user_service = SingleUserService(user)
    current_user = user_service.get_current_user()
    assert_equals(current_user, user)
    assert_equals(current_user.username, "tester")
Esempio n. 26
0
 def send_it_back_public(self, request, suffix=''):
     """Just return the data we got."""
     assert_equals(self.scope_ids.user_id, "none")
     response_json = json.dumps({
         'suffix': suffix,
         'a': request.GET.get('a', "no-a"),
         'b': request.GET.get('b', "no-b"),
     })
     return Response(response_json, content_type='application/json')
Esempio n. 27
0
def test_json_handler_return_unicode():
    test_request = Mock(method="POST", body='["foo", "bar"]')

    @XBlock.json_handler
    def test_func(self, request, suffix):  # pylint: disable=unused-argument
        return Response(request=request)

    response = test_func(Mock(), test_request, "dummy_suffix")
    for request_part in response.request:
        assert_equals(type(request_part), unicode)
Esempio n. 28
0
    def test_mutate_pointer_after_save(self):
        pointer = self.get()
        self.mutate(pointer)
        self.block.save()
        assert_equals(pointer, self.field_data.get(self.block, 'field'))

        # now check what happens when we mutate a field
        # that we haven't retrieved through __get__
        # (which would have marked it as dirty)
        self.mutate(pointer)
        self.block.save()
        assert_equals(pointer, self.field_data.get(self.block, 'field'))
Esempio n. 29
0
    def test_mutation_without_save_doesnt_write(self):
        initial_value = self.field_data.get(self.block, 'field')
        reference_copy = copy.deepcopy(initial_value)

        mutable = self.get()
        self.mutate(mutable)

        # Verify that the test isn't vacuously true
        assert_not_equals(reference_copy, mutable)

        final_value = self.field_data.get(self.block, 'field')
        assert_equals(reference_copy, final_value)
        assert_equals(initial_value, final_value)
Esempio n. 30
0
    def test_set_save_get_mutate_save(self):
        reference_value = copy.deepcopy(self.new_value)
        self.mutate(reference_value)

        # Verify that the test isn't vacuously true
        assert_not_equals(self.new_value, reference_value)

        self.set(copy.deepcopy(self.new_value))
        self.block.save()
        self.mutate(self.get())
        self.block.save()
        final_value = self.field_data.get(self.block, 'field')
        assert_equals(reference_value, final_value)
Esempio n. 31
0
def test_object_identity():
    # Check that values that are modified are what is returned
    class FieldTester(object):
        """Toy class for ModelMetaclass and field access testing"""
        __metaclass__ = ModelMetaclass

        field_a = List(scope=Scope.settings)

        def __init__(self, field_data):
            self._field_data = field_data
            self._dirty_fields = {}

    # Make sure that field_data always returns a different object
    # each time it's actually queried, so that the caching is
    # doing the work to maintain object identity.
    field_data = MagicMock(spec=FieldData)
    field_data.get = lambda block, name, default=None: [name]  # pylint: disable=C0322
    field_tester = FieldTester(field_data)

    value = field_tester.field_a
    assert_equals(value, field_tester.field_a)

    # Changing the field in place matches a previously fetched value
    field_tester.field_a.append(1)
    assert_equals(value, field_tester.field_a)

    # Changing the previously-fetched value also changes the value returned by the field:
    value.append(2)
    assert_equals(value, field_tester.field_a)

    # Deletion restores the default value.  In the case of a List with
    # no default defined, this is the empty list.
    del field_tester.field_a
    assert_equals([], field_tester.field_a)
Esempio n. 32
0
    def test_multiply_mixed(self):
        mixalot = Mixologist([ThirdMixin, FirstMixin])

        pre_mixed = mixalot.mix(self.mixologist.mix(FieldTester))
        post_mixed = self.mixologist.mix(mixalot.mix(FieldTester))

        assert_is(pre_mixed.fields['field'], FirstMixin.field)
        assert_is(post_mixed.fields['field'], ThirdMixin.field)

        assert_is(FieldTester, pre_mixed.unmixed_class)
        assert_is(FieldTester, post_mixed.unmixed_class)

        assert_equals(4, len(
            pre_mixed.__bases__))  # 1 for the original class + 3 mixin classes
        assert_equals(4, len(post_mixed.__bases__))
Esempio n. 33
0
def test_dummy_user_service_current_user():
    """
    Tests that get_current_user() works on a dummy user service.
    """
    user = XBlockUser(full_name="tester")
    user_service = SingleUserService(user)
    current_user = user_service.get_current_user()
    assert_equals(current_user, user)
    assert_equals(current_user.full_name, "tester")
    # assert that emails is an Iterable but not a string
    assert_is_instance(current_user.emails, collections.Iterable)
    assert_false(
        isinstance(current_user.emails, (six.text_type, six.binary_type)))
    # assert that opt_attrs is a Mapping
    assert_is_instance(current_user.opt_attrs, collections.Mapping)
Esempio n. 34
0
def test_set_incomparable_fields():
    # if we can't compare a field's value to the value it's going to be reset to
    # (i.e. timezone aware and unaware datetimes), just reset the value.

    class FieldTester(XBlock):
        """Test block for this test."""
        incomparable = Field(scope=Scope.settings)

    not_timezone_aware = dt.datetime(2015, 1, 1)
    timezone_aware = dt.datetime(2015, 1, 1, tzinfo=pytz.UTC)
    runtime = TestRuntime(services={'field-data': DictFieldData({})})
    field_tester = FieldTester(runtime, scope_ids=Mock(spec=ScopeIds))
    field_tester.incomparable = not_timezone_aware
    field_tester.incomparable = timezone_aware
    assert_equals(field_tester.incomparable, timezone_aware)
Esempio n. 35
0
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_equals(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_in('<span class="views">{0}</span>'.format(i + 1),
                  generated_html.body_html())
        assert_equals(tester.views, i + 1)
Esempio n. 36
0
    def test_mutation_with_save_writes(self):
        assert_false(self.field_data.has(self.block, 'field'))

        mutable = self.get()
        reference_copy = copy.deepcopy(mutable)
        self.mutate(reference_copy)

        # Verify that the test isn't vacuously true
        assert_not_equals(mutable, reference_copy)

        self.mutate(mutable)
        self.block.save()

        final_value = self.field_data.get(self.block, 'field')
        assert_equals(reference_copy, final_value)
Esempio n. 37
0
def test_ugettext_calls():
    """
    Test ugettext calls in xblock.
    """
    runtime = TestRuntime()
    block = XBlockWithServices(runtime, scope_ids=Mock(spec=[]))
    assert_equals(block.ugettext('test'), u'test')
    assert_true(isinstance(block.ugettext('test'), unicode))

    # NoSuchServiceError exception should raise if i18n is none/empty.
    runtime = TestRuntime(services={
        'i18n': None
    })
    block = XBlockWithServices(runtime, scope_ids=Mock(spec=[]))
    with assert_raises(NoSuchServiceError):
        block.ugettext('test')
Esempio n. 38
0
def test_services_decorators_with_inheritance():
    @XBlock.needs("n1")
    @XBlock.wants("w1")
    class ServiceUsingBlock(XBlock):
        """XBlock using some services."""
        pass

    @XBlock.needs("n2")
    @XBlock.wants("w2")
    class SubServiceUsingBlock(ServiceUsingBlock):
        """Does this class properly inherit services from ServiceUsingBlock?"""
        pass

    sub_service_using_block = SubServiceUsingBlock(None, scope_ids=None)
    assert_equals(sub_service_using_block.service_declaration("n1"), "need")
    assert_equals(sub_service_using_block.service_declaration("w1"), "want")
    assert_equals(sub_service_using_block.service_declaration("n2"), "need")
    assert_equals(sub_service_using_block.service_declaration("w2"), "want")
    assert_equals(sub_service_using_block.service_declaration("xx"), None)
Esempio n. 39
0
def test_loading_tagged_classes():

    @XBlock.tag("thetag")
    class HasTag1(XBlock):
        """Toy XBlock"""
        pass

    class HasTag2(HasTag1):
        """Toy XBlock"""
        pass

    class HasntTag(XBlock):
        """Toy XBlock"""
        pass

    the_classes = [('hastag1', HasTag1), ('hastag2', HasTag2), ('hasnttag', HasntTag)]
    tagged_classes = [('hastag1', HasTag1), ('hastag2', HasTag2)]
    with patch('xblock.core.XBlock.load_classes', return_value=the_classes):
        assert_equals(set(XBlock.load_tagged_classes('thetag')), set(tagged_classes))
Esempio n. 40
0
def test_problem_submission():
    runtime = WorkbenchRuntime()
    problem_usage_id = runtime.parse_xml_string("""
        <problem>
            <textinput name='vote_count' input_type='int'/>

            <script>
                numvotes = 4
            </script>
            <equality name='votes_named' left='./vote_count/@student_input' right='$numvotes'>
                Number of upvotes matches entered string
            </equality>
        </problem>
    """)
    problem = runtime.get_block(problem_usage_id)
    json_data = json.dumps({"vote_count": [{"name": "input", "value": "4"}]})
    resp = runtime.handle(problem, 'check', make_request(json_data))
    resp_data = json.loads(text_of_response(resp))
    assert_equals(resp_data['checkResults']['votes_named'], True)
Esempio n. 41
0
    def student_view(self, _context):
        """Try out some services."""

        # i18n is available, and works.
        def assert_equals_unicode(str1, str2):
            """`str1` equals `str2`, and both are Unicode strings."""
            assert_equals(str1, str2)
            assert isinstance(str1, unicode)
            assert isinstance(str2, unicode)

        i18n = self.runtime.service(self, "i18n")
        assert_equals_unicode(u"Welcome!", i18n.ugettext("Welcome!"))

        assert_equals_unicode(u"Plural",
                              i18n.ungettext("Singular", "Plural", 0))
        assert_equals_unicode(u"Singular",
                              i18n.ungettext("Singular", "Plural", 1))
        assert_equals_unicode(u"Plural",
                              i18n.ungettext("Singular", "Plural", 2))

        when = datetime(2013, 2, 14, 22, 30, 17)
        assert_equals_unicode(u"2013-02-14", i18n.strftime(when, "%Y-%m-%d"))
        assert_equals_unicode(u"Feb 14, 2013",
                              i18n.strftime(when, "SHORT_DATE"))
        assert_equals_unicode(u"Thursday, February 14, 2013",
                              i18n.strftime(when, "LONG_DATE"))
        assert_equals_unicode(u"Feb 14, 2013 at 22:30",
                              i18n.strftime(when, "DATE_TIME"))
        assert_equals_unicode(u"10:30:17 PM", i18n.strftime(when, "TIME"))

        # secret_service is available.
        assert_equals(self.runtime.service(self, "secret_service"), 17)

        # no_such_service is not available, and raises an exception, because we
        # said we needed it.
        with assert_raises_regexp(NoSuchServiceError, "is not available"):
            self.runtime.service(self, "no_such_service")

        # another_not_service is not available, and returns None, because we
        # didn't need it, we only wanted it.
        assert_is(self.runtime.service(self, "another_not_service"), None)
        return Fragment()
Esempio n. 42
0
def test_json_handler_basic():
    test_self = Mock()
    test_data = {"foo": "bar", "baz": "quux"}
    test_data_json = [
        '{"foo": "bar", "baz": "quux"}', '{"baz": "quux", "foo": "bar"}'
    ]
    test_suffix = "suff"
    test_request = Mock(method="POST", body=test_data_json[0])

    @XBlock.json_handler
    def test_func(self, request, suffix):
        assert_equals(self, test_self)
        assert_equals(request, test_data)
        assert_equals(suffix, test_suffix)
        return request

    response = test_func(test_self, test_request, test_suffix)
    assert_equals(response.status_code, 200)
    assert_in(response.body.decode('utf-8'), test_data_json)
    assert_equals(response.content_type, "application/json")
Esempio n. 43
0
def test_xblock_save_failure_none():
    # Mimics a save failure when we don't manage to save any of the values

    def fake_set_many(block, update_dict):  # pylint: disable=unused-argument
        """Mock update method that throws a KeyValueMultiSaveError indicating
           that no fields were correctly saved."""
        raise KeyValueMultiSaveError([])

    field_tester = setup_save_failure(fake_set_many)
    field_tester.field_a = 20
    field_tester.field_b = 30
    field_tester.field_c = 40

    with assert_raises(XBlockSaveError) as save_error:
        # This call should raise an XBlockSaveError
        field_tester.save()

    # Verify that the correct data is getting stored by the error
    assert_equals(len(save_error.exception.saved_fields), 0)
    assert_equals(len(save_error.exception.dirty_fields), 3)
Esempio n. 44
0
def test_unique_id_default():
    class TestBlock(XBlock):
        """
        Block for testing
        """
        field_a = String(default=UNIQUE_ID, scope=Scope.settings)
        field_b = String(default=UNIQUE_ID, scope=Scope.user_state)

    sids = ScopeIds(user_id="bob",
                    block_type="bobs-type",
                    def_id="definition-id",
                    usage_id="usage-id")

    runtime = TestRuntime(services={'field-data': DictFieldData({})})
    block = TestBlock(runtime, DictFieldData({}), sids)
    unique_a = block.field_a
    unique_b = block.field_b
    # Create another instance of the same block. Unique ID defaults should not change.
    runtime = TestRuntime(services={'field-data': DictFieldData({})})
    block = TestBlock(runtime, DictFieldData({}), sids)
    assert_equals(unique_a, block.field_a)
    assert_equals(unique_b, block.field_b)
    # Change the user id. Unique ID default should change for field_b with
    # user_state scope, but not for field_a with scope=settings.
    runtime = TestRuntime(services={'field-data': DictFieldData({})})
    block = TestBlock(runtime, DictFieldData({}),
                      sids._replace(user_id='alice'))
    assert_equals(unique_a, block.field_a)
    assert_not_equals(unique_b, block.field_b)
    # Change the usage id. Unique ID default for both fields should change.
    runtime = TestRuntime(services={'field-data': DictFieldData({})})
    block = TestBlock(runtime, DictFieldData({}),
                      sids._replace(usage_id='usage-2'))
    assert_not_equals(unique_a, block.field_a)
    assert_not_equals(unique_b, block.field_b)
Esempio n. 45
0
def test_xblock_with_handler():
    # Tests an XBlock that provides a handler, and has some simple
    # student state
    client = Client()

    # Initially, the data is the default.
    response = client.get("/view/testit/")
    response_content = response.content.decode('utf-8')

    expected = u"The data: %r." % u"def"
    assert_true(expected in response_content)

    parsed = response_content.split(':::')
    assert_equals(len(parsed), 3)
    handler_url = parsed[1]

    # Now change the data.
    response = client.post(handler_url, "{}", "text/json")
    the_data = json.loads(response.content)['the_data']
    assert_equals(the_data, "defx")

    # Change it again.
    response = client.post(handler_url, "{}", "text/json")
    the_data = json.loads(response.content)['the_data']
    assert_equals(the_data, "defxx")
Esempio n. 46
0
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_all_scenarios(self):
        """Load the home page, examine the scenarios displayed."""
        client = Client()
        response = client.get("/")
        assert response.status_code == 200
        html = lxml.html.fromstring(response.content)
        a_tags = list(html.xpath('//a'))

        # Load the loaded_scenarios from the classes.
        loaded_scenarios = scenarios.get_scenarios().values()

        # We should have an <a> tag for each scenario.
        assert_equals(len(a_tags), len(loaded_scenarios))

        # We should have at least one scenario with a vertical tag, since we use
        # empty verticals as our canary in the coal mine that something has gone
        # horribly wrong with loading the loaded_scenarios.
        assert any("<vertical_demo>" in scen.xml for scen in loaded_scenarios)

        # Since we are claiming in try_scenario that no vertical is empty, let's
        # eliminate the possibility that a scenario has an actual empty vertical.
        assert all("<vertical_demo></vertical_demo>" not in scen.xml for scen in loaded_scenarios)
        assert all("<vertical_demo/>" not in scen.xml for scen in loaded_scenarios)
Esempio n. 48
0
def test_problem_submission():
    runtime = WorkbenchRuntime()

    # WorkbenchRuntime has an id_generator, but most runtimes won't
    # (because the generator will be contextual), so we
    # pass it explicitly to parse_xml_string.
    problem_usage_id = runtime.parse_xml_string("""
        <problem_demo>
            <textinput_demo name='vote_count' input_type='int'/>

            <script>
                numvotes = 4
            </script>
            <equality_demo name='votes_named' left='./vote_count/@student_input' right='$numvotes'>
                Number of upvotes matches entered string
            </equality_demo>
        </problem_demo>
    """, runtime.id_generator)
    problem = runtime.get_block(problem_usage_id)
    json_data = json.dumps({"vote_count": [{"name": "input", "value": "4"}]})
    resp = runtime.handle(problem, 'check', make_request(json_data))
    resp_data = json.loads(text_of_response(resp))
    assert_equals(resp_data['checkResults']['votes_named'], True)
Esempio n. 49
0
def test_caching_is_per_instance():
    # Test that values cached for one instance do not appear on another
    class FieldTester(ScopedStorageMixin):
        """Toy class for ModelMetaclass and field access testing"""
        field_a = List(scope=Scope.settings)

    field_data = MagicMock(spec=FieldData)
    field_data.get = lambda block, name, default=None: [name]  # pylint: disable=C0322

    # Same field_data used in different objects should result
    # in separately-cached values, so that changing a value
    # in one instance doesn't affect values stored in others.
    field_tester_a = FieldTester(
        runtime=TestRuntime(services={'field-data': field_data}),
        scope_ids=MagicMock(spec=ScopeIds))
    field_tester_b = FieldTester(
        runtime=TestRuntime(services={'field-data': field_data}),
        scope_ids=MagicMock(spec=ScopeIds))
    value = field_tester_a.field_a
    assert_equals(value, field_tester_a.field_a)
    field_tester_a.field_a.append(1)
    assert_equals(value, field_tester_a.field_a)
    assert_not_equals(value, field_tester_b.field_a)
Esempio n. 50
0
def test_services_decorators():
    # pylint: disable=E1101
    # A default XBlock has requested no services
    xblock = XBlock(None, None, None)
    assert_equals(XBlock._services_requested, {})
    assert_equals(xblock._services_requested, {})

    @XBlock.needs("n")
    @XBlock.wants("w")
    class ServiceUsingBlock(XBlock):
        """XBlock using some services."""
        pass

    service_using_block = ServiceUsingBlock(None, scope_ids=None)
    assert_equals(ServiceUsingBlock._services_requested, {'n': 'need', 'w': 'want'})
    assert_equals(service_using_block._services_requested, {'n': 'need', 'w': 'want'})
Esempio n. 51
0
def test_plugin_caching():
    plugin.PLUGIN_CACHE = {}
    assert_equals(_num_plugins_cached(), 0)

    XBlock.load_class("thumbs")
    assert_equals(_num_plugins_cached(), 1)

    XBlock.load_class("thumbs")
    assert_equals(_num_plugins_cached(), 1)
Esempio n. 52
0
def test_class_tags():
    xblock = XBlock(None, None, None)
    assert_equals(xblock._class_tags, set())

    class Sub1Block(XBlock):
        """Toy XBlock"""
        pass

    sub1block = Sub1Block(None, None, None)
    assert_equals(sub1block._class_tags, set())

    @XBlock.tag("cat dog")
    class Sub2Block(Sub1Block):
        """Toy XBlock"""
        pass

    sub2block = Sub2Block(None, None, None)
    assert_equals(sub2block._class_tags, set(["cat", "dog"]))

    class Sub3Block(Sub2Block):
        """Toy XBlock"""
        pass

    sub3block = Sub3Block(None, None, None)
    assert_equals(sub3block._class_tags, set(["cat", "dog"]))

    @XBlock.tag("mixin")
    class MixinBlock(XBlock):
        """Toy XBlock"""
        pass

    class Sub4Block(MixinBlock, Sub3Block):
        """Toy XBlock"""
        pass

    sub4block = Sub4Block(None, None, None)
    assert_equals(sub4block._class_tags, set(["cat", "dog", "mixin"]))
Esempio n. 53
0
def test_defaults_not_shared():
    class FieldTester(XBlock):
        """Toy class for field access testing"""

        field_a = List(scope=Scope.settings)

    field_tester_a = FieldTester(TestRuntime(services={'field-data': DictFieldData({})}), scope_ids=Mock(spec=ScopeIds))
    field_tester_b = FieldTester(TestRuntime(services={'field-data': DictFieldData({})}), scope_ids=Mock(spec=ScopeIds))

    field_tester_a.field_a.append(1)
    assert_equals([1], field_tester_a.field_a)
    assert_equals([], field_tester_b.field_a)
    # Write out the data
    field_tester_a.save()
    # Double check that write didn't do something weird
    assert_equals([1], field_tester_a.field_a)
    assert_equals([], field_tester_b.field_a)
Esempio n. 54
0
def test_xblock_save_one():
    # Mimics a save failure when we only manage to save one of the values

    # Pylint, please allow this method to accept arguments.
    # pylint: disable=W0613
    def fake_set_many(block, update_dict):
        """Mock update method that throws a KeyValueMultiSaveError indicating
           that only one field was correctly saved."""
        raise KeyValueMultiSaveError([update_dict.keys()[0]])
    # pylint: enable=W0613

    field_tester = setup_save_failure(fake_set_many)

    field_tester.field_a = 20
    field_tester.field_b = 40
    field_tester.field_c = 60

    with assert_raises(XBlockSaveError) as save_error:
        # This call should raise an XBlockSaveError
        field_tester.save()

    # Verify that the correct data is getting stored by the error
    assert_equals(len(save_error.exception.saved_fields), 1)
    assert_equals(len(save_error.exception.dirty_fields), 2)
Esempio n. 55
0
def test_defaults_not_shared():
    class FieldTester(XBlock):
        """Toy class for field access testing"""

        field_a = List(scope=Scope.settings)

    field_tester_a = FieldTester(MagicMock(), DictFieldData({}), Mock())
    field_tester_b = FieldTester(MagicMock(), DictFieldData({}), Mock())

    field_tester_a.field_a.append(1)
    assert_equals([1], field_tester_a.field_a)
    assert_equals([], field_tester_b.field_a)
    # Write out the data
    field_tester_a.save()
    # Double check that write didn't do something weird
    assert_equals([1], field_tester_a.field_a)
    assert_equals([], field_tester_b.field_a)
Esempio n. 56
0
    def test_set(self):
        assert_equals(1, self.agg.first)
        self.agg.first = 10
        assert_equals(10, self.agg.first)
        assert_equals(10, self.first.first)  # pylint: disable=E1101

        with assert_raises(AttributeError):
            self.agg.other = 99
        assert_false(hasattr(self.first, 'other'))
        assert_false(hasattr(self.second, 'other'))
Esempio n. 57
0
def test_json_handler_get():
    test_request = Mock(method="GET")

    @XBlock.json_handler
    def test_func(self, request, suffix):
        return {}

    response = test_func(Mock(), test_request, "dummy_suffix")
    assert_equals(response.status_code, 405)
    assert_equals(json.loads(response.body), {"error": "Method must be POST"})
    assert_equals(list(response.allow), ["POST"])
Esempio n. 58
0
def test_json_handler_empty_request():
    test_request = Mock(method="POST", body="")

    @XBlock.json_handler
    def test_func(self, request, suffix):
        return {}

    response = test_func(Mock(), test_request, "dummy_suffix")
    assert_equals(response.status_code, 400)
    assert_equals(json.loads(response.body), {"error": "Invalid JSON"})
    assert_equals(response.content_type, "application/json")
Esempio n. 59
0
def test_json_handler_return_response():
    test_request = Mock(method="POST", body="{}")

    @XBlock.json_handler
    def test_func(self, request, suffix):  # pylint: disable=unused-argument
        return Response(body="not JSON", status=418, content_type="text/plain")

    response = test_func(Mock(), test_request, "dummy_suffix")
    assert_equals(response.body, "not JSON")
    assert_equals(response.status_code, 418)
    assert_equals(response.content_type, "text/plain")
Esempio n. 60
0
def test_json_handler_invalid_json():
    test_request = Mock(method="POST", body="{")

    @XBlock.json_handler
    def test_func(self, request, suffix):   # pylint: disable=unused-argument
        return {}

    response = test_func(Mock(), test_request, "dummy_suffix")
    # pylint: disable=no-member
    assert_equals(response.status_code, 400)
    assert_equals(json.loads(response.body), {"error": "Invalid JSON"})
    assert_equals(response.content_type, "application/json")