Unit test, remove display_name for now so there is no visible change.
This commit is contained in:
@@ -17,7 +17,7 @@ from xmodule.x_module import XModule, XModuleFields
|
||||
from xmodule.raw_module import RawDescriptor
|
||||
from xmodule.exceptions import NotFoundError, ProcessingError
|
||||
from xblock.core import Scope, String, Boolean, Object
|
||||
from .fields import Timedelta, Date, StringyInteger, StringyFloat
|
||||
from .fields import Timedelta, Date, StringyInteger, StringyFloat, NON_EDITABLE_SETTINGS_SCOPE
|
||||
from xmodule.util.date_utils import time_to_datetime
|
||||
|
||||
log = logging.getLogger("mitx.courseware")
|
||||
@@ -62,26 +62,23 @@ class ComplexEncoder(json.JSONEncoder):
|
||||
|
||||
class CapaFields(object):
|
||||
attempts = StringyInteger(help="Number of attempts taken by the student on this problem", default=0, scope=Scope.user_state)
|
||||
max_attempts = StringyInteger(display_name="Maximum Allowed Attempts",
|
||||
help="Maximum number of attempts that a student is allowed", scope=Scope.settings)
|
||||
due = Date(help="Date that this problem is due by", scope=XModuleFields.nonEditableSettingsScope)
|
||||
max_attempts = StringyInteger(help="Maximum number of attempts that a student is allowed", scope=Scope.settings)
|
||||
due = Date(help="Date that this problem is due by", scope=NON_EDITABLE_SETTINGS_SCOPE)
|
||||
graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted",
|
||||
scope=XModuleFields.nonEditableSettingsScope)
|
||||
showanswer = String(display_name="Show Answer",
|
||||
help="When to show the problem answer to the student", scope=Scope.settings, default="closed",
|
||||
scope=NON_EDITABLE_SETTINGS_SCOPE)
|
||||
showanswer = String(help="When to show the problem answer to the student", scope=Scope.settings, default="closed",
|
||||
values=["answered", "always", "attempted", "closed", "never"])
|
||||
force_save_button = Boolean(help="Whether to force the save button to appear on the page",
|
||||
scope=XModuleFields.nonEditableSettingsScope, default=False)
|
||||
rerandomize = Randomization(display_name="Rerandomize", help="When to rerandomize the problem",
|
||||
default="always", scope=Scope.settings)
|
||||
scope=NON_EDITABLE_SETTINGS_SCOPE, default=False)
|
||||
rerandomize = Randomization(help="When to rerandomize the problem", default="always", scope=Scope.settings)
|
||||
data = String(help="XML data for the problem", scope=Scope.content)
|
||||
correct_map = Object(help="Dictionary with the correctness of current student answers", scope=Scope.user_state, default={})
|
||||
input_state = Object(help="Dictionary for maintaining the state of inputtypes", scope=Scope.user_state)
|
||||
student_answers = Object(help="Dictionary with the current student responses", scope=Scope.user_state)
|
||||
done = Boolean(help="Whether the student has answered the problem", scope=Scope.user_state)
|
||||
seed = StringyInteger(help="Random seed for this student", scope=Scope.user_state)
|
||||
weight = StringyFloat(display_name="Problem Weight", help="How much to weight this problem by", scope=Scope.settings)
|
||||
markdown = String(help="Markdown source of this module", scope=XModuleFields.nonEditableSettingsScope)
|
||||
weight = StringyFloat(help="How much to weight this problem by", scope=Scope.settings)
|
||||
markdown = String(help="Markdown source of this module", scope=NON_EDITABLE_SETTINGS_SCOPE)
|
||||
source_code = String(help="Source code for LaTeX and Word problems. This feature is not well-supported.", scope=Scope.settings)
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
from pkg_resources import resource_string
|
||||
|
||||
from xmodule.x_module import XModule, XModuleFields
|
||||
from .fields import NON_EDITABLE_SETTINGS_SCOPE
|
||||
from xmodule.x_module import XModule
|
||||
from xmodule.raw_module import RawDescriptor
|
||||
from xmodule.editing_module import MetadataOnlyEditingDescriptor
|
||||
from xblock.core import String, Scope
|
||||
|
||||
|
||||
class DiscussionFields(object):
|
||||
discussion_id = String(scope=XModuleFields.nonEditableSettingsScope)
|
||||
discussion_category = String(display_name="Category Name", scope=Scope.settings)
|
||||
discussion_target = String(display_name="Subcategory Name", scope=Scope.settings)
|
||||
discussion_id = String(scope=NON_EDITABLE_SETTINGS_SCOPE)
|
||||
discussion_category = String(scope=Scope.settings)
|
||||
discussion_target = String(scope=Scope.settings)
|
||||
# We may choose to enable this in the future, but while Kevin is investigating....
|
||||
sort_key = String(scope=XModuleFields.nonEditableSettingsScope)
|
||||
sort_key = String(scope=NON_EDITABLE_SETTINGS_SCOPE)
|
||||
|
||||
|
||||
class DiscussionModule(DiscussionFields, XModule):
|
||||
|
||||
@@ -7,11 +7,18 @@ from xblock.core import ModelType
|
||||
import datetime
|
||||
import dateutil.parser
|
||||
|
||||
from xblock.core import Integer, Float, Boolean
|
||||
from xblock.core import Integer, Float, Boolean, Scope
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NonEditableSettingsScope(Scope):
|
||||
pass
|
||||
|
||||
# Same scope as Settings.scope, but not intended to be edited by users (in Studio).
|
||||
NON_EDITABLE_SETTINGS_SCOPE = NonEditableSettingsScope(user=Scope.settings.user, block=Scope.settings.block)
|
||||
|
||||
|
||||
class Date(ModelType):
|
||||
'''
|
||||
Date fields know how to parse and produce json (iso) compatible formats.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from .x_module import XModuleDescriptor, DescriptorSystem, NonEditableSettingsScope
|
||||
from .x_module import XModuleDescriptor, DescriptorSystem
|
||||
from .fields import NonEditableSettingsScope
|
||||
from xblock.core import Scope
|
||||
from xblock.core import XBlock
|
||||
|
||||
|
||||
73
common/lib/xmodule/xmodule/tests/test_mako_module.py
Normal file
73
common/lib/xmodule/xmodule/tests/test_mako_module.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from xmodule.x_module import XModuleFields
|
||||
from xblock.core import Scope, String, Object
|
||||
from xmodule.fields import Date, StringyInteger, NON_EDITABLE_SETTINGS_SCOPE
|
||||
from xmodule.mako_module import MakoModuleDescriptor
|
||||
import unittest
|
||||
from . import test_system
|
||||
from mock import Mock
|
||||
|
||||
|
||||
class TestFields(object):
|
||||
# Will be returned by editable_metadata_fields because Scope.settings.
|
||||
max_attempts = StringyInteger(scope=Scope.settings)
|
||||
# Will not be returned by editable_metadata_fields because declared as non-editable Scope.settings.
|
||||
due = Date(scope=NON_EDITABLE_SETTINGS_SCOPE)
|
||||
# Will not be returned by editable_metadata_fields because is not Scope.settings.
|
||||
student_answers = Object(scope=Scope.user_state)
|
||||
# Will be returned, and can override the inherited value from XModule.
|
||||
display_name = String(scope=Scope.settings)
|
||||
|
||||
|
||||
class EditableMetadataFieldsTest(unittest.TestCase):
|
||||
|
||||
def test_display_name_field(self):
|
||||
editable_fields = self.get_mako_editable_fields({})
|
||||
# Tests that the xblock fields (currently tags and name) get filtered out.
|
||||
self.assertEqual(1, len(editable_fields), "Expected only 1 editable field for mako descriptor.")
|
||||
self.assert_display_name_default(editable_fields)
|
||||
|
||||
def test_override_default(self):
|
||||
# Tests that is_default is correct when a value overrides the default.
|
||||
editable_fields = self.get_mako_editable_fields({'display_name': 'foo'})
|
||||
display_name = editable_fields['display_name']
|
||||
self.assertFalse(display_name['is_default'])
|
||||
self.assertEqual('foo', display_name['value'])
|
||||
|
||||
def test_additional_field(self):
|
||||
editable_fields = self.get_module_editable_fields({'max_attempts' : '7'})
|
||||
self.assertEqual(2, len(editable_fields))
|
||||
self.assert_field_values(editable_fields, 'max_attempts', TestFields.max_attempts, False, False, 7)
|
||||
self.assert_display_name_default(editable_fields)
|
||||
|
||||
editable_fields = self.get_module_editable_fields({})
|
||||
self.assert_field_values(editable_fields, 'max_attempts', TestFields.max_attempts, True, False, None)
|
||||
|
||||
def test_inherited_field(self):
|
||||
editable_fields = self.get_module_editable_fields({'display_name' : 'inherited'})
|
||||
self.assert_field_values(editable_fields, 'display_name', XModuleFields.display_name, False, True, 'inherited')
|
||||
|
||||
# Start of helper methods
|
||||
def get_mako_editable_fields(self, model_data):
|
||||
system = test_system()
|
||||
system.render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
return MakoModuleDescriptor(system=system, location=None, model_data=model_data).editable_metadata_fields
|
||||
|
||||
def get_module_editable_fields(self, model_data):
|
||||
class TestModuleDescriptor(TestFields, MakoModuleDescriptor):
|
||||
pass
|
||||
|
||||
system = test_system()
|
||||
system.render_template = Mock(return_value="<div>Test Template HTML</div>")
|
||||
descriptor = TestModuleDescriptor(system=system, location=None, model_data=model_data)
|
||||
descriptor._inherited_metadata = {'display_name' : 'inherited'}
|
||||
return descriptor.editable_metadata_fields
|
||||
|
||||
def assert_display_name_default(self, editable_fields):
|
||||
self.assert_field_values(editable_fields, 'display_name', XModuleFields.display_name, True, False, None)
|
||||
|
||||
def assert_field_values(self, editable_fields, name, field, is_default, is_inherited, value):
|
||||
test_field = editable_fields[name]
|
||||
self.assertEqual(field, test_field['field'])
|
||||
self.assertEqual(is_default, test_field['is_default'])
|
||||
self.assertEqual(is_inherited, test_field['is_inherited'])
|
||||
self.assertEqual(value, test_field['value'])
|
||||
@@ -78,18 +78,12 @@ class HTMLSnippet(object):
|
||||
.format(self.__class__))
|
||||
|
||||
|
||||
class NonEditableSettingsScope(Scope):
|
||||
pass
|
||||
|
||||
|
||||
class XModuleFields(object):
|
||||
display_name = String(
|
||||
display_name="Display Name",
|
||||
help="Display name for this module",
|
||||
scope=Scope.settings,
|
||||
default=None
|
||||
)
|
||||
nonEditableSettingsScope = NonEditableSettingsScope(user=Scope.settings.user, block=Scope.settings.block)
|
||||
|
||||
|
||||
class XModule(XModuleFields, HTMLSnippet, XBlock):
|
||||
|
||||
@@ -10,7 +10,7 @@ from xblock.core import Object
|
||||
from xmodule.x_module import (XModuleDescriptor, policy_key)
|
||||
from xmodule.modulestore import Location
|
||||
from xmodule.modulestore.inheritance import own_metadata
|
||||
from xmodule.x_module import XModuleFields
|
||||
from .fields import NON_EDITABLE_SETTINGS_SCOPE
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -86,7 +86,7 @@ class XmlDescriptor(XModuleDescriptor):
|
||||
"""
|
||||
|
||||
xml_attributes = Object(help="Map of unhandled xml attributes, used only for storage between import and export",
|
||||
default={}, scope=XModuleFields.nonEditableSettingsScope)
|
||||
default={}, scope=NON_EDITABLE_SETTINGS_SCOPE)
|
||||
|
||||
# Extension to append to filename paths
|
||||
filename_extension = 'xml'
|
||||
|
||||
Reference in New Issue
Block a user