def _build_app_with_groups(self, factory): module1, form1 = factory.new_basic_module('open_case', 'household') form1_builder = XFormBuilder(form1.name) # question 0 form1_builder.new_question('name', 'Name') # question 1 (a group) form1_builder.new_group('demographics', 'Demographics') # question 2 (a question in a group) form1_builder.new_question('age', 'Age', group='demographics') # question 3 (a question that has a load property) form1_builder.new_question('polar_bears_seen', 'Number of polar bears seen') form1.source = form1_builder.tostring( pretty_print=True).decode('utf-8') factory.form_requires_case(form1, case_type='household', update={ 'name': '/data/name', 'age': '/data/demographics/age', }, preload={ '/data/polar_bears_seen': 'polar_bears_seen', }) factory.app.save()
def get_form_source(form_name_): xform = XFormBuilder(form_name_) # We want to know the time according to the user, but event start and end timestamps are actually # determined from form submission times. xform.new_question('start_date', 'Start Date', data_type='date') xform.new_question('start_time', 'Start Time', data_type='time') xform.new_question( 'subject_name', None, data_type=None) # data_type=None makes this a hidden value xform.new_question( 'event_type', None, data_type=None, value="'{}'".format( self.unique_id)) # Quote string default values xform.new_question('event_repeats', None, data_type=None, value="'{}'".format(self.is_repeating).lower()) xform.new_question( 'name', None, data_type=None, calculate= "concat('{} ', /data/start_date, ' ', /data/start_time, " "' (', /data/subject_name, ')')".format(self.name)) for study_form in self.iter_forms(): study_form.add_item_groups_to_xform(xform) xform.new_question('end_date', 'End Date', data_type='date') xform.new_question('end_time', 'End Time', data_type='time') return xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True).decode('utf-8')
def build_xform(self): xform = XFormBuilder(self.name) xform.new_question('start_date', 'Start Date', data_type='date') xform.new_question('start_time', 'Start Time', data_type='time') self.add_item_groups_to_xform(xform) xform.new_question('end_date', 'End Date', data_type='date') xform.new_question('end_time', 'End Time', data_type='time') return xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True).decode('utf-8')
def build_xform(self): xform = XFormBuilder(self.name) xform.new_question('start_date', 'Start Date', data_type='date') xform.new_question('start_time', 'Start Time', data_type='time') self.add_item_groups_to_xform(xform) xform.new_question('end_date', 'End Date', data_type='date') xform.new_question('end_time', 'End Time', data_type='time') return xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)
def build_xform(self): xform = XFormBuilder(self.name) for ig in self.iter_item_groups(): data_type = 'repeatGroup' if self.is_repeating else 'group' group = xform.new_group(ig.question_name, ig.question_label, data_type) for item in ig.iter_items(): group.new_question(item.question_name, item.question_label, ODK_DATA_TYPES[item.data_type], choices=item.choices) return xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)
def setUp(self): self.domain = 'test-domain' self.factory = AppFactory(build_version='2.51.0', domain=self.domain) self.parent_case_type = 'mother' self.module, self.form = self.factory.new_advanced_module( 'advanced', self.parent_case_type) builder = XFormBuilder(self.form.name) builder.new_question(name='name', label='Name') self.form.source = builder.tostring(pretty_print=True).decode('utf-8')
def get_subject_form_source(name): """ Return a registration form that mimics OpenClinica subject registration """ xform = XFormBuilder(name) xform.new_question(CC_SUBJECT_KEY, 'Person ID') # Unique ID. aka "Screening Number", "Subject Key" xform.new_question(CC_STUDY_SUBJECT_ID, 'Subject Study ID') # Subject number for this study xform.new_question(CC_DOB, 'Date of Birth', data_type='date') xform.new_question(CC_SEX, 'Sex', data_type='select1', choices={1: 'Male', 2: 'Female'}) xform.new_question(CC_ENROLLMENT_DATE, 'Enrollment Date', data_type='date') return xform.tostring(pretty_print=True)
def get_subject_form_source(name): """ Return a registration form that mimics OpenClinica subject registration """ xform = XFormBuilder(name) xform.new_question('name', 'Person ID') # Subject's unique ID. aka "Screening Number", "Subject Key" xform.new_question('subject_study_id', 'Subject Study ID') # Subject number for this study xform.new_question('dob', 'Date of Birth', data_type='date') xform.new_question('sex', 'Sex', data_type='int', choices={1: 'Male', 2: 'Female'}) xform.new_question('enrollment_date', 'Enrollment Date', data_type='date') return xform.tostring(pretty_print=True)
def _add_question(self, form, options=None): if options is None: options = {'name': 'name', 'label': "Name"} if 'name' not in options: options['name'] = 'name' if 'label' not in options: options['label'] = "Name" builder = XFormBuilder(form.name, form.source if form.source else None) builder.new_question(**options) form.source = builder.tostring(pretty_print=True).decode('utf-8')
def get_subject_form_source(name): """ Return a registration form that mimics OpenClinica subject registration """ xform = XFormBuilder(name) xform.new_question(CC_SUBJECT_KEY, 'Person ID') # Unique ID. aka "Screening Number", "Subject Key" xform.new_question(CC_STUDY_SUBJECT_ID, 'Subject Study ID') # Subject number for this study xform.new_question(CC_DOB, 'Date of Birth', data_type='date') xform.new_question(CC_SEX, 'Sex', data_type='select1', choices={1: 'Male', 2: 'Female'}) xform.new_question(CC_ENROLLMENT_DATE, 'Enrollment Date', data_type='date') return xform.tostring(pretty_print=True).decode('utf-8')
def get_simple_xform(): xform = XFormBuilder() xform.new_question('first_name', 'First Name', data_type='string') xform.new_question('last_name', 'Last Name', data_type='string') xform.new_question('children', 'Children', data_type='int') xform.new_question('dob', 'Date of Birth', data_type='date') xform.new_question('state', 'State', data_type='select', choices={ 'MA': 'MA', 'MN': 'MN', 'VT': 'VT', }) return xform.tostring().decode('utf-8')
def test_form_data_with_case_properties(self): factory = AppFactory() app = factory.app module1, form1 = factory.new_basic_module('open_case', 'household') form1_builder = XFormBuilder(form1.name) # question 0 form1_builder.new_question('name', 'Name') # question 1 (a group) form1_builder.new_group('demographics', 'Demographics') # question 2 (a question in a group) form1_builder.new_question('age', 'Age', group='demographics') # question 3 (a question that has a load property) form1_builder.new_question('polar_bears_seen', 'Number of polar bears seen') form1.source = form1_builder.tostring( pretty_print=True).decode('utf-8') factory.form_requires_case(form1, case_type='household', update={ 'name': '/data/name', 'age': '/data/demographics/age', }, preload={ '/data/polar_bears_seen': 'polar_bears_seen', }) app.save() modules, errors = get_app_summary_formdata(app.domain, app) q1_saves = modules[0]['forms'][0]['questions'][0]['save_properties'][0] self.assertEqual(q1_saves.case_type, 'household') self.assertEqual(q1_saves.property, 'name') group_saves = modules[0]['forms'][0]['questions'][2][ 'save_properties'][0] self.assertEqual(group_saves.case_type, 'household') self.assertEqual(group_saves.property, 'age') q3_loads = modules[0]['forms'][0]['questions'][3]['load_properties'][0] self.assertEqual(q3_loads.case_type, 'household') self.assertEqual(q3_loads.property, 'polar_bears_seen')
def get_form_source(form_name_): xform = XFormBuilder(form_name_) # We want to know the time according to the user, but event start and end timestamps are actually # determined from form submission times. xform.new_question('start_date', 'Start Date', data_type='date') xform.new_question('start_time', 'Start Time', data_type='time') xform.new_question('subject_name', None, data_type=None) # data_type=None makes this a hidden value xform.new_question('event_type', None, data_type=None, value="'{}'".format(self.unique_id)) # Quote string default values xform.new_question('event_repeats', None, data_type=None, value="'{}'".format(self.is_repeating).lower()) xform.new_question('name', None, data_type=None, calculate="concat('{} ', /data/start_date, ' ', /data/start_time, " "' (', /data/subject_name, ')')".format(self.name)) for study_form in self.iter_forms(): study_form.add_item_groups_to_xform(xform) xform.new_question('end_date', 'End Date', data_type='date') xform.new_question('end_time', 'End Time', data_type='time') return xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True).decode('utf-8')
def setUp(self): self.domain = 'test-domain' self.factory = AppFactory(build_version='2.40.0', domain=self.domain) self.module, self.form = self.factory.new_basic_module( 'basic', 'patient') builder = XFormBuilder(self.form.name) builder.new_question(name='name', label='Name') self.form.source = builder.tostring(pretty_print=True).decode('utf-8') image_path = os.path.join('corehq', 'apps', 'hqwebapp', 'static', 'hqwebapp', 'images', 'favicon.png') with open(image_path, 'rb') as f: image_data = f.read() self.image = CommCareImage.get_by_data(image_data) self.image.attach_data(image_data, original_filename='icon.png') self.image.add_domain(self.domain) self.image.save() self.addCleanup(self.image.delete)
def _build_app_with_groups(self, factory): module1, form1 = factory.new_basic_module('open_case', 'household') form1_builder = XFormBuilder(form1.name) # question 0 form1_builder.new_question('name', 'Name') # question 1 (a group) form1_builder.new_group('demographics', 'Demographics') # question 2 (a question in a group) form1_builder.new_question('age', 'Age', group='demographics') # question 3 (a question that has a load property) form1_builder.new_question('polar_bears_seen', 'Number of polar bears seen') form1.source = form1_builder.tostring(pretty_print=True).decode('utf-8') factory.form_requires_case(form1, case_type='household', update={ 'name': '/data/name', 'age': '/data/demographics/age', }, preload={ '/data/polar_bears_seen': 'polar_bears_seen', }) factory.app.save()
def setUpClass(cls): cls.factory = AppFactory(domain=cls.domain) cls.app = cls.factory.app cls.module, cls.basic_form = cls.factory.new_basic_module( 'basic', 'patient') # necessary to render_xform builder = XFormBuilder(cls.basic_form.name) builder.new_question(name='name', label='Name') cls.basic_form.source = builder.tostring( pretty_print=True).decode('utf-8') cls.phone_number = "+919999999999" cls.case_id = uuid.uuid4().hex cls.recipient = None cls.case = CommCareCaseSQL(domain=cls.domain, case_id=cls.case_id, case_json={'language_code': 'fr'}) cls.web_user = WebUser(username='******', _id=uuid.uuid4().hex, language='hin')
def _get_xform(cls): xform = XFormBuilder() for prop_name, prop_text, datatype, _ in cls.case_properties: xform.new_question(prop_name, prop_text, data_type=datatype) return xform.tostring().decode('utf-8')
def _add_question_to_group(self, form, options): builder = XFormBuilder(form.name, form.source if form.source else None) group_name = options['group'] builder.new_group(group_name, group_name) builder.new_question(**options) form.source = builder.tostring(pretty_print=True).decode('utf-8')
class XFormBuilderTests(SimpleTestCase, TestXmlMixin): file_path = ('data', 'xform_builder') def setUp(self): self.xform = XFormBuilder() def replace_xmlns(self, xml, xmlns): xmlns = xmlns.encode('utf-8') return re.sub(br'http://openrosa\.org/formdesigner/[\w-]{36}', xmlns, xml) def test_new_question_group(self): """ XFormBuilder.new_question should be able to add a group """ self.xform.new_question('personal', 'Personal Questions', data_type='group') self.xform.new_question('name', 'What is your name?', group='personal') self.assertXmlEqual( self.replace_xmlns(self.get_xml('group'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)) def test_new_question_repeat_group(self): num_names = self.xform.new_question('num_names', 'How many names do you have?', data_type='int') self.xform.new_question('personal', 'Personal Questions', data_type='repeatGroup', repeat_count=num_names) self.xform.new_question( 'name', 'What is your <output value="ordinal(position(..) + 1)" /> name?', group='personal', label_safe=True) # Yes, that was plug for an ordinal function. cf. UserVoice: # https://dimagi.uservoice.com/forums/176376-form-builder/suggestions/10610517--ordinal-function self.assertXmlEqual( self.replace_xmlns(self.get_xml('repeat_group'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)) def test_new_group_group(self): personal = self.xform.new_group('personal', 'Personal Questions') personal.new_question('name', 'What is your name?') self.assertXmlEqual( self.replace_xmlns(self.get_xml('group'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)) def test_new_group_repeat_group(self): num_names = self.xform.new_question('num_names', 'How many names do you have?', data_type='int') personal = self.xform.new_group('personal', 'Personal Questions', data_type='repeatGroup', repeat_count=num_names) personal.new_question( 'name', 'What is your <output value="ordinal(position(..) + 1)" /> name?', label_safe=True) self.assertXmlEqual( self.replace_xmlns(self.get_xml('repeat_group'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)) def test_unicode(self): self.xform.new_question('name', 'သင့်နာမည်ဘယ်လိုခေါ်လဲ?' ) # ("What is your name?" in Myanmar/Burmese) self.assertXmlEqual( self.replace_xmlns(self.get_xml('unicode'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)) def test_select_question(self): self.xform.new_question('fav_colors', 'What are your favorite colors?', data_type='select', choices=OrderedDict([ ('r', 'Red'), ('o', 'Orange'), ('y', 'Yellow'), ('g', 'Green'), ('b', 'Blue'), ('i', 'Indigo'), ('v', 'Violet'), ])) self.assertXmlEqual( self.replace_xmlns(self.get_xml('select_question'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)) def test_select1_question(self): self.xform.new_question('you_aint_been_blue', 'What kind of blue are you?', data_type='select1', choices={ 1: 'Blue', 2: 'Indigo', 3: 'Black', }) self.assertXmlEqual( self.replace_xmlns(self.get_xml('select1_question'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)) def test_data_types(self): self.xform.new_question('name', 'Child name') self.xform.new_question('dob', 'Child date of birth', 'date') self.xform.new_question('with_mother', 'Does child live with mother?', 'boolean', value='true') self.xform.new_question('height', 'Child height (cm)', 'int') self.xform.new_question('weight', 'Child weight (metric tonnes)', 'decimal') self.xform.new_question('time', 'Arrival time', 'time') self.xform.new_question('now', 'Current timestamp', 'dateTime') self.xform.new_question( 'mothers_name', None, None, # Hidden values have no data type calculate="concat('Jane', ' ', 'Smith')") self.assertXmlEqual( self.replace_xmlns(self.get_xml('data_types'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)) def test_xform_title(self): self.xform = XFormBuilder('Built by XFormBuilder') self.xform.new_question('name', 'What is your name?') group = self.xform.new_group('personal', 'Personal Questions') group.new_question('fav_color', 'Quelle est ta couleur préférée?', choices=OrderedDict([('r', 'Rot'), ('b', 'Blau'), ('g', 'Grün')])) self.assertXmlEqual( self.replace_xmlns(self.get_xml('xform_title'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True)) def test_question_params(self): self.xform = XFormBuilder('Built by XFormBuilder') params = { 'constraint': ". != 'Ford Prefect'", 'jr:constraintMsg': 'That name is not as inconspicuous as you think.' } self.xform.new_question('name', 'What is your name?', **params) self.assertXmlEqual( self.replace_xmlns(self.get_xml('question_params'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True))
def test_get_data_cleaning_data(self, questions_patch): builder = XFormBuilder() responses = OrderedDict() # Simple question builder.new_question('something', 'Something') responses['something'] = 'blue' # Skipped question - doesn't appear in repsonses, shouldn't appear in data cleaning data builder.new_question('skip', 'Skip me') # Simple group lights = builder.new_group('lights', 'Traffic Lights', data_type='group') lights.new_question('red', 'Red means') lights.new_question('green', 'Green means') responses['lights'] = OrderedDict([('red', 'stop'), ('green', 'go')]) # Simple repeat group, one response one_hit_wonders = builder.new_group('one_hit_wonders', 'One-Hit Wonders', data_type='repeatGroup') one_hit_wonders.new_question('name', 'Name') responses['one_hit_wonders'] = [ { 'name': 'A-Ha' }, ] # Simple repeat group, multiple responses snacks = builder.new_group('snacks', 'Snacks', data_type='repeatGroup') snacks.new_question('kind_of_snack', 'Kind of snack') responses['snacks'] = [ { 'kind_of_snack': 'samosa' }, { 'kind_of_snack': 'pakora' }, ] # Repeat group with nested group cups = builder.new_group('cups_of_tea', 'Cups of tea', data_type='repeatGroup') details = cups.new_group('details_of_cup', 'Details', data_type='group') details.new_question('kind_of_cup', 'Flavor') details.new_question('secret', 'Secret', data_type=None) responses['cups_of_tea'] = [ { 'details_of_cup': { 'kind_of_cup': 'green', 'secret': 'g' } }, { 'details_of_cup': { 'kind_of_cup': 'black', 'secret': 'b' } }, { 'details_of_cup': { 'kind_of_cup': 'more green', 'secret': 'mg' } }, ] xform = XForm(builder.tostring()) questions_patch.return_value = get_questions_from_xform_node( xform, ['en']) xml = FormSubmissionBuilder(form_id='123', form_properties=responses).as_xml_string() submitted_xform = submit_form_locally(xml, self.domain).xform form_data, _ = get_readable_data_for_submission(submitted_xform) question_response_map, ordered_question_values = get_data_cleaning_data( form_data, submitted_xform) expected_question_values = [ '/data/something', '/data/lights/red', '/data/lights/green', '/data/one_hit_wonders/name', '/data/snacks[1]/kind_of_snack', '/data/snacks[2]/kind_of_snack', '/data/cups_of_tea[1]/details_of_cup/kind_of_cup', '/data/cups_of_tea[1]/details_of_cup/secret', '/data/cups_of_tea[2]/details_of_cup/kind_of_cup', '/data/cups_of_tea[2]/details_of_cup/secret', '/data/cups_of_tea[3]/details_of_cup/kind_of_cup', '/data/cups_of_tea[3]/details_of_cup/secret', ] self.assertListEqual(ordered_question_values, expected_question_values) expected_response_map = { '/data/something': 'blue', '/data/lights/red': 'stop', '/data/lights/green': 'go', '/data/one_hit_wonders/name': 'A-Ha', '/data/snacks[1]/kind_of_snack': 'samosa', '/data/snacks[2]/kind_of_snack': 'pakora', '/data/cups_of_tea[1]/details_of_cup/kind_of_cup': 'green', '/data/cups_of_tea[1]/details_of_cup/secret': 'g', '/data/cups_of_tea[2]/details_of_cup/kind_of_cup': 'black', '/data/cups_of_tea[2]/details_of_cup/secret': 'b', '/data/cups_of_tea[3]/details_of_cup/kind_of_cup': 'more green', '/data/cups_of_tea[3]/details_of_cup/secret': 'mg', } self.assertDictEqual( {k: v['value'] for k, v in question_response_map.items()}, expected_response_map)
class XFormBuilderTests(SimpleTestCase, TestXmlMixin): file_path = ('data', 'xform_builder') def setUp(self): self.xform = XFormBuilder() def replace_xmlns(self, xml, xmlns): return re.sub(r'http://openrosa\.org/formdesigner/[\w-]{36}', xmlns, xml) def test_new_question_group(self): """ XFormBuilder.new_question should be able to add a group """ self.xform.new_question('personal', 'Personal Questions', data_type='group') self.xform.new_question('name', 'What is your name?', group='personal') self.assertXmlEqual( self.replace_xmlns(self.get_xml('group'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) ) def test_new_question_repeat_group(self): num_names = self.xform.new_question('num_names', 'How many names do you have?', data_type='int') self.xform.new_question('personal', 'Personal Questions', data_type='repeatGroup', repeat_count=num_names) self.xform.new_question('name', 'What is your <output value="ordinal(position(..) + 1)" /> name?', group='personal', label_safe=True) # Yes, that was plug for an ordinal function. cf. UserVoice: # https://dimagi.uservoice.com/forums/176376-form-builder/suggestions/10610517--ordinal-function self.assertXmlEqual( self.replace_xmlns(self.get_xml('repeat_group'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) ) def test_new_group_group(self): personal = self.xform.new_group('personal', 'Personal Questions') personal.new_question('name', 'What is your name?') self.assertXmlEqual( self.replace_xmlns(self.get_xml('group'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) ) def test_new_group_repeat_group(self): num_names = self.xform.new_question('num_names', 'How many names do you have?', data_type='int') personal = self.xform.new_group('personal', 'Personal Questions', data_type='repeatGroup', repeat_count=num_names) personal.new_question('name', 'What is your <output value="ordinal(position(..) + 1)" /> name?', label_safe=True) self.assertXmlEqual( self.replace_xmlns(self.get_xml('repeat_group'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) ) def test_unicode(self): self.xform.new_question('name', u'သင့်နာမည်ဘယ်လိုခေါ်လဲ?') # ("What is your name?" in Myanmar/Burmese) self.assertXmlEqual( self.replace_xmlns(self.get_xml('unicode'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) ) def test_select_question(self): self.xform.new_question('fav_colors', 'What are your favorite colors?', data_type='select', choices={ 'r': 'Red', 'o': 'Orange', 'y': 'Yellow', 'g': 'Green', 'b': 'Blue', 'i': 'Indigo', 'v': 'Violet', }) self.assertXmlEqual( self.replace_xmlns(self.get_xml('select_question'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) ) def test_select1_question(self): self.xform.new_question('you_aint_been_blue', 'What kind of blue are you?', data_type='select1', choices={ 1: 'Blue', 2: 'Indigo', 3: 'Black', }) self.assertXmlEqual( self.replace_xmlns(self.get_xml('select1_question'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) ) def test_data_types(self): self.xform.new_question('name', 'Child name') self.xform.new_question('dob', 'Child date of birth', 'date') self.xform.new_question('with_mother', 'Does child live with mother?', 'boolean', value='true') self.xform.new_question('height', 'Child height (cm)', 'int') self.xform.new_question('weight', 'Child weight (metric tonnes)', 'decimal') self.xform.new_question('time', 'Arrival time', 'time') self.xform.new_question('now', 'Current timestamp', 'dateTime') self.xform.new_question('mothers_name', None, None, # Hidden values have no data type calculate="concat('Jane', ' ', 'Smith')") self.assertXmlEqual( self.replace_xmlns(self.get_xml('data_types'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) ) def test_xform_title(self): self.xform = XFormBuilder('Built by XFormBuilder') self.xform.new_question('name', 'What is your name?') group = self.xform.new_group('personal', 'Personal Questions') group.new_question('fav_color', u'Quelle est ta couleur préférée?', choices={'r': 'Rot', 'g': u'Grün', 'b': 'Blau'}) self.assertXmlEqual( self.replace_xmlns(self.get_xml('xform_title'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) ) def test_question_params(self): self.xform = XFormBuilder('Built by XFormBuilder') params = { 'constraint': ". != 'Ford Prefect'", 'jr:constraintMsg': 'That name is not as inconspicuous as you think.' } self.xform.new_question('name', 'What is your name?', **params) self.assertXmlEqual( self.replace_xmlns(self.get_xml('question_params'), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding='utf-8', xml_declaration=True) )
def test_get_data_cleaning_data(self, questions_patch): builder = XFormBuilder() responses = OrderedDict() # Simple question builder.new_question('something', 'Something') responses['something'] = 'blue' # Skipped question - doesn't appear in repsonses, shouldn't appear in data cleaning data builder.new_question('skip', 'Skip me') # Simple group lights = builder.new_group('lights', 'Traffic Lights', data_type='group') lights.new_question('red', 'Red means') lights.new_question('green', 'Green means') responses['lights'] = OrderedDict([('red', 'stop'), ('green', 'go')]) # Simple repeat group, one response one_hit_wonders = builder.new_group('one_hit_wonders', 'One-Hit Wonders', data_type='repeatGroup') one_hit_wonders.new_question('name', 'Name') responses['one_hit_wonders'] = [ {'name': 'A-Ha'}, ] # Simple repeat group, multiple responses snacks = builder.new_group('snacks', 'Snacks', data_type='repeatGroup') snacks.new_question('kind_of_snack', 'Kind of snack') responses['snacks'] = [ {'kind_of_snack': 'samosa'}, {'kind_of_snack': 'pakora'}, ] # Repeat group with nested group cups = builder.new_group('cups_of_tea', 'Cups of tea', data_type='repeatGroup') details = cups.new_group('details_of_cup', 'Details', data_type='group') details.new_question('kind_of_cup', 'Flavor') details.new_question('secret', 'Secret', data_type=None) responses['cups_of_tea'] = [ {'details_of_cup': {'kind_of_cup': 'green', 'secret': 'g'}}, {'details_of_cup': {'kind_of_cup': 'black', 'secret': 'b'}}, {'details_of_cup': {'kind_of_cup': 'more green', 'secret': 'mg'}}, ] xform = XForm(builder.tostring()) questions_patch.return_value = get_questions_from_xform_node(xform, ['en']) xml = FormSubmissionBuilder(form_id='123', form_properties=responses).as_xml_string() submitted_xform = submit_form_locally(xml, self.domain).xform form_data, _ = get_readable_data_for_submission(submitted_xform) question_response_map, ordered_question_values = get_data_cleaning_data(form_data, submitted_xform) expected_question_values = [ '/data/something', '/data/lights/red', '/data/lights/green', '/data/one_hit_wonders/name', '/data/snacks[1]/kind_of_snack', '/data/snacks[2]/kind_of_snack', '/data/cups_of_tea[1]/details_of_cup/kind_of_cup', '/data/cups_of_tea[1]/details_of_cup/secret', '/data/cups_of_tea[2]/details_of_cup/kind_of_cup', '/data/cups_of_tea[2]/details_of_cup/secret', '/data/cups_of_tea[3]/details_of_cup/kind_of_cup', '/data/cups_of_tea[3]/details_of_cup/secret', ] self.assertListEqual(ordered_question_values, expected_question_values) expected_response_map = { '/data/something': 'blue', '/data/lights/red': 'stop', '/data/lights/green': 'go', '/data/one_hit_wonders/name': 'A-Ha', '/data/snacks[1]/kind_of_snack': 'samosa', '/data/snacks[2]/kind_of_snack': 'pakora', '/data/cups_of_tea[1]/details_of_cup/kind_of_cup': 'green', '/data/cups_of_tea[1]/details_of_cup/secret': 'g', '/data/cups_of_tea[2]/details_of_cup/kind_of_cup': 'black', '/data/cups_of_tea[2]/details_of_cup/secret': 'b', '/data/cups_of_tea[3]/details_of_cup/kind_of_cup': 'more green', '/data/cups_of_tea[3]/details_of_cup/secret': 'mg', } self.assertDictEqual({k: v['value'] for k, v in question_response_map.items()}, expected_response_map)
class XFormBuilderTests(SimpleTestCase, TestXmlMixin): file_path = ("data", "xform_builder") def setUp(self): self.xform = XFormBuilder() def replace_xmlns(self, xml, xmlns): return re.sub(r"http://openrosa\.org/formdesigner/[\w-]{36}", xmlns, xml) def test_new_question_group(self): """ XFormBuilder.new_question should be able to add a group """ self.xform.new_question("personal", "Personal Questions", data_type="group") self.xform.new_question("name", "What is your name?", group="personal") self.assertXmlEqual( self.replace_xmlns(self.get_xml("group"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), ) def test_new_question_repeat_group(self): num_names = self.xform.new_question("num_names", "How many names do you have?", data_type="int") self.xform.new_question("personal", "Personal Questions", data_type="repeatGroup", repeat_count=num_names) self.xform.new_question( "name", 'What is your <output value="ordinal(position(..) + 1)" /> name?', group="personal", label_safe=True ) # Yes, that was plug for an ordinal function. cf. UserVoice: # https://dimagi.uservoice.com/forums/176376-form-builder/suggestions/10610517--ordinal-function self.assertXmlEqual( self.replace_xmlns(self.get_xml("repeat_group"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), ) def test_new_group_group(self): personal = self.xform.new_group("personal", "Personal Questions") personal.new_question("name", "What is your name?") self.assertXmlEqual( self.replace_xmlns(self.get_xml("group"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), ) def test_new_group_repeat_group(self): num_names = self.xform.new_question("num_names", "How many names do you have?", data_type="int") personal = self.xform.new_group( "personal", "Personal Questions", data_type="repeatGroup", repeat_count=num_names ) personal.new_question( "name", 'What is your <output value="ordinal(position(..) + 1)" /> name?', label_safe=True ) self.assertXmlEqual( self.replace_xmlns(self.get_xml("repeat_group"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), ) def test_unicode(self): self.xform.new_question("name", u"သင့်နာမည်ဘယ်လိုခေါ်လဲ?") # ("What is your name?" in Myanmar/Burmese) self.assertXmlEqual( self.replace_xmlns(self.get_xml("unicode"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), ) def test_select_question(self): self.xform.new_question( "fav_colors", "What are your favorite colors?", data_type="select", choices={"r": "Red", "o": "Orange", "y": "Yellow", "g": "Green", "b": "Blue", "i": "Indigo", "v": "Violet"}, ) self.assertXmlEqual( self.replace_xmlns(self.get_xml("select_question"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), ) def test_select1_question(self): self.xform.new_question( "you_aint_been_blue", "What kind of blue are you?", data_type="select1", choices={1: "Blue", 2: "Indigo", 3: "Black"}, ) self.assertXmlEqual( self.replace_xmlns(self.get_xml("select1_question"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), ) def test_data_types(self): self.xform.new_question("name", "Child name") self.xform.new_question("dob", "Child date of birth", "date") self.xform.new_question("with_mother", "Does child live with mother?", "boolean", value="true") self.xform.new_question("height", "Child height (cm)", "int") self.xform.new_question("weight", "Child weight (metric tonnes)", "decimal") self.xform.new_question("time", "Arrival time", "time") self.xform.new_question("now", "Current timestamp", "dateTime") self.xform.new_question( "mothers_name", None, None, calculate="concat('Jane', ' ', 'Smith')" # Hidden values have no data type ) self.assertXmlEqual( self.replace_xmlns(self.get_xml("data_types"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), ) def test_xform_title(self): self.xform = XFormBuilder("Built by XFormBuilder") self.xform.new_question("name", "What is your name?") group = self.xform.new_group("personal", "Personal Questions") group.new_question( "fav_color", u"Quelle est ta couleur préférée?", choices={"r": "Rot", "g": u"Grün", "b": "Blau"} ) self.assertXmlEqual( self.replace_xmlns(self.get_xml("xform_title"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), ) def test_question_params(self): self.xform = XFormBuilder("Built by XFormBuilder") params = { "constraint": ". != 'Ford Prefect'", "jr:constraintMsg": "That name is not as inconspicuous as you think.", } self.xform.new_question("name", "What is your name?", **params) self.assertXmlEqual( self.replace_xmlns(self.get_xml("question_params"), self.xform.xmlns), self.xform.tostring(pretty_print=True, encoding="utf-8", xml_declaration=True), )