Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
Move defaults from yaml templates to field definitions.
Browse files Browse the repository at this point in the history
This standardizes the XModule field default values to be the same as the
values that are presented by studio when a component is added to a
course.
  • Loading branch information
Don Mitchell committed Jul 16, 2013
1 parent ef8618f commit 8c904f3
Show file tree
Hide file tree
Showing 39 changed files with 707 additions and 496 deletions.
6 changes: 3 additions & 3 deletions cms/djangoapps/contentstore/features/discussion-editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ def i_created_discussion_tag(step):
def i_see_only_the_settings_and_values(step):
world.verify_all_setting_entries(
[
['Category', "Week 1", True],
['Display Name', "Discussion Tag", True],
['Subcategory', "Topic-Level Student-Visible Label", True]
['Category', "Week 1", False],
['Display Name', "Discussion Tag", False],
['Subcategory', "Topic-Level Student-Visible Label", False]
])


Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/features/html-editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ def i_created_blank_html_page(step):

@step('I see only the HTML display name setting$')
def i_see_only_the_html_display_name(step):
world.verify_all_setting_entries([['Display Name', "Blank HTML Page", True]])
world.verify_all_setting_entries([['Display Name', "Blank HTML Page", False]])
14 changes: 8 additions & 6 deletions cms/djangoapps/contentstore/features/problem-editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ def i_created_blank_common_problem(step):
world.create_component_instance(
step,
'.large-problem-icon',
'i4x://edx/templates/problem/Blank_Common_Problem',
'.xmodule_CapaModule'
'problem',
'.xmodule_CapaModule',
'blank_common.yaml'
)


Expand All @@ -32,11 +33,12 @@ def i_edit_and_select_settings(step):
def i_see_five_settings_with_values(step):
world.verify_all_setting_entries(
[
[DISPLAY_NAME, "Blank Common Problem", True],
[DISPLAY_NAME, "New problem", True],
[MAXIMUM_ATTEMPTS, "", False],
[PROBLEM_WEIGHT, "", False],
[RANDOMIZATION, "Never", True],
[SHOW_ANSWER, "Finished", True]
# Not sure why these are True other than via inspection
[RANDOMIZATION, "Always", True],
[SHOW_ANSWER, "Closed", True]
])


Expand Down Expand Up @@ -203,7 +205,7 @@ def verify_modified_display_name_with_special_chars():


def verify_unset_display_name():
world.verify_setting_entry(world.get_setting_entry(DISPLAY_NAME), DISPLAY_NAME, '', False)
world.verify_setting_entry(world.get_setting_entry(DISPLAY_NAME), DISPLAY_NAME, 'Blank Advanced Problem', False)


def set_weight(weight):
Expand Down
2 changes: 1 addition & 1 deletion cms/djangoapps/contentstore/features/video-editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
@step('I see the correct settings and default values$')
def i_see_the_correct_settings_and_values(step):
world.verify_all_setting_entries([['Default Speed', 'OEoXaMPEzfM', False],
['Display Name', 'default', True],
['Display Name', 'Video Title', False],
['Download Track', '', False],
['Download Video', '', False],
['Show Captions', 'True', False],
Expand Down
24 changes: 23 additions & 1 deletion cms/djangoapps/contentstore/tests/test_contentstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ def test_advanced_components_in_edit_unit(self):
self.check_components_on_page(ADVANCED_COMPONENT_TYPES, ['Video Alpha',
'Word cloud',
'Annotation',
'Open Ended Response',
'Open Ended Grading',
'Peer Grading Interface'])

def test_advanced_components_require_two_clicks(self):
Expand Down Expand Up @@ -1271,6 +1271,28 @@ def test_metadata_inheritance(self):

self.assertEqual(timedelta(1), new_module.lms.graceperiod)

def test_default_metadata_inheritance(self):
course = CourseFactory.create()
vertical = ItemFactory.create(parent_location=course.location)
course.children.append(vertical)
# in memory
self.assertIsNotNone(course.start)
self.assertEqual(course.start, vertical.lms.start)
self.assertEqual(course.textbooks, [])
self.assertIn('GRADER', course.grading_policy)
self.assertIn('GRADE_CUTOFFS', course.grading_policy)
self.assertGreaterEqual(len(course.checklists), 4)

# by fetching
module_store = modulestore('direct')
fetched_course = module_store.get_item(course.location)
fetched_item = module_store.get_item(vertical.location)
self.assertIsNotNone(fetched_course.start)
self.assertEqual(course.start, fetched_course.start)
self.assertEqual(fetched_course.start, fetched_item.lms.start)
self.assertEqual(course.textbooks, fetched_course.textbooks)
# is this test too strict? i.e., it requires the dicts to be ==
self.assertEqual(course.checklists, fetched_course.checklists)

class TemplateTestCase(ModuleStoreTestCase):

Expand Down
2 changes: 0 additions & 2 deletions cms/djangoapps/contentstore/tests/test_course_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def test_virgin_fetch(self):
self.assertIsNone(details.enrollment_start, "enrollment_start date somehow initialized " + str(details.enrollment_start))
self.assertIsNone(details.enrollment_end, "enrollment_end date somehow initialized " + str(details.enrollment_end))
self.assertIsNone(details.syllabus, "syllabus somehow initialized" + str(details.syllabus))
self.assertEqual(details.overview, "", "overview somehow initialized" + details.overview)
self.assertIsNone(details.intro_video, "intro_video somehow initialized" + str(details.intro_video))
self.assertIsNone(details.effort, "effort somehow initialized" + str(details.effort))

Expand All @@ -49,7 +48,6 @@ def test_encoder(self):
self.assertIsNone(jsondetails['enrollment_start'], "enrollment_start date somehow initialized ")
self.assertIsNone(jsondetails['enrollment_end'], "enrollment_end date somehow initialized ")
self.assertIsNone(jsondetails['syllabus'], "syllabus somehow initialized")
self.assertEqual(jsondetails['overview'], "", "overview somehow initialized")
self.assertIsNone(jsondetails['intro_video'], "intro_video somehow initialized")
self.assertIsNone(jsondetails['effort'], "effort somehow initialized")

Expand Down
2 changes: 1 addition & 1 deletion common/djangoapps/xmodule_modifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def _get_html():
# doesn't like symlinks)
filepath = filename
data_dir = osfs.root_path.rsplit('/')[-1]
giturl = getattr(module.lms, 'giturl', '') or 'https://github.com/MITx'
giturl = module.lms.giturl or 'https://github.com/MITx'
edit_link = "%s/%s/tree/master/%s" % (giturl, data_dir, filepath)
else:
edit_link = False
Expand Down
27 changes: 26 additions & 1 deletion common/lib/xmodule/xmodule/annotatable_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,37 @@
from xmodule.x_module import XModule
from xmodule.raw_module import RawDescriptor
from xblock.core import Scope, String
import textwrap

log = logging.getLogger(__name__)


class AnnotatableFields(object):
data = String(help="XML data for the annotation", scope=Scope.content)
data = String(help="XML data for the annotation", scope=Scope.content,
default=textwrap.dedent(
"""\
<annotatable>
<instructions>
<p>Enter your (optional) instructions for the exercise in HTML format.</p>
<p>Annotations are specified by an <code>&lt;annotation&gt;</code> tag which may may have the following attributes:</p>
<ul class="instructions-template">
<li><code>title</code> (optional). Title of the annotation. Defaults to <i>Commentary</i> if omitted.</li>
<li><code>body</code> (<b>required</b>). Text of the annotation.</li>
<li><code>problem</code> (optional). Numeric index of the problem associated with this annotation. This is a zero-based index, so the first problem on the page would have <code>problem="0"</code>.</li>
<li><code>highlight</code> (optional). Possible values: yellow, red, orange, green, blue, or purple. Defaults to yellow if this attribute is omitted.</li>
</ul>
</instructions>
<p>Add your HTML with annotation spans here.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. <annotation title="My title" body="My comment" highlight="yellow" problem="0">Ut sodales laoreet est, egestas gravida felis egestas nec.</annotation> Aenean at volutpat erat. Cras commodo viverra nibh in aliquam.</p>
<p>Nulla facilisi. <annotation body="Basic annotation example." problem="1">Pellentesque id vestibulum libero.</annotation> Suspendisse potenti. Morbi scelerisque nisi vitae felis dictum mattis. Nam sit amet magna elit. Nullam volutpat cursus est, sit amet sagittis odio vulputate et. Curabitur euismod, orci in vulputate imperdiet, augue lorem tempor purus, id aliquet augue turpis a est. Aenean a sagittis libero. Praesent fringilla pretium magna, non condimentum risus elementum nec. Pellentesque faucibus elementum pharetra. Pellentesque vitae metus eros.</p>
</annotatable>
"""))
display_name = String(
display_name="Display Name",
help="Display name for this module",
scope=Scope.settings,
default='Annotation',
)


class AnnotatableModule(AnnotatableFields, XModule):
Expand Down
27 changes: 19 additions & 8 deletions common/lib/xmodule/xmodule/capa_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ class CapaFields(object):
"""
Define the possible fields for a Capa problem
"""
display_name = String(
display_name="Display Name",
help="This name appears in the horizontal navigation at the top of the page.",
scope=Scope.settings,
# it'd be nice to have a useful default but it screws up other things; so,
# use display_name_with_default for those
default="Blank Advanced Problem"
)
attempts = Integer(help="Number of attempts taken by the student on this problem",
default=0, scope=Scope.user_state)
max_attempts = Integer(
Expand All @@ -94,7 +102,8 @@ class CapaFields(object):
display_name="Show Answer",
help=("Defines when to show the answer to the problem. "
"A default value can be set in Advanced Settings."),
scope=Scope.settings, default="closed",
scope=Scope.settings,
default="closed",
values=[
{"display_name": "Always", "value": "always"},
{"display_name": "Answered", "value": "answered"},
Expand All @@ -106,21 +115,24 @@ class CapaFields(object):
)
force_save_button = Boolean(
help="Whether to force the save button to appear on the page",
scope=Scope.settings, default=False
scope=Scope.settings,
default=False
)
rerandomize = Randomization(
display_name="Randomization",
help="Defines how often inputs are randomized when a student loads the problem. "
"This setting only applies to problems that can have randomly generated numeric values. "
"A default value can be set in Advanced Settings.",
default="always", scope=Scope.settings, values=[
"This setting only applies to problems that can have randomly generated numeric values. "
"A default value can be set in Advanced Settings.",
default="always",
scope=Scope.settings,
values=[
{"display_name": "Always", "value": "always"},
{"display_name": "On Reset", "value": "onreset"},
{"display_name": "Never", "value": "never"},
{"display_name": "Per Student", "value": "per_student"}
]
)
data = String(help="XML data for the problem", scope=Scope.content)
data = String(help="XML data for the problem", scope=Scope.content, default="<problem></problem>")
correct_map = Dict(help="Dictionary with the correctness of current student answers",
scope=Scope.user_state, default={})
input_state = Dict(help="Dictionary for maintaining the state of inputtypes", scope=Scope.user_state)
Expand All @@ -134,13 +146,12 @@ class CapaFields(object):
values={"min": 0, "step": .1},
scope=Scope.settings
)
markdown = String(help="Markdown source of this module", scope=Scope.settings)
markdown = String(help="Markdown source of this module", default="", scope=Scope.settings)
source_code = String(
help="Source code for LaTeX and Word problems. This feature is not well-supported.",
scope=Scope.settings
)


class CapaModule(CapaFields, XModule):
"""
An XModule implementing LonCapa format problems, implemented by way of
Expand Down
54 changes: 52 additions & 2 deletions common/lib/xmodule/xmodule/combined_open_ended_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from xmodule.open_ended_grading_classes.combined_open_ended_modulev1 import CombinedOpenEndedV1Module, CombinedOpenEndedV1Descriptor
from collections import namedtuple
from .fields import Date
import textwrap

log = logging.getLogger("mitx.courseware")

Expand All @@ -27,6 +28,38 @@
}

DEFAULT_VERSION = 1
DEFAULT_DATA = textwrap.dedent("""\
<combinedopenended>
<rubric>
<rubric>
<category>
<description>Category 1</description>
<option>
The response does not incorporate what is needed for a one response.
</option>
<option>
The response is correct for category 1.
</option>
</category>
</rubric>
</rubric>
<prompt>
<p>Why is the sky blue?</p>
</prompt>
<task>
<selfassessment/>
</task>
<task>
<openended min_score_to_attempt="1" max_score_to_attempt="2">
<openendedparam>
<initial_display>Enter essay here.</initial_display>
<answer_display>This is the answer.</answer_display>
<grader_payload>{"grader_settings" : "peer_grading.conf", "problem_id" : "700x/Demo"}</grader_payload>
</openendedparam>
</openended>
</task>
</combinedopenended>
""")


class VersionInteger(Integer):
Expand Down Expand Up @@ -85,13 +118,30 @@ class CombinedOpenEndedFields(object):
scope=Scope.settings
)
version = VersionInteger(help="Current version number", default=DEFAULT_VERSION, 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,
default=DEFAULT_DATA)
weight = Float(
display_name="Problem Weight",
help="Defines the number of points each problem is worth. If the value is not set, each problem is worth one point.",
scope=Scope.settings, values={"min" : 0 , "step": ".1"}
)
markdown = String(help="Markdown source of this module", scope=Scope.settings)
markdown = String(
help="Markdown source of this module",
default=textwrap.dedent("""\
[rubric]
+ Category 1
- The response does not incorporate what is needed for a one response.
- The response is correct for category 1.
[rubric]
[prompt]
<p>Why is the sky blue?</p>
[prompt]
[tasks]
(Self), ({1-2}AI)
[tasks]
"""),
scope=Scope.settings
)


class CombinedOpenEndedModule(CombinedOpenEndedFields, XModule):
Expand Down
Loading

0 comments on commit 8c904f3

Please sign in to comment.