Commit 524db5e3 by Brian Talbot

Merge branch 'master' into fix/btalbot/studio-sasscleanup

parents 7a9fdb90 7806acc7
1.8.7-p371 1.9.3-p374
\ No newline at end of file
...@@ -39,7 +39,7 @@ def reload_the_page(step): ...@@ -39,7 +39,7 @@ def reload_the_page(step):
def edit_the_name_of_a_policy_key(step): def edit_the_name_of_a_policy_key(step):
policy_key_css = 'input.policy-key' policy_key_css = 'input.policy-key'
e = css_find(policy_key_css).first e = css_find(policy_key_css).first
e.fill('new') e.type('_new')
@step(u'I press the "([^"]*)" notification button$') @step(u'I press the "([^"]*)" notification button$')
...@@ -97,7 +97,12 @@ def i_see_only_display_name(step): ...@@ -97,7 +97,12 @@ def i_see_only_display_name(step):
@step('there are no advanced policy settings$') @step('there are no advanced policy settings$')
def no_policy_settings(step): def no_policy_settings(step):
assert_policy_entries([], []) keys_css = 'input.policy-key'
val_css = 'textarea.json'
k = world.browser.is_element_not_present_by_css(keys_css, 5)
v = world.browser.is_element_not_present_by_css(val_css, 5)
assert_true(k)
assert_true(v)
@step('they are alphabetized$') @step('they are alphabetized$')
...@@ -121,7 +126,7 @@ def the_policy_key_name_is_unchanged(step): ...@@ -121,7 +126,7 @@ def the_policy_key_name_is_unchanged(step):
def the_policy_key_name_is_changed(step): def the_policy_key_name_is_changed(step):
policy_key_css = 'input.policy-key' policy_key_css = 'input.policy-key'
val = css_find(policy_key_css).first.value val = css_find(policy_key_css).first.value
assert_equal(val, 'new') assert_equal(val, 'display_name_new')
@step(u'the policy key value is unchanged$') @step(u'the policy key value is unchanged$')
...@@ -170,8 +175,8 @@ def delete_entry(index): ...@@ -170,8 +175,8 @@ def delete_entry(index):
def assert_policy_entries(expected_keys, expected_values): def assert_policy_entries(expected_keys, expected_values):
assert_entries('.key input', expected_keys) assert_entries('.key input.policy-key', expected_keys)
assert_entries('.json', expected_values) assert_entries('textarea.json', expected_values)
def assert_entries(css, expected_values): def assert_entries(css, expected_values):
...@@ -184,14 +189,6 @@ def assert_entries(css, expected_values): ...@@ -184,14 +189,6 @@ def assert_entries(css, expected_values):
def click_save(): def click_save():
css = "a.save-button" css = "a.save-button"
# def is_shown(driver):
# visible = css_find(css).first.visible
# if visible:
# # Even when waiting for visible, this fails sporadically. Adding in a small wait.
# time.sleep(float(1))
# return visible
# wait_for(is_shown)
css_click_at(css) css_click_at(css)
......
...@@ -126,7 +126,7 @@ def css_find(css): ...@@ -126,7 +126,7 @@ def css_find(css):
def is_visible(driver): def is_visible(driver):
return EC.visibility_of_element_located((By.CSS_SELECTOR,css,)) return EC.visibility_of_element_located((By.CSS_SELECTOR,css,))
assert_true(world.browser.is_element_present_by_css(css, 5)) world.browser.is_element_present_by_css(css, 5)
wait_for(is_visible) wait_for(is_visible)
return world.browser.find_by_css(css) return world.browser.find_by_css(css)
......
...@@ -229,7 +229,7 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ ...@@ -229,7 +229,7 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
var error = {}; var error = {};
error[oldKey] = 'You have already defined "' + newKey + '" in the manual policy definitions.'; error[oldKey] = 'You have already defined "' + newKey + '" in the manual policy definitions.';
error[newKey] = "You tried to enter a duplicate of this key."; error[newKey] = "You tried to enter a duplicate of this key.";
this.model.trigger("error", this.model, error); this.model.trigger("invalid", this.model, error);
return false; return false;
} }
...@@ -245,7 +245,7 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ ...@@ -245,7 +245,7 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({
// swap to the key which the map knows about // swap to the key which the map knows about
validation[oldKey] = validation[newKey]; validation[oldKey] = validation[newKey];
} }
this.model.trigger("error", this.model, validation); this.model.trigger("invalid", this.model, validation);
// abandon update // abandon update
return; return;
} }
......
...@@ -366,6 +366,12 @@ class ChoiceGroup(InputTypeBase): ...@@ -366,6 +366,12 @@ class ChoiceGroup(InputTypeBase):
self.choices = self.extract_choices(self.xml) self.choices = self.extract_choices(self.xml)
@classmethod
def get_attributes(cls):
return [Attribute("show_correctness", "always"),
Attribute("submitted_message", "Answer received.")]
def _extra_context(self): def _extra_context(self):
return {'input_type': self.html_input_type, return {'input_type': self.html_input_type,
'choices': self.choices, 'choices': self.choices,
......
<form class="choicegroup capa_inputtype" id="inputtype_${id}"> <form class="choicegroup capa_inputtype" id="inputtype_${id}">
<div class="indicator_container"> <div class="indicator_container">
% if input_type == 'checkbox' or not value: % if input_type == 'checkbox' or not value:
% if status == 'unsubmitted': % if status == 'unsubmitted' or show_correctness == 'never':
<span class="unanswered" style="display:inline-block;" id="status_${id}"></span> <span class="unanswered" style="display:inline-block;" id="status_${id}"></span>
% elif status == 'correct': % elif status == 'correct':
<span class="correct" id="status_${id}"></span> <span class="correct" id="status_${id}"></span>
...@@ -21,11 +21,15 @@ ...@@ -21,11 +21,15 @@
<% <%
if status == 'correct': if status == 'correct':
correctness = 'correct' correctness = 'correct'
if status == 'incorrect': elif status == 'incorrect':
correctness = 'incorrect' correctness = 'incorrect'
else:
correctness = None
%> %>
% if correctness and not show_correctness=='never':
class="choicegroup_${correctness}" class="choicegroup_${correctness}"
% endif % endif
% endif
> >
<input type="${input_type}" name="input_${id}${name_array_suffix}" id="input_${id}_${choice_id}" value="${choice_id}" <input type="${input_type}" name="input_${id}${name_array_suffix}" id="input_${id}_${choice_id}" value="${choice_id}"
% if choice_id in value: % if choice_id in value:
...@@ -37,4 +41,7 @@ ...@@ -37,4 +41,7 @@
<span id="answer_${id}"></span> <span id="answer_${id}"></span>
</fieldset> </fieldset>
% if show_correctness == "never" and (value or status not in ['unsubmitted']):
<div class="capa_alert">${submitted_message}</div>
%endif
</form> </form>
...@@ -102,6 +102,8 @@ class ChoiceGroupTest(unittest.TestCase): ...@@ -102,6 +102,8 @@ class ChoiceGroupTest(unittest.TestCase):
'choices': [('foil1', '<text>This is foil One.</text>'), 'choices': [('foil1', '<text>This is foil One.</text>'),
('foil2', '<text>This is foil Two.</text>'), ('foil2', '<text>This is foil Two.</text>'),
('foil3', 'This is foil Three.'), ], ('foil3', 'This is foil Three.'), ],
'show_correctness': 'always',
'submitted_message': 'Answer received.',
'name_array_suffix': expected_suffix, # what is this for?? 'name_array_suffix': expected_suffix, # what is this for??
} }
......
...@@ -246,7 +246,7 @@ class CourseDescriptor(SequenceDescriptor): ...@@ -246,7 +246,7 @@ class CourseDescriptor(SequenceDescriptor):
policy = json.loads(cls.read_grading_policy(paths, system)) policy = json.loads(cls.read_grading_policy(paths, system))
except ValueError: except ValueError:
system.error_tracker("Unable to decode grading policy as json") system.error_tracker("Unable to decode grading policy as json")
policy = None policy = {}
# cdodge: import the grading policy information that is on disk and put into the # cdodge: import the grading policy information that is on disk and put into the
# descriptor 'definition' bucket as a dictionary so that it is persisted in the DB # descriptor 'definition' bucket as a dictionary so that it is persisted in the DB
...@@ -398,7 +398,7 @@ class CourseDescriptor(SequenceDescriptor): ...@@ -398,7 +398,7 @@ class CourseDescriptor(SequenceDescriptor):
return self.metadata.get("cohort_config", {}).get( return self.metadata.get("cohort_config", {}).get(
"auto_cohort_groups", []) "auto_cohort_groups", [])
@property @property
def top_level_discussion_topic_ids(self): def top_level_discussion_topic_ids(self):
""" """
......
...@@ -18,7 +18,6 @@ import pystache_custom as pystache ...@@ -18,7 +18,6 @@ import pystache_custom as pystache
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.search import path_to_location
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -166,7 +165,6 @@ def initialize_discussion_info(course): ...@@ -166,7 +165,6 @@ def initialize_discussion_info(course):
# get all discussion models within this course_id # get all discussion models within this course_id
all_modules = modulestore().get_items(['i4x', course.location.org, course.location.course, 'discussion', None], course_id=course_id) all_modules = modulestore().get_items(['i4x', course.location.org, course.location.course, 'discussion', None], course_id=course_id)
path_to_locations = {}
for module in all_modules: for module in all_modules:
skip_module = False skip_module = False
for key in ('id', 'discussion_category', 'for'): for key in ('id', 'discussion_category', 'for'):
...@@ -174,14 +172,6 @@ def initialize_discussion_info(course): ...@@ -174,14 +172,6 @@ def initialize_discussion_info(course):
log.warning("Required key '%s' not in discussion %s, leaving out of category map" % (key, module.location)) log.warning("Required key '%s' not in discussion %s, leaving out of category map" % (key, module.location))
skip_module = True skip_module = True
# cdodge: pre-compute the path_to_location. Note this can throw an exception for any
# dangling discussion modules
try:
path_to_locations[module.location] = path_to_location(modulestore(), course.id, module.location)
except NoPathToItem:
log.warning("Could not compute path_to_location for {0}. Perhaps this is an orphaned discussion module?!? Skipping...".format(module.location))
skip_module = True
if skip_module: if skip_module:
continue continue
...@@ -246,7 +236,6 @@ def initialize_discussion_info(course): ...@@ -246,7 +236,6 @@ def initialize_discussion_info(course):
_DISCUSSIONINFO[course.id]['id_map'] = discussion_id_map _DISCUSSIONINFO[course.id]['id_map'] = discussion_id_map
_DISCUSSIONINFO[course.id]['category_map'] = category_map _DISCUSSIONINFO[course.id]['category_map'] = category_map
_DISCUSSIONINFO[course.id]['timestamp'] = datetime.now() _DISCUSSIONINFO[course.id]['timestamp'] = datetime.now()
_DISCUSSIONINFO[course.id]['path_to_location'] = path_to_locations
class JsonResponse(HttpResponse): class JsonResponse(HttpResponse):
...@@ -403,21 +392,8 @@ def get_courseware_context(content, course): ...@@ -403,21 +392,8 @@ def get_courseware_context(content, course):
location = id_map[id]["location"].url() location = id_map[id]["location"].url()
title = id_map[id]["title"] title = id_map[id]["title"]
# cdodge: did we pre-compute, if so, then let's use that rather than recomputing url = reverse('jump_to', kwargs={"course_id":course.location.course_id,
if 'path_to_location' in _DISCUSSIONINFO[course.id] and location in _DISCUSSIONINFO[course.id]['path_to_location']: "location": location})
(course_id, chapter, section, position) = _DISCUSSIONINFO[course.id]['path_to_location'][location]
else:
try:
(course_id, chapter, section, position) = path_to_location(modulestore(), course.id, location)
except NoPathToItem:
# Object is not in the graph any longer, let's just get path to the base of the course
# so that we can at least return something to the caller
(course_id, chapter, section, position) = path_to_location(modulestore(), course.id, course.location)
url = reverse('courseware_position', kwargs={"course_id":course_id,
"chapter":chapter,
"section":section,
"position":position})
content_info = {"courseware_url": url, "courseware_title": title} content_info = {"courseware_url": url, "courseware_title": title}
return content_info return content_info
......
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