示例#1
0
 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)
示例#2
0
 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)
     )
示例#3
0
    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')
示例#4
0
    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')
示例#5
0
 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)
     )
示例#6
0
    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')
示例#7
0
    def make_app(cls):
        factory = AppFactory(domain=cls.domain.name,
                             name="API App",
                             build_version='2.11.0')
        module1, form1 = factory.new_basic_module('open_case', 'house')
        form1.source = XFormBuilder().new_question("name",
                                                   "name").form.tostring()
        factory.form_opens_case(form1)

        module2, form2 = factory.new_basic_module('update_case', 'person')
        form2.source = XFormBuilder().new_question("name",
                                                   "name").form.tostring()
        factory.form_requires_case(form2, case_type='house')
        factory.form_opens_case(form2, case_type="person", is_subcase=True)

        app = factory.app
        app.save()
        return app
示例#8
0
 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)
示例#9
0
    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 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)
     )
示例#12
0
 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),
     )
示例#13
0
 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),
     )
示例#14
0
    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')
示例#15
0
    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()
示例#16
0
 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')
示例#17
0
 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')
示例#18
0
 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')
示例#19
0
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))
示例#20
0
    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()
示例#21
0
 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')
示例#22
0
 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')
示例#23
0
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),
        )
示例#24
0
 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)
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)
示例#27
0
 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')
示例#28
0
 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')
示例#29
0
 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')
示例#30
0
 def setUp(self):
     self.xform = XFormBuilder()
    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)
示例#32
0
 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')
 def setUp(self):
     self.xform = XFormBuilder()
示例#34
0
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')