def test_survey_can_be_created_in_a_verbose_manner(self): s = Survey() s.name = "simple_survey" q = MultipleChoiceQuestion() q.name = "cow_color" q.type = "select one" q.add_choice(label="Green", name="green") s.add_child(q) expected_dict = { "name": "simple_survey", "children": [{ "name": "cow_color", "type": "select one", "children": [{ "label": "Green", "name": "green" }], }], } self.maxDiff = None self.assertEqual(s.to_json_dict(), expected_dict)
def setUp(self): survey_out = Survey(type=u"survey") question = InputQuestion(name=u"age") question.set(InputQuestion.TYPE, u"integer") question.set(InputQuestion.LABEL, u"How old are you?") survey_out.add_child(question) self.survey_out_dict = survey_out.to_dict() print_pyobj_to_json(self.survey_out_dict, "pyxform/tests/how_old_are_you.json")
def setUp(self): self.this_directory = os.path.dirname(__file__) survey_out = Survey(name=u"age", sms_keyword=u"age", type=u"survey") question = InputQuestion(name=u"age") question.type = u"integer" question.label = u"How old are you?" survey_out.add_child(question) self.survey_out_dict = survey_out.to_json_dict() print_pyobj_to_json(self.survey_out_dict, utils.path_to_text_fixture("how_old_are_you.json"))
def setUp(self): self.this_directory = os.path.dirname(__file__) survey_out = Survey(name=u"age", type=u"survey") question = InputQuestion(name=u"age") question.type = u"integer" question.label = u"How old are you?" survey_out.add_child(question) self.survey_out_dict = survey_out.to_json_dict() print_pyobj_to_json(self.survey_out_dict, utils.path_to_text_fixture("how_old_are_you.json"))
def setUp(self): survey_out = Survey( type=u"survey" ) question = InputQuestion(name=u"age") question.set(InputQuestion.TYPE, u"integer") question.set(InputQuestion.LABEL, u"How old are you?") survey_out.add_child(question) self.survey_out_dict = survey_out.to_dict() print_pyobj_to_json(self.survey_out_dict, "pyxform/tests/how_old_are_you.json")
def test_simple_survey_instantiation(self): surv = Survey(name="Simple") q = create_survey_element_from_dict( {"type": "text", "name": "survey_question", "label": "Question"} ) surv.add_child(q) i = surv.instantiate() self.assertEquals(i.keys(), ["survey_question"]) self.assertEquals(set(i.xpaths()), {"/Simple", "/Simple/survey_question"})
def test_output_node_for_select_one_question_type(self): self.this_directory = os.path.dirname(__file__) survey_out = Survey(name="geopgraphy", sms_keyword="geography", type="survey") question = InputQuestion(name="counties") question.type = "select one external" question.label = "county" survey_out.add_child(question) expected = '<input ref="/geopgraphy/counties">' xml = survey_out.to_xml() self.assertEqual(1, xml.count(expected))
def test_simple_survey_instantiation(self): surv = Survey(name="Simple") q = create_survey_element_from_dict({ "type": "text", "name": "survey_question", "label": "Question" }) surv.add_child(q) i = surv.instantiate() self.assertEquals(i.keys(), ["survey_question"]) self.assertEquals(set(i.xpaths()), {"/Simple", "/Simple/survey_question"})
def _load_registration_survey_object(): """ Loads a registration survey with all the values necessary to register a surveyor. """ survey = Survey(name="registration", id_string="registration") survey.add_child( create_survey_element_from_dict({ 'type': 'text', 'name': 'name', 'label': 'Name' })) survey.add_child( create_survey_element_from_dict({ 'type': 'start time', 'name': 'start' })) survey.add_child( create_survey_element_from_dict({ 'type': 'end time', 'name': 'end' })) survey.add_child( create_survey_element_from_dict({ 'type': 'imei', 'name': 'device_id' })) return survey
def test_answers_can_be_imported_from_xml(self): surv = Survey(name="data") surv.add_child( create_survey_element_from_dict( {"type": "text", "name": "name", "label": "Name"} ) ) surv.add_child( create_survey_element_from_dict( { "type": "integer", "name": "users_per_month", "label": "Users per month", } ) ) surv.add_child( create_survey_element_from_dict( {"type": "gps", "name": "geopoint", "label": "gps"} ) ) surv.add_child( create_survey_element_from_dict({"type": "imei", "name": "device_id"}) ) instance = surv.instantiate() import_xml = self.config.get( self.cls_name, "test_answers_can_be_imported_from_xml" ) instance.import_from_xml(import_xml)
def test_answers_can_be_imported_from_xml(self): surv = Survey(name="data") surv.add_child( create_survey_element_from_dict({ "type": "text", "name": "name", "label": "Name" })) surv.add_child( create_survey_element_from_dict({ "type": "integer", "name": "users_per_month", "label": "Users per month", })) surv.add_child( create_survey_element_from_dict({ "type": "gps", "name": "geopoint", "label": "gps" })) surv.add_child( create_survey_element_from_dict({ "type": "imei", "name": "device_id" })) instance = surv.instantiate() import_xml = self.config.get(self.cls_name, "test_answers_can_be_imported_from_xml") instance.import_from_xml(import_xml)
def test_simple_registration_xml(self): reg_xform = Survey(name="Registration") name_question = create_survey_element_from_dict( {"type": "text", "name": "name", "label": "Name"} ) reg_xform.add_child(name_question) reg_instance = reg_xform.instantiate() reg_instance.answer(name="name", value="bob") rx = reg_instance.to_xml() expected_xml = self.config.get( self.cls_name, "test_simple_registration_xml" ).format(reg_xform.id_string) self.assertEqual(rx, expected_xml)
def test_simple_survey_answering(self): surv = Survey(name="Water") q = create_survey_element_from_dict( {"type": "text", "name": "color", "label": "Color"} ) q2 = create_survey_element_from_dict( {"type": "text", "name": "feeling", "label": "Feeling"} ) surv.add_child(q) surv.add_child(q2) i = SurveyInstance(surv) i.answer(name="color", value="blue") self.assertEquals(i.answers()["color"], "blue") i.answer(name="feeling", value="liquidy") self.assertEquals(i.answers()["feeling"], "liquidy")
def test_simple_registration_xml(self): reg_xform = Survey(name="Registration") name_question = create_survey_element_from_dict({ "type": "text", "name": "name", "label": "Name" }) reg_xform.add_child(name_question) reg_instance = reg_xform.instantiate() reg_instance.answer(name="name", value="bob") rx = reg_instance.to_xml() expected_xml = self.config.get(self.cls_name, "test_simple_registration_xml").format( reg_xform.id_string) self.assertEqual(rx, expected_xml)
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()
def test_simple_survey_answering(self): surv = Survey(name="Water") q = create_survey_element_from_dict({ "type": "text", "name": "color", "label": "Color" }) q2 = create_survey_element_from_dict({ "type": "text", "name": "feeling", "label": "Feeling" }) surv.add_child(q) surv.add_child(q2) i = SurveyInstance(surv) i.answer(name="color", value="blue") self.assertEquals(i.answers()["color"], "blue") i.answer(name="feeling", value="liquidy") self.assertEquals(i.answers()["feeling"], "liquidy")
def test_survey_can_be_created_in_a_verbose_manner(self): s = Survey() s.name = "simple_survey" q = MultipleChoiceQuestion() q.name = "cow_color" q.type = "select one" q.add_choice(label="Green", name="green") s.add_child(q) expected_dict = { "name": "simple_survey", "children": [ { "name": "cow_color", "type": "select one", "children": [{"label": "Green", "name": "green"}], } ], } self.maxDiff = None self.assertEqual(s.to_json_dict(), expected_dict)
def _load_registration_survey_object(): """ Loads a registration survey with all the values necessary to register a surveyor. """ survey = Survey(name=u"registration", id_string=u"registration") survey.add_child(create_survey_element_from_dict({ u'type': u'text', u'name': u'name', u'label': u'Name' })) survey.add_child(create_survey_element_from_dict({ u'type': u'start time', u'name': u'start' })) survey.add_child(create_survey_element_from_dict({ u'type': u'end time', u'name': u'end' })) survey.add_child(create_survey_element_from_dict({ u'type': u'imei', u'name': u'device_id' })) return survey
def _load_simple_survey_object(): """ Returns a "watersimple" survey object, complete with questions. """ survey = Survey(name="WaterSimple", id_string="WaterSimple") survey.add_child( create_survey_element_from_dict({ 'hint': { 'English': 'What is this point named?' }, 'label': { 'English': 'Water Point Name' }, 'type': 'text', 'name': 'name' })) survey.add_child( create_survey_element_from_dict({ 'hint': { 'English': 'How many people use this every month?' }, 'label': { 'English': 'Monthly Usage' }, 'name': 'users_per_month', 'type': 'integer' })) survey.add_child( create_survey_element_from_dict({ 'type': 'gps', 'name': 'geopoint', 'label': { 'English': 'Location' } })) survey.add_child( create_survey_element_from_dict({ 'type': 'imei', 'name': 'device_id' })) survey.add_child( create_survey_element_from_dict({ 'type': 'start time', 'name': 'start' })) survey.add_child( create_survey_element_from_dict({ 'type': 'end time', 'name': 'end' })) return survey
def _load_simple_survey_object(): """ Returns a "watersimple" survey object, complete with questions. """ survey = Survey(name=u"WaterSimple", id_string=u"WaterSimple") survey.add_child(create_survey_element_from_dict({ u'hint': {u'English': u'What is this point named?'}, u'label': {u'English': u'Water Point Name'}, u'type': u'text', u'name': u'name' })) survey.add_child(create_survey_element_from_dict({ u'hint': {u'English': u'How many people use this every month?'}, u'label': {u'English': u'Monthly Usage'}, u'name': u'users_per_month', u'type': u'integer' })) survey.add_child(create_survey_element_from_dict({ u'type': u'gps', u'name': u'geopoint', u'label': {u'English': u'Location'} })) survey.add_child(create_survey_element_from_dict({ u'type': u'imei', u'name': u'device_id' })) survey.add_child(create_survey_element_from_dict({ u'type': u'start time', u'name': u'start' })) survey.add_child(create_survey_element_from_dict({ u'type': u'end time', u'name': u'end' })) return survey
class Json2XformQuestionValidationTests(TestCase): maxDiff = None config = None cls_name = None @classmethod def setUpClass(cls): prep_class_config(cls=cls) def setUp(self): self.s = Survey(name="test") def test_question_type_string(self): simple_string_json = { "label": { "French": "Nom du travailleur agricole:", "English": "Name of Community Agricultural Worker", }, "type": "text", "name": "enumerator_name", } q = create_survey_element_from_dict(simple_string_json) expected_string_control_xml = self.config.get( self.cls_name, "test_question_type_string_control") expected_string_binding_xml = self.config.get( self.cls_name, "test_question_type_string_binding") self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_string_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_string_binding_xml) def test_select_one_question_multilingual(self): """ Test the lowest common denominator of question types. """ simple_select_one_json = { "label": { "f": "ftext", "e": "etext" }, "type": "select one", "name": "qname", "choices": [ { "label": { "f": "fa", "e": "ea" }, "name": "a" }, { "label": { "f": "fb", "e": "eb" }, "name": "b" }, ], } # I copied the response in, since this is not our method of testing # valid return values. expected_select_one_control_xml = self.config.get( self.cls_name, "test_select_one_question_multilingual_control") expected_select_one_binding_xml = self.config.get( self.cls_name, "test_select_one_question_multilingual_binding") q = create_survey_element_from_dict(simple_select_one_json) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_one_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_one_binding_xml) def test_simple_integer_question_type_multilingual(self): """ not sure how integer questions should show up. """ simple_integer_question = { "label": { "f": "fc", "e": "ec" }, "type": "integer", "name": "integer_q", "attributes": {}, } expected_integer_control_xml = self.config.get( self.cls_name, "test_simple_integer_question_type_multilingual_control") expected_integer_binding_xml = self.config.get( self.cls_name, "test_simple_integer_question_type_multilingual_binding") q = create_survey_element_from_dict(simple_integer_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_integer_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_integer_binding_xml) def test_simple_date_question_type_multilingual(self): """ not sure how date questions should show up. """ simple_date_question = { "label": { "f": "fd", "e": "ed" }, "type": "date", "name": "date_q", "attributes": {}, } expected_date_control_xml = self.config.get( self.cls_name, "test_simple_date_question_type_multilingual_control") expected_date_binding_xml = self.config.get( self.cls_name, "test_simple_date_question_type_multilingual_binding") q = create_survey_element_from_dict(simple_date_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_date_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_date_binding_xml) def test_simple_phone_number_question_type_multilingual(self): """ not sure how phone number questions should show up. """ simple_phone_number_question = { "label": { "f": "fe", "e": "ee" }, "type": "phone number", "name": "phone_number_q", } expected_phone_number_control_xml = self.config.get( self.cls_name, "test_simple_phone_number_question_type_multilingual_control") expected_phone_number_binding_xml = self.config.get( self.cls_name, "test_simple_phone_number_question_type_multilingual_binding") q = create_survey_element_from_dict(simple_phone_number_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_phone_number_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_phone_number_binding_xml) def test_simple_select_all_question_multilingual(self): """ not sure how select all questions should show up... """ simple_select_all_question = { "label": { "f": "f choisit", "e": "e choose" }, "type": "select all that apply", "name": "select_all_q", "choices": [ { "label": { "f": "ff", "e": "ef" }, "name": "f" }, { "label": { "f": "fg", "e": "eg" }, "name": "g" }, { "label": { "f": "fh", "e": "eh" }, "name": "h" }, ], } expected_select_all_control_xml = self.config.get( self.cls_name, "test_simple_select_all_question_multilingual_control") expected_select_all_binding_xml = self.config.get( self.cls_name, "test_simple_select_all_question_multilingual_binding") q = create_survey_element_from_dict(simple_select_all_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_all_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_all_binding_xml) def test_simple_decimal_question_multilingual(self): """ not sure how decimal should show up. """ simple_decimal_question = { "label": { "f": "f text", "e": "e text" }, "type": "decimal", "name": "decimal_q", "attributes": {}, } expected_decimal_control_xml = self.config.get( self.cls_name, "test_simple_decimal_question_multilingual_control") expected_decimal_binding_xml = self.config.get( self.cls_name, "test_simple_decimal_question_multilingual_binding") q = create_survey_element_from_dict(simple_decimal_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_decimal_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_decimal_binding_xml)
class Json2XformQuestionValidationTests(TestCase): maxDiff = None @classmethod def setUpClass(cls): prep_class_config(cls=cls) def setUp(self): self.s = Survey(name="test") def test_question_type_string(self): simple_string_json = { "label": { "French": "Nom du travailleur agricole:", "English": "Name of Community Agricultural Worker", }, "type": "text", "name": "enumerator_name", } q = create_survey_element_from_dict(simple_string_json) expected_string_control_xml = self.config.get( self.cls_name, "test_question_type_string_control" ) expected_string_binding_xml = self.config.get( self.cls_name, "test_question_type_string_binding" ) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_string_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_string_binding_xml) def test_select_one_question_multilingual(self): """ Test the lowest common denominator of question types. """ simple_select_one_json = { "label": {"f": "ftext", "e": "etext"}, "type": "select one", "name": "qname", "choices": [ {"label": {"f": "fa", "e": "ea"}, "name": "a"}, {"label": {"f": "fb", "e": "eb"}, "name": "b"}, ], } # I copied the response in, since this is not our method of testing # valid return values. expected_select_one_control_xml = self.config.get( self.cls_name, "test_select_one_question_multilingual_control" ) expected_select_one_binding_xml = self.config.get( self.cls_name, "test_select_one_question_multilingual_binding" ) q = create_survey_element_from_dict(simple_select_one_json) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_one_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_one_binding_xml) def test_simple_integer_question_type_multilingual(self): """ not sure how integer questions should show up. """ simple_integer_question = { "label": {"f": "fc", "e": "ec"}, "type": "integer", "name": "integer_q", "attributes": {}, } expected_integer_control_xml = self.config.get( self.cls_name, "test_simple_integer_question_type_multilingual_control" ) expected_integer_binding_xml = self.config.get( self.cls_name, "test_simple_integer_question_type_multilingual_binding" ) q = create_survey_element_from_dict(simple_integer_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_integer_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_integer_binding_xml) def test_simple_date_question_type_multilingual(self): """ not sure how date questions should show up. """ simple_date_question = { "label": {"f": "fd", "e": "ed"}, "type": "date", "name": "date_q", "attributes": {}, } expected_date_control_xml = self.config.get( self.cls_name, "test_simple_date_question_type_multilingual_control" ) expected_date_binding_xml = self.config.get( self.cls_name, "test_simple_date_question_type_multilingual_binding" ) q = create_survey_element_from_dict(simple_date_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_date_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_date_binding_xml) def test_simple_phone_number_question_type_multilingual(self): """ not sure how phone number questions should show up. """ simple_phone_number_question = { "label": {"f": "fe", "e": "ee"}, "type": "phone number", "name": "phone_number_q", } expected_phone_number_control_xml = self.config.get( self.cls_name, "test_simple_phone_number_question_type_multilingual_control" ) expected_phone_number_binding_xml = self.config.get( self.cls_name, "test_simple_phone_number_question_type_multilingual_binding" ) q = create_survey_element_from_dict(simple_phone_number_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_phone_number_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_phone_number_binding_xml) def test_simple_select_all_question_multilingual(self): """ not sure how select all questions should show up... """ simple_select_all_question = { "label": {"f": "f choisit", "e": "e choose"}, "type": "select all that apply", "name": "select_all_q", "choices": [ {"label": {"f": "ff", "e": "ef"}, "name": "f"}, {"label": {"f": "fg", "e": "eg"}, "name": "g"}, {"label": {"f": "fh", "e": "eh"}, "name": "h"}, ], } expected_select_all_control_xml = self.config.get( self.cls_name, "test_simple_select_all_question_multilingual_control" ) expected_select_all_binding_xml = self.config.get( self.cls_name, "test_simple_select_all_question_multilingual_binding" ) q = create_survey_element_from_dict(simple_select_all_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_select_all_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_select_all_binding_xml) def test_simple_decimal_question_multilingual(self): """ not sure how decimal should show up. """ simple_decimal_question = { "label": {"f": "f text", "e": "e text"}, "type": "decimal", "name": "decimal_q", "attributes": {}, } expected_decimal_control_xml = self.config.get( self.cls_name, "test_simple_decimal_question_multilingual_control" ) expected_decimal_binding_xml = self.config.get( self.cls_name, "test_simple_decimal_question_multilingual_binding" ) q = create_survey_element_from_dict(simple_decimal_question) self.s.add_child(q) self.assertEqual(ctw(q.xml_control()), expected_decimal_control_xml) if TESTING_BINDINGS: self.assertEqual(ctw(q.xml_binding()), expected_decimal_binding_xml)
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()