Update unit test for editable_metadata_fields.
This commit is contained in:
@@ -1,21 +1,39 @@
|
|||||||
from xmodule.x_module import XModuleFields
|
from xmodule.x_module import XModuleFields
|
||||||
from xblock.core import Scope, String, Object
|
from xblock.core import Scope, String, Object, Boolean
|
||||||
from xmodule.fields import Date, StringyInteger
|
from xmodule.fields import Date, StringyInteger, StringyFloat
|
||||||
from xmodule.xml_module import XmlDescriptor
|
from xmodule.xml_module import XmlDescriptor
|
||||||
import unittest
|
import unittest
|
||||||
from . import test_system
|
from . import test_system
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
|
|
||||||
|
|
||||||
|
class CrazyJsonString(String):
|
||||||
|
|
||||||
|
def to_json(self, value):
|
||||||
|
return value + " JSON"
|
||||||
|
|
||||||
|
|
||||||
class TestFields(object):
|
class TestFields(object):
|
||||||
# Will be returned by editable_metadata_fields.
|
# Will be returned by editable_metadata_fields.
|
||||||
max_attempts = StringyInteger(scope=Scope.settings, default=1000)
|
max_attempts = StringyInteger(scope=Scope.settings, default=1000, values={'min': 1 , 'max' : 10})
|
||||||
# Will not be returned by editable_metadata_fields because filtered out by non_editable_metadata_fields.
|
# Will not be returned by editable_metadata_fields because filtered out by non_editable_metadata_fields.
|
||||||
due = Date(scope=Scope.settings)
|
due = Date(scope=Scope.settings)
|
||||||
# Will not be returned by editable_metadata_fields because is not Scope.settings.
|
# Will not be returned by editable_metadata_fields because is not Scope.settings.
|
||||||
student_answers = Object(scope=Scope.user_state)
|
student_answers = Object(scope=Scope.user_state)
|
||||||
# Will be returned, and can override the inherited value from XModule.
|
# Will be returned, and can override the inherited value from XModule.
|
||||||
display_name = String(scope=Scope.settings, default='local default')
|
display_name = String(scope=Scope.settings, default='local default', display_name = 'Local Display Name',
|
||||||
|
help='local help')
|
||||||
|
# Used for testing select type, effect of to_json method
|
||||||
|
string_select = CrazyJsonString(scope=Scope.settings, default='default value',
|
||||||
|
values=[{'display_name' : 'first', 'value' : 'value a'},
|
||||||
|
{'display_name' : 'second','value' : 'value b'}])
|
||||||
|
# Used for testing select type
|
||||||
|
float_select = StringyFloat(scope=Scope.settings, default=.999, values=[1.23, 0.98])
|
||||||
|
# Used for testing float type
|
||||||
|
float_non_select = StringyFloat(scope=Scope.settings, default=.999, values={'min': 0 , 'step' : .3})
|
||||||
|
# Used for testing that Booleans get mapped to select type
|
||||||
|
# TODO: move default value into xblock!
|
||||||
|
boolean_select = Boolean(scope=Scope.settings, values=[{'display_name': "True", "value": True}, {'display_name': "False", "value": False}])
|
||||||
|
|
||||||
|
|
||||||
class EditableMetadataFieldsTest(unittest.TestCase):
|
class EditableMetadataFieldsTest(unittest.TestCase):
|
||||||
@@ -34,18 +52,20 @@ class EditableMetadataFieldsTest(unittest.TestCase):
|
|||||||
self.assert_field_values(editable_fields, 'display_name', XModuleFields.display_name,
|
self.assert_field_values(editable_fields, 'display_name', XModuleFields.display_name,
|
||||||
explicitly_set=True, inheritable=False, value='foo', default_value=None)
|
explicitly_set=True, inheritable=False, value='foo', default_value=None)
|
||||||
|
|
||||||
def test_additional_field(self):
|
def test_integer_field(self):
|
||||||
descriptor = self.get_descriptor({'max_attempts' : '7'})
|
descriptor = self.get_descriptor({'max_attempts' : '7'})
|
||||||
editable_fields = descriptor.editable_metadata_fields
|
editable_fields = descriptor.editable_metadata_fields
|
||||||
self.assertEqual(2, len(editable_fields))
|
self.assertEqual(6, len(editable_fields))
|
||||||
self.assert_field_values(editable_fields, 'max_attempts', TestFields.max_attempts,
|
self.assert_field_values(editable_fields, 'max_attempts', TestFields.max_attempts,
|
||||||
explicitly_set=True, inheritable=False, value=7, default_value=1000)
|
explicitly_set=True, inheritable=False, value=7, default_value=1000, type='Integer',
|
||||||
self.assert_field_values(editable_fields, 'display_name', XModuleFields.display_name,
|
options=TestFields.max_attempts.values)
|
||||||
|
self.assert_field_values(editable_fields, 'display_name', TestFields.display_name,
|
||||||
explicitly_set=False, inheritable=False, value='local default', default_value='local default')
|
explicitly_set=False, inheritable=False, value='local default', default_value='local default')
|
||||||
|
|
||||||
editable_fields = self.get_descriptor({}).editable_metadata_fields
|
editable_fields = self.get_descriptor({}).editable_metadata_fields
|
||||||
self.assert_field_values(editable_fields, 'max_attempts', TestFields.max_attempts,
|
self.assert_field_values(editable_fields, 'max_attempts', TestFields.max_attempts,
|
||||||
explicitly_set=False, inheritable=False, value=1000, default_value=1000)
|
explicitly_set=False, inheritable=False, value=1000, default_value=1000, type='Integer',
|
||||||
|
options=TestFields.max_attempts.values)
|
||||||
|
|
||||||
def test_inherited_field(self):
|
def test_inherited_field(self):
|
||||||
model_val = {'display_name' : 'inherited'}
|
model_val = {'display_name' : 'inherited'}
|
||||||
@@ -54,7 +74,7 @@ class EditableMetadataFieldsTest(unittest.TestCase):
|
|||||||
descriptor._inherited_metadata = model_val
|
descriptor._inherited_metadata = model_val
|
||||||
descriptor._inheritable_metadata = model_val
|
descriptor._inheritable_metadata = model_val
|
||||||
editable_fields = descriptor.editable_metadata_fields
|
editable_fields = descriptor.editable_metadata_fields
|
||||||
self.assert_field_values(editable_fields, 'display_name', XModuleFields.display_name,
|
self.assert_field_values(editable_fields, 'display_name', TestFields.display_name,
|
||||||
explicitly_set=False, inheritable=True, value='inherited', default_value='inherited')
|
explicitly_set=False, inheritable=True, value='inherited', default_value='inherited')
|
||||||
|
|
||||||
descriptor = self.get_descriptor({'display_name' : 'explicit'})
|
descriptor = self.get_descriptor({'display_name' : 'explicit'})
|
||||||
@@ -62,9 +82,36 @@ class EditableMetadataFieldsTest(unittest.TestCase):
|
|||||||
descriptor._inheritable_metadata = {'display_name' : 'inheritable value'}
|
descriptor._inheritable_metadata = {'display_name' : 'inheritable value'}
|
||||||
descriptor._inherited_metadata = {}
|
descriptor._inherited_metadata = {}
|
||||||
editable_fields = descriptor.editable_metadata_fields
|
editable_fields = descriptor.editable_metadata_fields
|
||||||
self.assert_field_values(editable_fields, 'display_name', XModuleFields.display_name,
|
self.assert_field_values(editable_fields, 'display_name', TestFields.display_name,
|
||||||
explicitly_set=True, inheritable=True, value='explicit', default_value='inheritable value')
|
explicitly_set=True, inheritable=True, value='explicit', default_value='inheritable value')
|
||||||
|
|
||||||
|
def test_type_and_options(self):
|
||||||
|
# test_display_name_field verifies that a String field is of type "Generic".
|
||||||
|
# test_integer_field verifies that a StringyInteger field is of type "Integer".
|
||||||
|
|
||||||
|
descriptor = self.get_descriptor({})
|
||||||
|
editable_fields = descriptor.editable_metadata_fields
|
||||||
|
|
||||||
|
# Tests for select
|
||||||
|
self.assert_field_values(editable_fields, 'string_select', TestFields.string_select,
|
||||||
|
explicitly_set=False, inheritable=False, value='default value', default_value='default value',
|
||||||
|
type='Select', options=[{'display_name' : 'first', 'value' : 'value a JSON'},
|
||||||
|
{'display_name' : 'second','value' : 'value b JSON'}])
|
||||||
|
|
||||||
|
self.assert_field_values(editable_fields, 'float_select', TestFields.float_select,
|
||||||
|
explicitly_set=False, inheritable=False, value=.999, default_value=.999,
|
||||||
|
type='Select', options=[1.23, 0.98])
|
||||||
|
|
||||||
|
self.assert_field_values(editable_fields, 'boolean_select', TestFields.boolean_select,
|
||||||
|
explicitly_set=False, inheritable=False, value=None, default_value=None,
|
||||||
|
type='Select', options=[{'display_name': "True", "value": True}, {'display_name': "False", "value": False}])
|
||||||
|
|
||||||
|
# Test for float
|
||||||
|
self.assert_field_values(editable_fields, 'float_non_select', TestFields.float_non_select,
|
||||||
|
explicitly_set=False, inheritable=False, value=.999, default_value=.999,
|
||||||
|
type='Float', options={'min': 0 , 'step' : .3})
|
||||||
|
|
||||||
|
|
||||||
# Start of helper methods
|
# Start of helper methods
|
||||||
def get_xml_editable_fields(self, model_data):
|
def get_xml_editable_fields(self, model_data):
|
||||||
system = test_system()
|
system = test_system()
|
||||||
@@ -84,10 +131,19 @@ class EditableMetadataFieldsTest(unittest.TestCase):
|
|||||||
system.render_template = Mock(return_value="<div>Test Template HTML</div>")
|
system.render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||||
return TestModuleDescriptor(system=system, location=None, model_data=model_data)
|
return TestModuleDescriptor(system=system, location=None, model_data=model_data)
|
||||||
|
|
||||||
def assert_field_values(self, editable_fields, name, field, explicitly_set, inheritable, value, default_value):
|
def assert_field_values(self, editable_fields, name, field, explicitly_set, inheritable, value, default_value,
|
||||||
|
type='Generic', options=[]):
|
||||||
test_field = editable_fields[name]
|
test_field = editable_fields[name]
|
||||||
self.assertEqual(field, test_field['field'])
|
|
||||||
|
self.assertEqual(field.name, test_field['field_name'])
|
||||||
|
self.assertEqual(field.display_name, test_field['display_name'])
|
||||||
|
self.assertEqual(field.help, test_field['help'])
|
||||||
|
|
||||||
|
self.assertEqual(field.to_json(value), test_field['value'])
|
||||||
|
self.assertEqual(field.to_json(default_value), test_field['default_value'])
|
||||||
|
|
||||||
|
self.assertEqual(options, test_field['options'])
|
||||||
|
self.assertEqual(type, test_field['type'])
|
||||||
|
|
||||||
self.assertEqual(explicitly_set, test_field['explicitly_set'])
|
self.assertEqual(explicitly_set, test_field['explicitly_set'])
|
||||||
self.assertEqual(inheritable, test_field['inheritable'])
|
self.assertEqual(inheritable, test_field['inheritable'])
|
||||||
self.assertEqual(value, test_field['value'])
|
|
||||||
self.assertEqual(default_value, test_field['default_value'])
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
import copy
|
||||||
import yaml
|
import yaml
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -644,17 +645,16 @@ class XModuleDescriptor(XModuleFields, HTMLSnippet, ResourceTemplates, XBlock):
|
|||||||
|
|
||||||
# We support the following editors:
|
# We support the following editors:
|
||||||
# 1. A select editor for fields with a list of possible values (includes Booleans).
|
# 1. A select editor for fields with a list of possible values (includes Booleans).
|
||||||
# 2. Number editor for integers and floats.
|
# 2. Number editors for integers and floats.
|
||||||
# 3. A generic string editor for anything else (editing JSON representation of the value).
|
# 3. A generic string editor for anything else (editing JSON representation of the value).
|
||||||
type = "Generic"
|
type = "Generic"
|
||||||
# TODO: test all this logic
|
values = [] if field.values is None else copy.deepcopy(field.values)
|
||||||
values = [] if field.values is None else field.values
|
|
||||||
if isinstance(values, list):
|
if isinstance(values, list):
|
||||||
if len(values) > 0:
|
if len(values) > 0:
|
||||||
type = "Select"
|
type = "Select"
|
||||||
for index, choice in enumerate(values):
|
for index, choice in enumerate(values):
|
||||||
json_choice = choice
|
json_choice = copy.deepcopy(choice)
|
||||||
if hasattr(json_choice, 'value'):
|
if isinstance(json_choice, dict) and 'value' in json_choice:
|
||||||
json_choice['value'] = field.to_json(json_choice['value'])
|
json_choice['value'] = field.to_json(json_choice['value'])
|
||||||
else:
|
else:
|
||||||
json_choice = field.to_json(json_choice)
|
json_choice = field.to_json(json_choice)
|
||||||
|
|||||||
Reference in New Issue
Block a user