diff --git a/.ruby-version b/.ruby-version index dd472cffa2..311baaf3e2 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -1.8.7-p371 \ No newline at end of file +1.9.3-p374 diff --git a/cms/djangoapps/contentstore/features/advanced-settings.py b/cms/djangoapps/contentstore/features/advanced-settings.py index ec58aeccc6..1024579b45 100644 --- a/cms/djangoapps/contentstore/features/advanced-settings.py +++ b/cms/djangoapps/contentstore/features/advanced-settings.py @@ -39,7 +39,7 @@ def reload_the_page(step): def edit_the_name_of_a_policy_key(step): policy_key_css = 'input.policy-key' e = css_find(policy_key_css).first - e.fill('new') + e.type('_new') @step(u'I press the "([^"]*)" notification button$') @@ -97,7 +97,12 @@ def i_see_only_display_name(step): @step('there are no advanced policy settings$') 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$') @@ -121,7 +126,7 @@ def the_policy_key_name_is_unchanged(step): def the_policy_key_name_is_changed(step): policy_key_css = 'input.policy-key' 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$') @@ -170,8 +175,8 @@ def delete_entry(index): def assert_policy_entries(expected_keys, expected_values): - assert_entries('.key input', expected_keys) - assert_entries('.json', expected_values) + assert_entries('.key input.policy-key', expected_keys) + assert_entries('textarea.json', expected_values) def assert_entries(css, expected_values): @@ -184,14 +189,6 @@ def assert_entries(css, expected_values): def click_save(): 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) diff --git a/cms/djangoapps/contentstore/features/common.py b/cms/djangoapps/contentstore/features/common.py index f7e76ecf7f..2ec0427e1d 100644 --- a/cms/djangoapps/contentstore/features/common.py +++ b/cms/djangoapps/contentstore/features/common.py @@ -126,7 +126,7 @@ def css_find(css): def is_visible(driver): 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) return world.browser.find_by_css(css) diff --git a/cms/static/js/views/settings/advanced_view.js b/cms/static/js/views/settings/advanced_view.js index 2f2abb8d25..a933bbdb9b 100644 --- a/cms/static/js/views/settings/advanced_view.js +++ b/cms/static/js/views/settings/advanced_view.js @@ -229,7 +229,7 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ var error = {}; error[oldKey] = 'You have already defined "' + newKey + '" in the manual policy definitions.'; 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; } @@ -245,7 +245,7 @@ CMS.Views.Settings.Advanced = CMS.Views.ValidatingView.extend({ // swap to the key which the map knows about validation[oldKey] = validation[newKey]; } - this.model.trigger("error", this.model, validation); + this.model.trigger("invalid", this.model, validation); // abandon update return; } diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index f614743e67..9781f10ae6 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -366,6 +366,12 @@ class ChoiceGroup(InputTypeBase): 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): return {'input_type': self.html_input_type, 'choices': self.choices, diff --git a/common/lib/capa/capa/templates/choicegroup.html b/common/lib/capa/capa/templates/choicegroup.html index 8816933075..e1ff40b6a1 100644 --- a/common/lib/capa/capa/templates/choicegroup.html +++ b/common/lib/capa/capa/templates/choicegroup.html @@ -1,7 +1,7 @@
% if input_type == 'checkbox' or not value: - % if status == 'unsubmitted': + % if status == 'unsubmitted' or show_correctness == 'never': % elif status == 'correct': @@ -21,11 +21,15 @@ <% if status == 'correct': correctness = 'correct' - if status == 'incorrect': + elif status == 'incorrect': correctness = 'incorrect' + else: + correctness = None %> + % if correctness and not show_correctness=='never': class="choicegroup_${correctness}" % endif + % endif > + % if show_correctness == "never" and (value or status not in ['unsubmitted']): +
${submitted_message}
+ %endif diff --git a/common/lib/capa/capa/tests/test_inputtypes.py b/common/lib/capa/capa/tests/test_inputtypes.py index f670a38746..287caad28f 100644 --- a/common/lib/capa/capa/tests/test_inputtypes.py +++ b/common/lib/capa/capa/tests/test_inputtypes.py @@ -102,6 +102,8 @@ class ChoiceGroupTest(unittest.TestCase): 'choices': [('foil1', 'This is foil One.'), ('foil2', 'This is foil Two.'), ('foil3', 'This is foil Three.'), ], + 'show_correctness': 'always', + 'submitted_message': 'Answer received.', 'name_array_suffix': expected_suffix, # what is this for?? } diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index 72196f92a2..764a35b77a 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -246,7 +246,7 @@ class CourseDescriptor(SequenceDescriptor): policy = json.loads(cls.read_grading_policy(paths, system)) except ValueError: 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 # descriptor 'definition' bucket as a dictionary so that it is persisted in the DB @@ -398,7 +398,7 @@ class CourseDescriptor(SequenceDescriptor): return self.metadata.get("cohort_config", {}).get( "auto_cohort_groups", []) - + @property def top_level_discussion_topic_ids(self): """ diff --git a/lms/djangoapps/django_comment_client/utils.py b/lms/djangoapps/django_comment_client/utils.py index dde219294c..7cc36c491b 100644 --- a/lms/djangoapps/django_comment_client/utils.py +++ b/lms/djangoapps/django_comment_client/utils.py @@ -18,7 +18,6 @@ import pystache_custom as pystache from xmodule.modulestore import Location from xmodule.modulestore.django import modulestore -from xmodule.modulestore.search import path_to_location log = logging.getLogger(__name__) @@ -166,7 +165,6 @@ def initialize_discussion_info(course): # 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) - path_to_locations = {} for module in all_modules: skip_module = False for key in ('id', 'discussion_category', 'for'): @@ -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)) 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: continue @@ -246,7 +236,6 @@ def initialize_discussion_info(course): _DISCUSSIONINFO[course.id]['id_map'] = discussion_id_map _DISCUSSIONINFO[course.id]['category_map'] = category_map _DISCUSSIONINFO[course.id]['timestamp'] = datetime.now() - _DISCUSSIONINFO[course.id]['path_to_location'] = path_to_locations class JsonResponse(HttpResponse): @@ -403,21 +392,8 @@ def get_courseware_context(content, course): location = id_map[id]["location"].url() title = id_map[id]["title"] - # cdodge: did we pre-compute, if so, then let's use that rather than recomputing - if 'path_to_location' in _DISCUSSIONINFO[course.id] and location in _DISCUSSIONINFO[course.id]['path_to_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}) + url = reverse('jump_to', kwargs={"course_id":course.location.course_id, + "location": location}) content_info = {"courseware_url": url, "courseware_title": title} return content_info diff --git a/lms/static/images/university/delft/delft-cover.jpg b/lms/static/images/university/delft/delft-cover.jpg index 73092d7596..e69c836908 100644 Binary files a/lms/static/images/university/delft/delft-cover.jpg and b/lms/static/images/university/delft/delft-cover.jpg differ