Commit 94e41319 by cahrens

Unit test, remove display_name for now so there is no visible change.

parent a9a234f0
...@@ -17,7 +17,7 @@ from xmodule.x_module import XModule, XModuleFields ...@@ -17,7 +17,7 @@ from xmodule.x_module import XModule, XModuleFields
from xmodule.raw_module import RawDescriptor from xmodule.raw_module import RawDescriptor
from xmodule.exceptions import NotFoundError, ProcessingError from xmodule.exceptions import NotFoundError, ProcessingError
from xblock.core import Scope, String, Boolean, Object 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 from xmodule.util.date_utils import time_to_datetime
log = logging.getLogger("mitx.courseware") log = logging.getLogger("mitx.courseware")
...@@ -62,26 +62,23 @@ class ComplexEncoder(json.JSONEncoder): ...@@ -62,26 +62,23 @@ class ComplexEncoder(json.JSONEncoder):
class CapaFields(object): class CapaFields(object):
attempts = StringyInteger(help="Number of attempts taken by the student on this problem", default=0, scope=Scope.user_state) 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", max_attempts = StringyInteger(help="Maximum number of attempts that a student is allowed", scope=Scope.settings)
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)
due = Date(help="Date that this problem is due by", scope=XModuleFields.nonEditableSettingsScope)
graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted", graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted",
scope=XModuleFields.nonEditableSettingsScope) scope=NON_EDITABLE_SETTINGS_SCOPE)
showanswer = String(display_name="Show Answer", showanswer = String(help="When to show the problem answer to the student", scope=Scope.settings, default="closed",
help="When to show the problem answer to the student", scope=Scope.settings, default="closed",
values=["answered", "always", "attempted", "closed", "never"]) values=["answered", "always", "attempted", "closed", "never"])
force_save_button = Boolean(help="Whether to force the save button to appear on the page", force_save_button = Boolean(help="Whether to force the save button to appear on the page",
scope=XModuleFields.nonEditableSettingsScope, default=False) scope=NON_EDITABLE_SETTINGS_SCOPE, default=False)
rerandomize = Randomization(display_name="Rerandomize", help="When to rerandomize the problem", rerandomize = Randomization(help="When to rerandomize the problem", default="always", scope=Scope.settings)
default="always", scope=Scope.settings)
data = String(help="XML data for the problem", scope=Scope.content) 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={}) 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) 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) 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) 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) 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) weight = StringyFloat(help="How much to weight this problem by", scope=Scope.settings)
markdown = String(help="Markdown source of this module", scope=XModuleFields.nonEditableSettingsScope) 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) source_code = String(help="Source code for LaTeX and Word problems. This feature is not well-supported.", scope=Scope.settings)
......
from pkg_resources import resource_string 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.raw_module import RawDescriptor
from xmodule.editing_module import MetadataOnlyEditingDescriptor from xmodule.editing_module import MetadataOnlyEditingDescriptor
from xblock.core import String, Scope from xblock.core import String, Scope
class DiscussionFields(object): class DiscussionFields(object):
discussion_id = String(scope=XModuleFields.nonEditableSettingsScope) discussion_id = String(scope=NON_EDITABLE_SETTINGS_SCOPE)
discussion_category = String(display_name="Category Name", scope=Scope.settings) discussion_category = String(scope=Scope.settings)
discussion_target = String(display_name="Subcategory Name", scope=Scope.settings) discussion_target = String(scope=Scope.settings)
# We may choose to enable this in the future, but while Kevin is investigating.... # 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): class DiscussionModule(DiscussionFields, XModule):
......
...@@ -7,11 +7,18 @@ from xblock.core import ModelType ...@@ -7,11 +7,18 @@ from xblock.core import ModelType
import datetime import datetime
import dateutil.parser import dateutil.parser
from xblock.core import Integer, Float, Boolean from xblock.core import Integer, Float, Boolean, Scope
log = logging.getLogger(__name__) 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): class Date(ModelType):
''' '''
Date fields know how to parse and produce json (iso) compatible formats. Date fields know how to parse and produce json (iso) compatible formats.
......
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 Scope
from xblock.core import XBlock from xblock.core import XBlock
......
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): ...@@ -78,18 +78,12 @@ class HTMLSnippet(object):
.format(self.__class__)) .format(self.__class__))
class NonEditableSettingsScope(Scope):
pass
class XModuleFields(object): class XModuleFields(object):
display_name = String( display_name = String(
display_name="Display Name",
help="Display name for this module", help="Display name for this module",
scope=Scope.settings, scope=Scope.settings,
default=None default=None
) )
nonEditableSettingsScope = NonEditableSettingsScope(user=Scope.settings.user, block=Scope.settings.block)
class XModule(XModuleFields, HTMLSnippet, XBlock): class XModule(XModuleFields, HTMLSnippet, XBlock):
......
...@@ -10,7 +10,7 @@ from xblock.core import Object ...@@ -10,7 +10,7 @@ from xblock.core import Object
from xmodule.x_module import (XModuleDescriptor, policy_key) from xmodule.x_module import (XModuleDescriptor, policy_key)
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.modulestore.inheritance import own_metadata from xmodule.modulestore.inheritance import own_metadata
from xmodule.x_module import XModuleFields from .fields import NON_EDITABLE_SETTINGS_SCOPE
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -86,7 +86,7 @@ class XmlDescriptor(XModuleDescriptor): ...@@ -86,7 +86,7 @@ class XmlDescriptor(XModuleDescriptor):
""" """
xml_attributes = Object(help="Map of unhandled xml attributes, used only for storage between import and export", 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 # Extension to append to filename paths
filename_extension = 'xml' filename_extension = 'xml'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment