def test_dictionary_consolidates_duplicate_entries(self): yes_or_no_dict_array = [ {"label": {"French": "Oui", "English": "Yes"}, "name": "yes"}, {"label": {"French": "Non", "English": "No"}, "name": "no"}, ] first_yesno_question = MultipleChoiceQuestion( name="yn_q1", options=yes_or_no_dict_array, type="select one" ) second_yesno_question = MultipleChoiceQuestion( name="yn_q2", options=yes_or_no_dict_array, type="select one" ) s = Survey(name="yes_or_no_tests") s.add_child(first_yesno_question) s.add_child(second_yesno_question) # begin the processes in survey.to_xml() # 1. validate() s.validate()
class FloipSurvey(object): """ Converter of a FLOIP Result descriptor to Openrosa XForm. """ def __init__(self, descriptor=None, title=None, id_string=None): # Seek to begining of file if it has the seek attribute before loading # the file. if hasattr(descriptor, 'seek'): descriptor.seek(0) try: # descriptor is a file self.descriptor = json.load(descriptor) except AttributeError: try: # descriptor is a JSON string self.descriptor = json.loads(descriptor) except JSONDecodeError: # descriptor is a file path. self.descriptor = json.load( codecs.open(descriptor, encoding='utf-8')) if self.descriptor['profile'] == FLOW_RESULTS_PROFILE: del self.descriptor['profile'] self._package = Package(self.descriptor) self.descriptor = self._package.descriptor self._name = id_string or self._package.descriptor.get('name') assert self._name, "The 'name' property must be defined." title = title or self._package.descriptor.get('title') or self._name survey_dict = { constants.NAME: 'data', constants.ID_STRING: self._name, constants.TITLE: title, constants.TYPE: constants.SURVEY, } self._survey = Survey(**survey_dict) self.build() def build(self): """ Creates the survey questions for the XForm a FLOIP descriptor. """ if not self._package.resources: raise ValidationError("At least one data resource is required.") resource = self._package.resources[0] if 'schema' not in resource.descriptor: raise ValidationError("The 'schema' object is missing in resource") if 'questions' not in resource.descriptor['schema']: raise ValidationError( "The 'questions' object is missing from schema") questions = resource.descriptor['schema']['questions'] if isinstance(questions, dict): question_keys = list(questions.keys()) question_keys.sort() for name in question_keys: xform_from_floip_dict(self._survey, name, questions[name]) elif isinstance(questions, list): for question in questions: for name in question: xform_from_floip_dict(self._survey, name, question[name]) else: raise ValidationError( "Expecting 'questions' to be an object or array") meta_dict = { "name": "meta", "type": "group", "control": { "bodyless": True }, "children": [{ "name": "instanceID", "type": "calculate", "bind": { "calculate": "concat('uuid:', uuid())" } }, { "name": "contactID", "type": "string", }, { "name": "sessionID", "type": "string", }] } # yapf: disable self._survey.add_child(create_survey_element_from_dict(meta_dict)) self._survey.validate() # check that we can recreate the survey object from the survey JSON create_survey_element_from_dict(self._survey.to_json_dict()) @property def survey(self): """ Returns a pyxform `Survey` object """ return self._survey def xml(self): """ Returns a XForm XML """ return self._survey.to_xml() def survey_dict(self): """ Returns a XForm dict. """ return self._survey.to_json_dict()