def test_long_detail_xml(self):
        factory = AppFactory(build_version='2.26')
        factory.new_basic_module('registration', 'patient registration')
        module = factory.app.get_module(0)
        case_details = module.case_details
        long = case_details.long
        long.display = 'long'
        long_column = long.get_column(0)
        long_column.format = 'distance'

        suite = factory.app.create_suite()
        template_xpath = './detail[@id="m0_case_long"]/field'
        self.assertXmlHasXpath(suite, template_xpath)
        self.assertXmlPartialEqual(
            """
            <partial>
                <field>
                    <header>
                        <text>
                            <locale id="m0.case_long.case_name_1.header"/>
                        </text>
                    </header>
                    <template>
                        <text>
                            <xpath function="if(here() = '', '', if(case_name = '', '', concat(round(distance(case_name, here()) div 1000), ' km')))"/>
                        </text>
                    </template>
                </field>
            </partial>
            """,
            suite,
            template_xpath
        )
Exemplo n.º 2
0
    def test_that_grid_style_is_added(self):
        """
        Confirms that style="grid" is added to the root menu
        """
        factory = AppFactory(build_version='2.24')
        factory.app.use_grid_menus = True
        factory.new_basic_module('registration', 'patient registration')
        factory.app.get_module(0).put_in_root = True
        factory.new_basic_module('visit', 'patient visit')
        factory.app.get_module(1).put_in_root = True

        suite = factory.app.create_suite()
        root_xpath = './menu[@id="root"]'
        self.assertXmlHasXpath(suite, root_xpath)
        self.assertXmlPartialEqual(
            """
            <partial>
                <menu id="root" style="grid">
                    <text><locale id="modules.m0"/></text>
                    <command id="m0-f0"/>
                </menu>
                <menu id="root" style="grid">
                    <text><locale id="modules.m1"/></text>
                    <command id="m1-f0"/>
                </menu>
            </partial>
            """,
            suite,
            root_xpath
        )
Exemplo n.º 3
0
    def test_form_display_condition(self):
        """
        case_id should be renamed in a basic submodule form
        """
        factory = AppFactory(domain=DOMAIN)
        m0, m0f0 = factory.new_advanced_module('parent', 'gold-fish')
        factory.form_requires_case(m0f0)

        # changing this case tag should result in the session var in the submodule entry being updated to match it
        m0f0.actions.load_update_cases[0].case_tag = 'load_goldfish_renamed'

        m1, m1f0 = factory.new_advanced_module('child', 'guppy', parent_module=m0)
        factory.form_requires_case(m1f0, 'gold-fish', update={'question1': '/data/question1'})
        factory.form_requires_case(m1f0, 'guppy', parent_case_type='gold-fish')

        # making this case tag the same as the one in the parent module should mean that it will also get changed
        # to avoid conflicts
        m1f0.actions.load_update_cases[1].case_tag = 'load_goldfish_renamed'

        m1f0.form_filter = "#case/age > 33"

        XML = """
        <partial>
          <menu id="m1" root="m0">
            <text>
              <locale id="modules.m1"/>
            </text>
            <command id="m1-f0" relevant="instance('casedb')/casedb/case[@case_id=instance('commcaresession')/session/data/case_id_load_goldfish_renamed_guppy]/age &gt; 33"/>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(XML, factory.app.create_suite(), "./menu[@id='m1']")
Exemplo n.º 4
0
    def test_use_grid_menus_is_false(self):
        """
        Confirms that style="grid" is not added to any menus when use_grid_menus is False.
        """
        factory = AppFactory(build_version='2.24')
        factory.app.use_grid_menus = False
        factory.new_basic_module('registration', 'patient')

        suite = factory.app.create_suite()
        style_xpath = './menu[@style="grid"]'
        self.assertXmlDoesNotHaveXpath(suite, style_xpath)
Exemplo n.º 5
0
 def setUp(self):
     self.factory = AppFactory()
     self.basic_module, self.form0 = self.factory.new_basic_module('basic_module', 'parrot')
     self.form0.xmlns = 'http://openrosa.org/formdesigner/firstform'
     self.form1 = self.factory.new_form(self.basic_module)
     self.form1.xmlns = 'http://openrosa.org/formdesigner/secondform'
     self.shadow_module = self.factory.new_shadow_module('shadow_module', self.basic_module, with_form=False)
Exemplo n.º 6
0
    def setUp(self):
        update_toggle_cache(MODULE_FILTER.slug, DOMAIN, True, NAMESPACE_DOMAIN)
        self.factory = AppFactory(domain=DOMAIN)
        self.module_0, _ = self.factory.new_basic_module('parent', 'gold-fish')
        self.module_1, _ = self.factory.new_module(self.child_module_class, 'child', 'guppy', parent_module=self.module_0)

        self.app = self.factory.app
Exemplo n.º 7
0
    def test_that_root_menu_added(self):
        """
        Confirms that a menu is added with id="root" and style="grid"
        when the app normally wouldn't have a menu with id="root".
        """
        factory = AppFactory(build_version='2.24')
        factory.app.use_grid_menus = True
        factory.new_basic_module('registration', 'patient')

        suite = factory.app.create_suite()
        root_xpath = './menu[@id="root"]'
        self.assertXmlHasXpath(suite, root_xpath)
        self.assertXmlPartialEqual(
            '<partial><menu id="root" style="grid"><text/></menu></partial>',
            suite,
            root_xpath
        )
 def test_case_list_lookup_display_results(self):
     factory = AppFactory(build_version='2.11')
     module, form = factory.new_basic_module('follow_up', 'case')
     case_list = module.case_details.short
     case_list.lookup_enabled = True
     case_list.lookup_action = "callout.commcarehq.org.dummycallout.LAUNCH"
     case_list.lookup_name = 'Scan fingerprint'
     case_list.lookup_extras = [
         {'key': 'deviceId', 'value': '123'},
         {'key': 'apiKey', 'value': '0000'},
         {'key': 'packageName', 'value': 'foo'},
     ]
     case_list.lookup_responses = [
         {'key': 'fake'}
     ]
     case_list.lookup_display_results = True
     case_list.lookup_field_header['en'] = 'Accuracy'
     case_list.lookup_field_template = '@case_id'
     expected = """
       <partial>
         <lookup name="Scan fingerprint"
                 action="callout.commcarehq.org.dummycallout.LAUNCH">
           <extra key="deviceId" value="123"/>
           <extra key="apiKey" value="0000"/>
           <extra key="packageName" value="foo"/>
           <response key="fake"/>
           <field>
             <header>
               <text>
                 <locale id="case_lists.m0.callout.header"/>
               </text>
             </header>
             <template>
               <text>
                 <xpath function="@case_id"/>
               </text>
             </template>
           </field>
         </lookup>
       </partial>
     """
     self.assertXmlPartialEqual(
         expected,
         factory.app.create_suite(),
         "./detail[@id='m0_case_short']/lookup"
     )
Exemplo n.º 9
0
 def class_setup(cls):
     cls.domain = uuid.uuid4().hex
     cls.f1_xmlns = 'xmlns1'
     cls.f2_xmlns = 'xmlns2'
     app_factory = AppFactory(domain=cls.domain)
     module1, form1 = app_factory.new_basic_module('m1', '_casetype')
     module2, form2 = app_factory.new_basic_module('m2', '_casetype2')
     form1.xmlns = cls.f1_xmlns
     form2.xmlns = cls.f2_xmlns
     app_factory.app.save()
     cls.app = app_factory.app
     deleted_app_factory = AppFactory(domain=cls.domain)
     deleted_module1, deleted_form1 = deleted_app_factory.new_basic_module('del-m1', '_casetype3')
     cls.deleted_xmlns = 'xmlns3'
     deleted_form1.xmlns = cls.deleted_xmlns
     deleted_app_factory.app.doc_type = 'Application-Deleted'
     # make sure the ID comes after the primary app
     deleted_app_factory.app._id = '{}z'.format(cls.app.id)
     deleted_app_factory.app.save()
     cls.deleted_app = deleted_app_factory.app
     cls.xmlnses = [cls.f1_xmlns, cls.f2_xmlns, cls.deleted_xmlns]
     update_reports_analytics_indexes()
Exemplo n.º 10
0
    def test_short_detail_xml(self):
        factory = AppFactory(build_version='2.26')
        factory.new_basic_module('registration', 'patient registration')
        module = factory.app.get_module(0)
        case_details = module.case_details
        short = case_details.short
        short.display = 'short'
        short_column = short.get_column(0)
        short_column.format = 'distance'

        suite = factory.app.create_suite()
        template_xpath = './detail[@id="m0_case_short"]/field'
        self.assertXmlHasXpath(suite, template_xpath)
        self.assertXmlPartialEqual(
            """
            <partial>
                <field>
                    <header>
                        <text>
                            <locale id="m0.case_short.case_name_1.header"/>
                        </text>
                    </header>
                    <template>
                        <text>
                            <xpath function="if(here() = '', '', if(case_name = '', '', concat(round(distance(case_name, here()) div 1000), ' km')))"/>
                        </text>
                    </template>
                    <sort direction="ascending" order="1" type="double">
                        <text>
                                <xpath function="round(distance(case_name, here()))"/>
                        </text>
                    </sort>
                </field>
            </partial>
            """,
            suite,
            template_xpath
        )
Exemplo n.º 11
0
    def test_parent_preload(self):
        """
        Test parent case is correctly set in preloads when first form of parent module updates a case
        """
        factory = AppFactory(build_version='2.9')
        upd_goldfish_mod, upd_goldfish_form = factory.new_basic_module('upd_goldfish', 'gold-fish')
        factory.form_requires_case(upd_goldfish_form)

        guppy_mod, guppy_form = factory.new_basic_module(
            'upd_guppy',
            'guppy',
            parent_module=upd_goldfish_mod,
        )
        guppy_form.source = self.get_xml('original_form', override_path=('data',))
        factory.form_requires_case(
            guppy_form,
            'guppy',
            parent_case_type='gold-fish',
            preload={'/data/question1': 'parent/question1'})

        self.assertXmlEqual(self.get_xml('child-module-preload-parent-ref'), guppy_form.render_xform())
 def setUp(self):
     self.factory = AppFactory(build_version="2.26")
     self.factory.new_basic_module("registration", "patient registration")
     module = self.factory.app.get_module(0)
     self.case_details = module.case_details
class CaseDetailDistance(SimpleTestCase, TestXmlMixin):
    def setUp(self):
        self.factory = AppFactory(build_version="2.26")
        self.factory.new_basic_module("registration", "patient registration")
        module = self.factory.app.get_module(0)
        self.case_details = module.case_details

    def test_short_detail_xml(self):
        short = self.case_details.short
        short.display = "short"
        short_column = short.get_column(0)
        short_column.format = "distance"

        suite = self.factory.app.create_suite()
        template_xpath = './detail[@id="m0_case_short"]/field'
        self.assertXmlHasXpath(suite, template_xpath)
        self.assertXmlPartialEqual(
            """
            <partial>
                <field>
                    <header>
                        <text>
                            <locale id="m0.case_short.case_name_1.header"/>
                        </text>
                    </header>
                    <template>
                        <text>
                            <xpath function="if(here() = '', '', if(case_name = '', '', concat(round(distance(case_name, here()) div 1000), ' km')))"/>
                        </text>
                    </template>
                    <sort direction="ascending" order="1" type="double">
                        <text>
                                <xpath function="round(distance(case_name, here()))"/>
                        </text>
                    </sort>
                </field>
            </partial>
            """,
            suite,
            template_xpath,
        )

    def test_short_detail_xml_with_sort(self):
        short = self.case_details.short
        short.display = "short"
        short_column = short.get_column(0)
        short.sort_elements.append(SortElement(field=short_column.field, type="distance", direction="descending"))

        suite = self.factory.app.create_suite()
        template_xpath = './detail[@id="m0_case_short"]/field'
        self.assertXmlHasXpath(suite, template_xpath)
        self.assertXmlPartialEqual(
            """
            <partial>
                <field>
                    <header>
                        <text>
                            <locale id="m0.case_short.case_name_1.header"/>
                        </text>
                    </header>
                    <template>
                        <text>
                            <xpath function="case_name"/>
                        </text>
                    </template>
                    <sort direction="descending" order="1" type="double">
                        <text>
                            <xpath function="round(distance(case_name, here()))"/>
                        </text>
                    </sort>
                </field>
            </partial>
            """,
            suite,
            template_xpath,
        )

    def test_short_detail_xml_sort_only(self):
        short = self.case_details.short
        short.display = "short"
        short.sort_elements.append(SortElement(field="gps", type="distance", direction="descending"))

        suite = self.factory.app.create_suite()
        template_xpath = './detail[@id="m0_case_short"]/field'
        self.assertXmlHasXpath(suite, template_xpath)
        self.assertXmlPartialEqual(
            """
            <partial>
                <field>
                    <header>
                        <text>
                            <locale id="m0.case_short.case_name_1.header"/>
                        </text>
                    </header>
                    <template>
                        <text>
                            <xpath function="case_name"/>
                        </text>
                    </template>
                </field>
                <field>
                    <header width="0">
                        <text/>
                    </header>
                    <template width="0">
                        <text>
                            <xpath function="gps"/>
                        </text>
                    </template>
                    <sort direction="descending" order="1" type="double">
                        <text>
                            <xpath function="round(distance(gps, here()))"/>
                        </text>
                    </sort>
                </field>
            </partial>
            """,
            suite,
            template_xpath,
        )

    def test_long_detail_xml(self):
        long = self.case_details.long
        long.display = "long"
        long_column = long.get_column(0)
        long_column.format = "distance"

        suite = self.factory.app.create_suite()
        template_xpath = './detail[@id="m0_case_long"]/field'
        self.assertXmlHasXpath(suite, template_xpath)
        self.assertXmlPartialEqual(
            """
            <partial>
                <field>
                    <header>
                        <text>
                            <locale id="m0.case_long.case_name_1.header"/>
                        </text>
                    </header>
                    <template>
                        <text>
                            <xpath function="if(here() = '', '', if(case_name = '', '', concat(round(distance(case_name, here()) div 1000), ' km')))"/>
                        </text>
                    </template>
                </field>
            </partial>
            """,
            suite,
            template_xpath,
        )
Exemplo n.º 14
0
class ShadowModuleFormSelectionSuiteTest(SimpleTestCase, TestXmlMixin):

    def setUp(self):
        self.factory = AppFactory()
        self.basic_module, self.form0 = self.factory.new_basic_module('basic_module', 'parrot')
        self.form0.xmlns = 'http://openrosa.org/formdesigner/firstform'
        self.form1 = self.factory.new_form(self.basic_module)
        self.form1.xmlns = 'http://openrosa.org/formdesigner/secondform'
        self.shadow_module = self.factory.new_shadow_module('shadow_module', self.basic_module, with_form=False)

    def test_all_forms_selected(self):
        expected = """
        <partial>
          <menu id="m1">
            <text>
              <locale id="modules.m1"/>
            </text>
            <command id="m1-f0"/>
            <command id="m1-f1"/>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(
            expected,
            self.factory.app.create_suite(),
            "./menu[@id='m1']"
        )

    def test_some_forms_selected(self):
        self.shadow_module.excluded_form_ids = [self.form0.unique_id]
        expected = """
        <partial>
          <menu id="m1">
            <text>
              <locale id="modules.m1"/>
            </text>
            <command id="m1-f1"/>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(
            expected,
            self.factory.app.create_suite(),
            "./menu[@id='m1']"
        )

    def test_no_forms_selected(self):
        self.shadow_module.excluded_form_ids = [self.form0.unique_id, self.form1.unique_id]
        expected = """
        <partial>
          <menu id="m1">
            <text>
              <locale id="modules.m1"/>
            </text>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(
            expected,
            self.factory.app.create_suite(),
            "./menu[@id='m1']"
        )

    def test_form_added(self):
        self.shadow_module.excluded_form_ids = [self.form0.unique_id]
        self.factory.new_form(self.basic_module)
        expected = """
        <partial>
          <menu id="m1">
            <text>
              <locale id="modules.m1"/>
            </text>
            <command id="m1-f1"/>
            <command id="m1-f2"/>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(
            expected,
            self.factory.app.create_suite(),
            "./menu[@id='m1']"
        )

    def test_form_removed(self):
        self.basic_module.forms.remove(self.form1)
        expected = """
        <partial>
          <menu id="m1">
            <text>
              <locale id="modules.m1"/>
            </text>
            <command id="m1-f0"/>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(
            expected,
            self.factory.app.create_suite(),
            "./menu[@id='m1']"
        )

    def test_forms_reordered(self):
        expected_before = """
        <partial>
          <form>http://openrosa.org/formdesigner/firstform</form>
          <form>http://openrosa.org/formdesigner/secondform</form>

          <form>http://openrosa.org/formdesigner/firstform</form>
          <form>http://openrosa.org/formdesigner/secondform</form>
        </partial>
        """
        self.assertXmlPartialEqual(
            expected_before,
            self.factory.app.create_suite(),
            "./entry/form"
        )
        # Swap forms around
        self.basic_module.forms = [self.form1, self.form0]
        expected_after = """
        <partial>
          <form>http://openrosa.org/formdesigner/secondform</form>
          <form>http://openrosa.org/formdesigner/firstform</form>

          <form>http://openrosa.org/formdesigner/secondform</form>
          <form>http://openrosa.org/formdesigner/firstform</form>
        </partial>
        """
        self.assertXmlPartialEqual(
            expected_after,
            self.factory.app.create_suite(),
            "./entry/form"
        )
Exemplo n.º 15
0
    def test_form_rename_session_vars(self):
        """
        The session vars in the entries for the submodule should match the parent and avoid naming conflicts.
        """
        factory = AppFactory(build_version='2.9')
        reg_goldfish_mod, reg_goldfish_form = factory.new_basic_module('reg_goldfish', 'gold-fish')
        factory.form_opens_case(reg_goldfish_form)
        reg_guppy_mod, reg_guppy_form = factory.new_advanced_module('reg_guppy', 'guppy')
        factory.form_requires_case(reg_guppy_form, 'gold-fish')
        factory.form_opens_case(reg_guppy_form, 'guppy', is_subcase=True)
        upd_goldfish_mod, upd_goldfish_form = factory.new_advanced_module(
            'upd_goldfish',
            'gold-fish',
        )
        factory.form_requires_case(upd_goldfish_form)
        # changing this case tag should result in the session var in the submodule entry being updated to match it
        upd_goldfish_form.actions.load_update_cases[0].case_tag = 'load_goldfish_renamed'

        upd_guppy_mod, upd_guppy_form = factory.new_advanced_module(
            'upd_guppy',
            'guppy',
            parent_module=upd_goldfish_mod,
        )
        upd_guppy_form.source = self.get_xml('original_form', override_path=('data',))
        factory.form_requires_case(upd_guppy_form, 'gold-fish', update={'question1': '/data/question1'})
        factory.form_requires_case(
            upd_guppy_form,
            'guppy',
            parent_case_type='gold-fish',
            update={'question1': '/data/question1'}
        )
        # making this case tag the same as the one in the parent module should mean that it will also get changed
        # to avoid conflicts
        upd_guppy_form.actions.load_update_cases[1].case_tag = 'load_goldfish_renamed'

        self.assertXmlEqual(self.get_xml('child-module-rename-session-vars'), upd_guppy_form.render_xform())
Exemplo n.º 16
0
class ModuleAsChildTestBase(TestXmlMixin):
    file_path = ('data', 'suite')
    child_module_class = None

    def setUp(self):
        update_toggle_cache(MODULE_FILTER.slug, DOMAIN, True, NAMESPACE_DOMAIN)
        self.factory = AppFactory(domain=DOMAIN)
        self.module_0, _ = self.factory.new_basic_module('parent', 'gold-fish')
        self.module_1, _ = self.factory.new_module(self.child_module_class, 'child', 'guppy', parent_module=self.module_0)

        self.app = self.factory.app

    def tearDown(self):
        clear_toggle_cache(MODULE_FILTER.slug, DOMAIN, NAMESPACE_DOMAIN)

    def test_basic_workflow(self):
        # make module_1 as submenu to module_0
        XML = """
        <partial>
          <menu id="m0">
            <text>
              <locale id="modules.m0"/>
            </text>
            <command id="m0-f0"/>
          </menu>
          <menu root="m0" id="m1">
            <text>
              <locale id="modules.m1"/>
            </text>
            <command id="m1-f0"/>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(XML, self.app.create_suite(), "./menu")

    def test_workflow_with_put_in_root(self):
        # make module_1 as submenu to module_0
        self.module_1.put_in_root = True

        XML = """
        <partial>
          <menu id="m0">
            <text>
              <locale id="modules.m0"/>
            </text>
            <command id="m0-f0"/>
          </menu>
          <menu id="m0">
            <text>
              <locale id="modules.m1"/>
            </text>
            <command id="m1-f0"/>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(XML, self.app.create_suite(), "./menu")

    def test_deleted_parent(self):
        self.module_1.root_module_id = "unknownmodule"

        cycle_error = {
            'type': 'unknown root',
        }
        errors = self.app.validate_app()
        self.assertIn(cycle_error, errors)

    def test_circular_relation(self):
        self.module_0.root_module_id = self.module_1.unique_id
        cycle_error = {
            'type': 'root cycle',
        }
        errors = self.app.validate_app()
        self.assertIn(cycle_error, errors)