From 1a0220c765b6a09a10ca67304e8cb172412c4d64 Mon Sep 17 00:00:00 2001 From: Arthur Barrett Date: Wed, 27 Feb 2013 15:04:30 -0500 Subject: [PATCH] added a validation check on the input choice attribute --- common/lib/capa/capa/inputtypes.py | 14 +++++++++++++- common/lib/capa/capa/responsetypes.py | 3 ++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/common/lib/capa/capa/inputtypes.py b/common/lib/capa/capa/inputtypes.py index 956d82bd94..6fe307423a 100644 --- a/common/lib/capa/capa/inputtypes.py +++ b/common/lib/capa/capa/inputtypes.py @@ -974,6 +974,7 @@ class AnnotationInput(InputTypeBase): xml = self.xml self.debug = False # set to True to display extra debug info with input + self.return_to_annotation = True # return only works in conjunction with annotatable xmodule self.title = xml.findtext('./title', 'Annotation Exercise') self.text = xml.findtext('./text') @@ -981,13 +982,14 @@ class AnnotationInput(InputTypeBase): self.comment_prompt = xml.findtext('./comment_prompt', 'Type a commentary below:') self.tag_prompt = xml.findtext('./tag_prompt', 'Select one or more tags:') self.options = self._find_options() - self.return_to_annotation = True # return only works in conjunction with annotatable xmodule # Need to provide a value that JSON can parse if there is no # student-supplied value yet. if self.value == '': self.value = 'null' + self._validate_options() + def _find_options(self): ''' Returns an array of dicts where each dict represents an option. ''' elements = self.xml.findall('./options/option') @@ -997,6 +999,16 @@ class AnnotationInput(InputTypeBase): 'choice': option.get('choice') } for (index, option) in enumerate(elements) ] + def _validate_options(self): + ''' Raises a ValueError if the choice attribute is missing or invalid. ''' + valid_choices = ('correct', 'partially-correct', 'incorrect') + for option in self.options: + choice = option['choice'] + if choice is None: + raise ValueError('Missing required choice attribute.') + elif choice not in valid_choices: + raise ValueError('Invalid choice attribute: {0}. Must be one of: {1}'.format(choice, ', '.join(valid_choices))) + def _unpack(self, json_value): ''' Unpacks the json input state into a dict. ''' d = json.loads(json_value) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index d8703a4e2f..c797170a56 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -1881,7 +1881,8 @@ class AnnotationResponse(LoncapaResponse): answer_map = {} for inputfield in self.inputfields: correct_option = self._find_option_with_choice(inputfield, 'correct') - answer_map[inputfield.get('id')] = correct_option['description'] + if correct_option is not None: + answer_map[inputfield.get('id')] = correct_option.get('description') return answer_map def _find_options(self, inputfield):