def test_scheduler_module(self):
        factory = AppFactory()
        m1, m1f1 = factory.new_basic_module('open_case', 'house')
        factory.form_opens_case(m1f1)
        m2, m2f1 = factory.new_advanced_module('scheduler_module', 'house')
        m2f2 = factory.new_form(m2)
        factory.form_requires_case(m2f1, case_type='house', update={
            'foo': '/data/question1',
            'bar': '/data/question2',
        })
        factory.form_requires_case(m2f2, case_type='house', update={
            'bleep': '/data/question1',
            'bloop': '/data/question2',
        })

        self._add_scheduler_to_module(m2)
        self._add_scheduler_to_form(m2f1, m2, 'form1')
        self._add_scheduler_to_form(m2f2, m2, 'form2')

        self.assertCaseProperties(factory.app, 'house', [
            'foo',
            'bar',
            'bleep',
            'bloop',
            # Scheduler properties:
            'last_visit_date_form1',
            'last_visit_number_form1',
            'last_visit_date_form2',
            'last_visit_number_form2',
            'current_schedule_phase',
        ])
Example #2
0
    def test_persistent_case_name_when_tiles_enabled(self):
        """
        Confirm that the persistent case name context is not added when case tiles
        are configured to persist in forms
        """
        factory = AppFactory()
        module, form = factory.new_advanced_module("my_module", "person")
        factory.form_requires_case(form, "person")
        module.case_details.short.custom_xml = '<detail id="m0_case_short"></detail>'
        module.case_details.short.persist_tile_on_forms = True
        module.case_details.short.persist_case_context = True
        suite = factory.app.create_suite()

        self.assertXmlDoesNotHaveXpath(suite, "detail[@id='m0_persistent_case_context']")
        self.assertXmlPartialEqual(
            """
            <partial>
                <datum
                    detail-confirm="m0_case_long"
                    detail-persistent="m0_case_short"
                    detail-select="m0_case_short"
                    id="case_id_load_person_0"
                    nodeset="instance('casedb')/casedb/case[@case_type='person'][@status='open']"
                    value="./@case_id"
                />
            </partial>
            """,
            suite,
            "entry/session/datum"
        )
Example #3
0
    def test_default_app_strings_with_build_profiles(self):
        factory = AppFactory(build_version='2.40.0')
        factory.app.langs = ['en', 'es']
        factory.app.build_profiles = OrderedDict({
            'en': BuildProfile(langs=['en'], name='en-profile'),
            'es': BuildProfile(langs=['es'], name='es-profile'),
        })
        module, form = factory.new_basic_module('my_module', 'cases')
        module.name = {
            'en': 'Alive',
            'es': 'Viva',
        }
        form.name = {
            'en': 'Human',
            'es': 'Humana',
        }

        all_default_strings = self._generate_app_strings(factory.app, 'default')
        self.assertEqual(all_default_strings['modules.m0'], module.name['en'])
        self.assertEqual(all_default_strings['forms.m0f0'], form.name['en'])

        en_default_strings = self._generate_app_strings(factory.app, 'default', build_profile_id='en')
        self.assertEqual(en_default_strings['modules.m0'], module.name['en'])
        self.assertEqual(en_default_strings['forms.m0f0'], form.name['en'])

        es_default_strings = self._generate_app_strings(factory.app, 'default', build_profile_id='es')
        self.assertEqual(es_default_strings['modules.m0'], module.name['es'])
        self.assertEqual(es_default_strings['forms.m0f0'], form.name['es'])
Example #4
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.0')
        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
        )
Example #5
0
class _BaseTestAppDiffs(object):
    def setUp(self):
        super(_BaseTestAppDiffs, self).setUp()

        self.factory1 = AppFactory()
        self.app1 = self.factory1.app
        self.factory1.new_basic_module('module_1', 'case')

        self.factory2 = AppFactory()
        self.app2 = self.factory2.app
        self.factory2.new_basic_module('module_1', 'case')

    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 _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')
Example #6
0
    def test_persistent_case_tiles_in_advanced_module_case_lists(self):
        """
        Test that the detail-persistent attributes is set correctly when persistent
        case tiles are used on advanced module case lists
        """
        factory = AppFactory()
        module, form = factory.new_advanced_module("my_module", "person")
        factory.form_requires_case(form, "person")
        module.case_list.show = True
        module.case_details.short.custom_xml = '<detail id="m0_case_short"></detail>'
        module.case_details.short.persist_tile_on_forms = True
        suite = factory.app.create_suite()

        # The relevant check is really that detail-persistent="m0_case_short"
        # but assertXmlPartialEqual xpath implementation doesn't currently
        # support selecting attributes
        self.assertXmlPartialEqual(
            """
            <partial>
                <datum
                    detail-confirm="m0_case_long"
                    detail-persistent="m0_case_short"
                    detail-select="m0_case_short"
                    id="case_id_case_person"
                    nodeset="instance('casedb')/casedb/case[@case_type='person'][@status='open']"
                    value="./@case_id"
                />
            </partial>
            """,
            suite,
            'entry/command[@id="m0-case-list"]/../session/datum',
        )
 def _get_app(self):
     from corehq.apps.app_manager.tests.app_factory import AppFactory
     factory = AppFactory()
     factory.new_basic_module('m0', 'case1')
     factory.new_basic_module('m1', 'case2')
     factory.new_advanced_module('m2', 'case3')
     return factory.app
Example #8
0
    def test_grid_menu_for_none(self):
        factory = AppFactory(build_version='2.24.3')
        factory.app.create_profile()
        factory.app.grid_form_menus = 'none'
        factory.new_basic_module('registration', 'patient')
        factory.app.get_module(0).display_style = 'grid'
        root_xpath = './menu[@id="root"]'
        m0_xpath = './menu[@id="m0"]'

        # with Modules Menu to be list should not render root menu and render module w/o style=grid
        factory.app.use_grid_menus = False
        suite = factory.app.create_suite()
        self.assertXmlDoesNotHaveXpath(suite, root_xpath)
        self.assertXmlPartialEqual(
            '<partial><menu id="m0"><text><locale id="modules.m0"/></text><command id="m0-f0"/></menu></partial>',
            suite,
            m0_xpath
        )

        # with Modules Menu to be grid should render root menu w/ style=grid and render module w/o style=grid
        factory.app.use_grid_menus = True
        suite = factory.app.create_suite()
        self.assertXmlPartialEqual(
            '<partial><menu id="root" style="grid"><text/></menu></partial>',
            suite,
            root_xpath
        )
        self.assertXmlPartialEqual(
            '<partial><menu id="m0"><text><locale id="modules.m0"/></text><command id="m0-f0"/></menu></partial>',
            suite,
            m0_xpath
        )
Example #9
0
 def _create_app(self, name):
     factory = AppFactory(domain=self.domain, name=name, build_version='2.11.0')
     module1, form1 = factory.new_basic_module('open_case', 'house')
     factory.form_opens_case(form1)
     app = factory.app
     app.save()
     self.addCleanup(app.delete)
     return app
Example #10
0
    def test_basic(self):
        factory = AppFactory(build_version="2.9.0/latest")
        m0, m0f0 = factory.new_basic_module("m0", "frog")
        m1, m1f0 = factory.new_basic_module("m1", "frog")

        m0f0.post_form_workflow = WORKFLOW_FORM
        m0f0.form_links = [FormLink(xpath="(today() - dob) &lt; 7", form_id=m1f0.unique_id)]
        self.assertXmlPartialEqual(self.get_xml("form_link_basic"), factory.app.create_suite(), "./entry[1]")
    def _get_app(self):
        from corehq.apps.app_manager.tests.app_factory import AppFactory

        factory = AppFactory()
        factory.new_basic_module("m0", "case1")
        factory.new_basic_module("m1", "case2")
        factory.new_advanced_module("m2", "case3")
        return factory.app
Example #12
0
    def test_grid_menu_for_all(self):
        factory = AppFactory(build_version='2.24.3')
        self.assertTrue(factory.app.grid_menu_toggle_enabled())
        factory.app.create_profile()
        factory.app.grid_form_menus = 'all'
        factory.new_basic_module('registration', 'patient')
        suite = factory.app.create_suite()
        root_xpath = './menu[@id="root"]'
        grid_module_xpath = './menu[@id="m0"]'

        # with Modules Menu to be list should not render root menu and render module w/ style=grid
        factory.app.use_grid_menus = False
        self.assertXmlDoesNotHaveXpath(suite, root_xpath)
        self.assertXmlPartialEqual(
            '<partial><menu id="m0" style="grid"><text><locale id="modules.m0"/></text>\
            <command id="m0-f0"/></menu></partial>',
            suite,
            grid_module_xpath
        )

        # with Modules Menu to be grid should render root menu and module w/ style=grid
        factory.app.use_grid_menus = True
        suite = factory.app.create_suite()
        self.assertXmlPartialEqual(
            '<partial><menu id="root" style="grid"><text/></menu></partial>',
            suite,
            root_xpath
        )
        self.assertXmlPartialEqual(
            '<partial><menu id="m0" style="grid"><text><locale id="modules.m0"/></text>\
            <command id="m0-f0"/></menu></partial>',
            suite,
            grid_module_xpath
        )

        # with Modules Menu to be list and module itself being the root should render root w/o style=grid with
        # module content
        factory.app.use_grid_menus = False
        factory.app.get_module(0).put_in_root = True
        suite = factory.app.create_suite()
        self.assertXmlPartialEqual(
            '<partial><menu id="root"><text><locale id="modules.m0"/></text>\
            <command id="m0-f0"/></menu></partial>',
            suite,
            root_xpath
        )

        # with Modules Menu to be grid and module itself being the root should render root w/ style=grid with
        # module content
        factory.app.get_module(0).put_in_root = True
        factory.app.use_grid_menus = True
        suite = factory.app.create_suite()
        self.assertXmlPartialEqual(
            '<partial><menu id="root" style="grid"><text><locale id="modules.m0"/></text>\
            <command id="m0-f0"/></menu></partial>',
            suite,
            root_xpath
        )
Example #13
0
    def setUpClass(cls):
        super(UCRAggregationTest, cls).setUpClass()
        # cleanup any previous data
        cls._cleanup_data()

        # setup app
        factory = AppFactory(domain=cls.domain)
        # parent case module, incl opening child cases of main type
        m_parent, f_parent = factory.new_basic_module('Parent Module', cls.parent_case_type)
        factory.form_opens_case(f_parent, case_type=cls.parent_case_type)
        factory.form_opens_case(f_parent, case_type=cls.case_type, is_subcase=True)

        # main module
        m0, f0 = factory.new_basic_module('A Module', cls.case_type)
        f1 = factory.new_form(m0)
        f1.source = cls._get_xform()
        factory.form_requires_case(f1, case_type=cls.case_type, update={
            cp[0]: '/data/{}'.format(cp[0]) for cp in cls.case_properties
        })
        cls.followup_form = f1

        cls.app = factory.app
        cls.app.save()

        # create form and case ucrs
        cls.form_data_source = get_form_data_source(cls.app, cls.followup_form)
        cls.case_data_source = get_case_data_source(cls.app, cls.case_type)
        cls.parent_case_data_source = get_case_data_source(cls.app, cls.parent_case_type)

        # create some data - first just create the case
        cls.parent_case_id = cls._create_parent_case(cls.parent_name)
        cls.case_id = cls._create_case(cls.parent_case_id)
        for fu_date in cls.fu_visit_dates:
            cls._submit_followup_form(cls.case_id, received_on=fu_date)

        # the closed case causes there to be some data with an end_column
        cls.closed_case_id = cls._create_closed_case()

        # populate the UCRs with the data we just created
        cls.form_adapter = get_indicator_adapter(cls.form_data_source)
        cls.case_adapter = get_indicator_adapter(cls.case_data_source)
        cls.parent_case_adapter = get_indicator_adapter(cls.parent_case_data_source)

        cls.form_adapter.rebuild_table()
        cls.case_adapter.rebuild_table()
        cls.parent_case_adapter.rebuild_table()

        _iteratively_build_table(cls.form_data_source)
        _iteratively_build_table(cls.case_data_source)
        _iteratively_build_table(cls.parent_case_data_source)

        # setup AggregateTableDefinition
        cls.monthly_aggregate_table_definition = cls._get_monthly_aggregate_table_definition()
        cls.weekly_aggregate_table_definition = cls._get_weekly_aggregate_table_definition()
        cls.basic_aggregate_table_definition = cls._get_basic_aggregate_table_definition()

        # and adapter
        cls.monthly_adapter = get_indicator_adapter(cls.monthly_aggregate_table_definition)
Example #14
0
    def test_circular_parent_case_ref(self):
        factory = AppFactory()
        m0, m0f0 = factory.new_basic_module('m0', 'case1')
        m1, m1f0 = factory.new_basic_module('m1', 'case2')
        factory.form_requires_case(m0f0, 'case1', parent_case_type='case2')
        factory.form_requires_case(m1f0, 'case2', parent_case_type='case1')

        with self.assertRaises(SuiteValidationError):
            factory.app.create_suite()
Example #15
0
    def test_persistent_case_name_in_forms(self):
        """
        Test that the detail-persistent attributes are set correctly when the
        module is configured to persist the case name at the top of the form.
        Also confirm that the appropriate <detail> element is added to the suite.
        """
        factory = AppFactory()
        module, form = factory.new_basic_module("my_module", "person")
        factory.form_requires_case(form, "person")
        module.case_details.short.persist_case_context = True
        suite = factory.app.create_suite()

        self.assertXmlPartialEqual(
            """
            <partial>
                <detail id="m0_persistent_case_context">
                    <title>
                        <text/>
                    </title>
                    <field>
                        <style font-size="large" horz-align="center">
                            <grid grid-height="1" grid-width="12" grid-x="0" grid-y="0"/>
                        </style>
                        <header>
                            <text/>
                        </header>
                        <template>
                            <text>
                                <xpath function="case_name"/>
                            </text>
                        </template>
                    </field>
                </detail>
            </partial>
            """,
            suite,
            "detail[@id='m0_persistent_case_context']"
        )

        # The attribute we care about here is detail-persistent="m0_persistent_case_context"
        self.assertXmlPartialEqual(
            """
            <partial>
                <datum
                    detail-confirm="m0_case_long"
                    detail-persistent="m0_persistent_case_context"
                    detail-select="m0_case_short"
                    id="case_id"
                    nodeset="instance('casedb')/casedb/case[@case_type='person'][@status='open']"
                    value="./@case_id"
                />
            </partial>
            """,
            suite,
            "entry/session/datum"
        )
Example #16
0
    def setUp(self):
        super(_BaseTestAppDiffs, self).setUp()

        self.factory1 = AppFactory()
        self.app1 = self.factory1.app
        self.factory1.new_basic_module('module_1', 'case')

        self.factory2 = AppFactory()
        self.app2 = self.factory2.app
        self.factory2.new_basic_module('module_1', 'case')
Example #17
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']")
Example #18
0
class FormFilterErrorTests(SimpleTestCase, TestXmlMixin):
    file_path = ('data', 'suite')

    def setUp(self):
        self.suite_xml_is_usercase_in_use_patch = patch(
            'corehq.apps.app_manager.suite_xml.sections.menus.is_usercase_in_use'
        )
        self.suite_xml_is_usercase_in_use_mock = self.suite_xml_is_usercase_in_use_patch.start()
        self.factory = AppFactory(build_version='2.9')

    def tearDown(self):
        self.suite_xml_is_usercase_in_use_patch.stop()

    def test_error_when_no_case(self):
        self.suite_xml_is_usercase_in_use_mock.return_value = True

        __, reg_form = self.factory.new_basic_module('reg_module', 'mother')
        self.factory.form_opens_case(reg_form)
        reg_form.form_filter = './due_date <= today()'

        with self.assertRaises(CaseXPathValidationError):
            self.factory.app.create_suite()

    def test_no_error_when_user_case(self):
        self.suite_xml_is_usercase_in_use_mock.return_value = True

        __, reg_form = self.factory.new_basic_module('reg_module', 'mother')
        self.factory.form_opens_case(reg_form)
        reg_form.form_filter = '#user/due_date <= today()'

        expected = """
        <partial>
            <menu id="m0">
            <text>
              <locale id="modules.m0"/>
            </text>
            <command id="m0-f0" relevant="instance('casedb')/casedb/case[@case_type='commcare-user'][hq_user_id=instance('commcaresession')/session/context/userid]/due_date &lt;= today()"/>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(expected, self.factory.app.create_suite(), './menu')

    def test_no_error_when_case(self):
        self.suite_xml_is_usercase_in_use_mock.return_value = False

        __, update_form = self.factory.new_basic_module('update_mother', 'mother')
        self.factory.form_requires_case(update_form)
        update_form.form_filter = '#case/due_date <= today()'

        expected = """
        <partial>
          <menu id="m0">
            <text>
              <locale id="modules.m0"/>
            </text>
            <command id="m0-f0" relevant="instance('casedb')/casedb/case[@case_id=instance('commcaresession')/session/data/case_id]/due_date &lt;= today()"/>
          </menu>
        </partial>
        """
        self.assertXmlPartialEqual(expected, self.factory.app.create_suite(), './menu')
Example #19
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.0')
        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)
Example #20
0
    def test_fixture_to_case_selection(self):
        factory = AppFactory(build_version='2.9')

        module, form = factory.new_basic_module('my_module', 'cases')
        module.fixture_select.active = True
        module.fixture_select.fixture_type = 'days'
        module.fixture_select.display_column = 'my_display_column'
        module.fixture_select.variable_column = 'my_variable_column'
        module.fixture_select.xpath = 'date(scheduled_date) <= date(today() + $fixture_value)'

        factory.form_requires_case(form)

        self.assertXmlEqual(self.get_xml('fixture-to-case-selection'), factory.app.create_suite())
    def setUpClass(cls):
        super(TestCaseDelayedSchema, cls).setUpClass()
        factory = AppFactory(domain=cls.domain)
        module1, form1 = factory.new_basic_module('update_case', cls.case_type)
        factory.form_requires_case(form1, cls.case_type, update={
            'age': '/data/age',
            'height': '/data/height',
        })
        cls.current_app = factory.app
        cls.current_app._id = '1234'

        factory = AppFactory(domain=cls.domain)
        module1, form1 = factory.new_basic_module('update_case', cls.case_type)
        factory.form_requires_case(form1, cls.case_type, update={
            'age': '/data/age',
            'height': '/data/height',
            'weight': '/data/weight',
        })
        cls.build = factory.app
        cls.build.copy_of = cls.current_app._id
        cls.build.version = 5
        cls.build.has_submissions = True

        cls.apps = [
            cls.current_app,
            cls.build,
        ]
        with drop_connected_signals(app_post_save):
            for app in cls.apps:
                app.save()
Example #22
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
Example #23
0
    def test_link_to_form_in_parent_module(self):
        factory = AppFactory(build_version="2.9.0/latest")
        m0, m0f0 = factory.new_basic_module("enroll child", "child")
        factory.form_opens_case(m0f0)

        m1, m1f0 = factory.new_basic_module("child visit", "child")
        factory.form_updates_case(m1f0)

        m2, m2f0 = factory.new_advanced_module("visit history", "visit", parent_module=m1)
        factory.form_updates_case(m2f0, "child")

        # link to child -> edit child
        m2f0.post_form_workflow = WORKFLOW_FORM
        m2f0.form_links = [FormLink(xpath="true()", form_id=m1f0.unique_id)]

        self.assertXmlPartialEqual(self.get_xml("form_link_child_modules"), factory.app.create_suite(), "./entry[3]")
Example #24
0
    def test_grid_menu_for_some(self):
        factory = AppFactory(build_version='2.24.3')
        factory.app.create_profile()
        factory.app.grid_form_menus = 'some'
        factory.new_basic_module('registration', 'patient')
        factory.new_basic_module('visit', 'patient visit')
        factory.app.get_module(1).display_style = 'grid'
        root_xpath = './menu[@id="root"]'
        grid_module_xpath = './menu[@id="m1"]'

        # with Modules Menu to be list should not render root menu and render module w/ style=grid
        factory.app.use_grid_menus = False
        suite = factory.app.create_suite()
        self.assertXmlDoesNotHaveXpath(suite, root_xpath)
        self.assertXmlHasXpath(suite, grid_module_xpath)
        self.assertXmlPartialEqual(
            '<partial><menu id="m1" style="grid"><text><locale id="modules.m1"/></text>\
            <command id="m1-f0"/></menu></partial>',
            suite,
            grid_module_xpath
        )

        # with Modules Menu to be grid should render both root menu and module w/ style=grid
        factory.app.use_grid_menus = True
        suite = factory.app.create_suite()
        self.assertXmlHasXpath(suite, root_xpath)
        self.assertXmlPartialEqual(
            '<partial><menu id="root" style="grid"><text/></menu></partial>',
            suite,
            root_xpath
        )
        self.assertXmlPartialEqual(
            '<partial><menu id="m1" style="grid"><text><locale id="modules.m1"/></text>\
            <command id="m1-f0"/></menu></partial>',
            suite,
            grid_module_xpath
        )

        # with module itself being the root should render root menu style=grid with module content
        factory.app.get_module(1).put_in_root = True
        suite = factory.app.create_suite()
        self.assertXmlPartialEqual(
            '<partial><menu id="root" style="grid"><text><locale id="modules.m1"/></text>\
            <command id="m1-f0"/></menu></partial>',
            suite,
            root_xpath
        )
    def test_with_case_management_multiple_links(self):
        factory = AppFactory(build_version='2.9.0/latest')
        m0, m0f0 = factory.new_basic_module('m0', 'frog')
        factory.form_opens_case(m0f0)
        m1, m1f0 = factory.new_basic_module('m1', 'frog')
        factory.form_requires_case(m1f0)

        m1f1 = factory.new_form(m1)
        factory.form_opens_case(m1f1)

        m0f0.post_form_workflow = WORKFLOW_FORM
        m0f0.form_links = [
            FormLink(xpath="a = 1", form_id=m1f0.unique_id),
            FormLink(xpath="a = 2", form_id=m1f1.unique_id)
        ]

        self.assertXmlPartialEqual(self.get_xml('form_link_multiple'), factory.app.create_suite(), "./entry[1]")
 def test_case_list_lookup_display_results(self):
     factory = AppFactory(build_version='2.11.0')
     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"
     )
Example #27
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.0')
        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
        )
Example #28
0
    def test_tiered_select_with_advanced_module_as_parent_with_filters(self):
        factory = AppFactory(build_version="2.25")
        parent_module, parent_form = factory.new_advanced_module("parent", "parent")
        parent_module.case_details.short.filter = "parent_filter = 1"

        child_module, child_form = factory.new_basic_module("child", "child")
        child_form.xmlns = "http://id_m1-f0"
        child_module.case_details.short.filter = "child_filter = 1"
        factory.form_requires_case(child_form)

        # make child module point to advanced module as parent
        child_module.parent_select.active = True
        child_module.parent_select.module_id = parent_module.unique_id

        self.assertXmlPartialEqual(
            self.get_xml("advanced_module_parent_filters"), factory.app.create_suite(), "./entry[2]"
        )
 def set_up_app(self):
     self.factory = AppFactory(build_version='2.30.0')
     training_module = self.factory.app.add_module(Module.new_training_module('training module', None))
     self.releases_form = self.factory.app.new_form(training_module.id, "Untitled Form", None)
     self.releases_form.is_release_notes_form=True
     self.releases_form.xmlns = "http://openrosa.org/formdesigner/{}".format(uuid.uuid4().hex)
     basic_module, self.basic_form = self.factory.new_basic_module("basic_module", "doctor", with_form=True)
     self.basic_form.xmlns = "http://openrosa.org/formdesigner/{}".format(uuid.uuid4().hex)
 def setUpClass(cls):
     super(TestAppCasePropertyReferences, cls).setUpClass()
     factory = AppFactory(domain=cls.domain)
     m0 = factory.new_basic_module('save_to_case', cls.case_type, with_form=False)
     m0f1 = m0.new_form('save to case', 'en', attachment=cls.get_xml('basic_form').decode('utf-8'))
     m0f1.case_references = CaseReferences.wrap({
         'save': {
             "/data/question1": {
                 "case_type": cls.case_type,
                 "properties": [
                     "save_to_case_p1",
                     "save_to_case_p2"
                 ],
             }
         }
     })
     cls.current_app = factory.app
     cls.current_app.save()
Example #31
0
    def test_that_grid_style_is_added(self, *args):
        """
        Confirms that style="grid" is added to the root menu
        """
        factory = AppFactory(build_version='2.24.0')
        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)
    def test_case_list_registration_form_advanced(self):
        factory = AppFactory(build_version='2.9')

        register_module, register_form = factory.new_advanced_module('register_dugong', 'dugong')
        factory.form_opens_case(register_form)

        case_module, update_form = factory.new_advanced_module('update_dugong', 'dugong')
        factory.form_requires_case(update_form)

        case_module.case_list_form.form_id = register_form.get_unique_id()
        case_module.case_list_form.label = {
            'en': 'Register another Dugong'
        }
        self.assertXmlEqual(self.get_xml('case-list-form-advanced'), factory.app.create_suite())
Example #33
0
    def test_training_module_as_child(self, *args):
        factory = AppFactory(build_version='2.43.0')
        app = factory.app

        parent_module = Module.new_module('parent', 'en')
        app.add_module(parent_module)

        training_module, _ = factory.new_basic_module(
            'training', 'case_type', parent_module=parent_module)
        training_module.is_training_module = True

        self.assertIn(
            {
                'type': 'training module child',
                'module': {
                    'id': 1,
                    'unique_id': 'training_module',
                    'name': {
                        'en': 'training module'
                    }
                }
            }, app.validate_app())
Example #34
0
class BaseSchemaTest(SimpleTestCase):
    def setUp(self):
        self.factory = AppFactory()
        self.factory_2 = AppFactory()

    # -- helpers --

    def assert_has_kv_pairs(self, test_dict, expected_dict):
        """Assert that test_dict contains all key/value pairs in expected_dict

        Key/value pairs in `test_dict` but not present in
        `expected_dict` will be ignored.
        """
        for key, value in expected_dict.items():
            self.assertEqual(test_dict[key], value)

    def add_form(self, case_type=None, case_updates=None):
        module_id = len(self.factory.app.modules)
        module, form = self.factory.new_basic_module(module_id, case_type)
        if case_type:
            self.factory.form_opens_case(form, case_type)
        if case_updates:
            assert case_type, 'case_type is required with case_updates'
            self.factory.form_requires_case(form,
                                            case_type=case_type,
                                            update=case_updates)
        return form

    def add_form_app_2(self, case_type=None, case_updates=None):
        module_id = len(self.factory_2.app.modules)
        module, form = self.factory_2.new_basic_module(module_id, case_type)
        if case_type:
            self.factory_2.form_opens_case(form, case_type)
        if case_updates:
            assert case_type, 'case_type is required with case_updates'
            self.factory_2.form_requires_case(form,
                                              case_type=case_type,
                                              update=case_updates)
        return form
    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')
Example #36
0
    def test_inline_case_detail_from_another_module(self):
        factory = AppFactory()
        module0, form0 = factory.new_advanced_module("m0", "person")
        factory.form_requires_case(form0, "person")
        module0.case_details.short.use_case_tiles = True
        self._add_columns_for_case_details(module0)

        module1, form1 = factory.new_advanced_module("m1", "person")
        factory.form_requires_case(form1, "person")

        # not configured to use other module's persistent case tile so
        # has no detail-inline and detail-persistent attr
        self.ensure_module_session_datum_xml(factory, '', '')

        # configured to use other module's persistent case tile
        module1.case_details.short.persistent_case_tile_from_module = module0.unique_id
        self.ensure_module_session_datum_xml(factory, '', 'detail-persistent="m0_case_short"')

        # configured to use other module's persistent case tile that has custom xml
        module0.case_details.short.use_case_tiles = False
        module0.case_details.short.custom_xml = '<detail id="m0_case_short"></detail>'
        self.ensure_module_session_datum_xml(factory, '', 'detail-persistent="m0_case_short"')
        module0.case_details.short.custom_xml = ''
        module0.case_details.short.use_case_tiles = True

        # configured to use pull down tile from the other module
        module1.case_details.short.pull_down_tile = True
        self.ensure_module_session_datum_xml(factory, 'detail-inline="m0_case_long"',
                                             'detail-persistent="m0_case_short"')

        # set to use persistent case tile of its own as well but it would still
        # persists case tiles and detail inline from another module
        module1.case_details.short.use_case_tiles = True
        module1.case_details.short.persist_tile_on_forms = True
        self._add_columns_for_case_details(module1)
        self.ensure_module_session_datum_xml(factory, 'detail-inline="m0_case_long"',
                                             'detail-persistent="m0_case_short"')

        # set to use case tile from a module that does not support case tiles anymore
        # and has own persistent case tile as well
        # So now detail inline from its own details
        module0.case_details.short.use_case_tiles = False
        self.ensure_module_session_datum_xml(factory, 'detail-inline="m1_case_long"',
                                             'detail-persistent="m1_case_short"')

        # set to use case tile from a module that does not support case tiles anymore
        # and does not have its own persistent case tile as well
        module1.case_details.short.use_case_tiles = False
        self.ensure_module_session_datum_xml(factory, '', '')
Example #37
0
    def setUpClass(cls):
        super(TestGlobalAppConfig, cls).setUpClass()
        cls.project = Domain.get_or_create_with_name(cls.domain)

        cls.build_profile_id = 'english'
        factory = AppFactory(cls.domain, 'foo')
        m0, f0 = factory.new_basic_module("bar", "bar")
        f0.source = get_simple_form(xmlns=f0.unique_id)
        app = factory.app
        app.build_profiles = {
            cls.build_profile_id: BuildProfile(langs=['en'], name='English only'),
        }
        app.langs = ["en"]
        app.version = 1
        app.save()  # app is now v2

        cls.v2_build = app.make_build()
        cls.v2_build.is_released = True
        cls.v2_build.save()  # v2 is starred

        app.save()  # app is now v3
        cls.v3_build = app.make_build()
        cls.v3_build.is_released = True
        cls.v3_build.save()  # v3 is starred

        app.save()  # app is v4

        # Add a build-profile-specific release at v2
        cls.latest_profile = LatestEnabledBuildProfiles(
            domain=cls.domain,
            app_id=app.get_id,
            build_profile_id=cls.build_profile_id,
            version=cls.v2_build.version,
            build_id=cls.v2_build.get_id,
            active=True,
        )
        cls.latest_profile.save()

        cls.app = app
Example #38
0
    def testConvertToApplication(self):
        factory = AppFactory(build_version='2.40.0')
        m0, f0 = factory.new_basic_module('register', 'case')
        f0.source = get_simple_form(xmlns=f0.unique_id)
        factory.app.save()
        self.addCleanup(factory.app.delete)
        build = factory.app.make_build()
        build.is_released = True
        build.save()
        self.addCleanup(build.delete)

        linked_app = LinkedApplication()
        linked_app.domain = 'other-domain'
        linked_app.save()
        self.addCleanup(linked_app.delete)

        link_app(linked_app, factory.app.domain, factory.app.id)
        update_linked_app(linked_app, factory.app.id, 'system')

        unlinked_doc = linked_app.convert_to_application().to_json()
        self.assertEqual(unlinked_doc['doc_type'], 'Application')
        self.assertFalse(hasattr(unlinked_doc, 'linked_app_attrs'))
class ReleaseFormsSetupMixin(object):
    def set_up_app(self):
        self.factory = AppFactory(build_version='2.30.0')
        training_module = self.factory.app.add_module(
            Module.new_training_module('training module', None))
        self.releases_form = self.factory.app.new_form(training_module.id,
                                                       "Untitled Form", None)
        self.releases_form.is_release_notes_form = True
        self.releases_form.xmlns = "http://openrosa.org/formdesigner/{}".format(
            uuid.uuid4().hex)
        basic_module, self.basic_form = self.factory.new_basic_module(
            "basic_module", "doctor", with_form=True)
        self.basic_form.xmlns = "http://openrosa.org/formdesigner/{}".format(
            uuid.uuid4().hex)
Example #40
0
    def test_multi_select_module_errors(self, *args):
        factory = AppFactory()
        module, form = factory.new_basic_module('basic', 'person')
        factory.form_requires_case(form, 'person')

        module.case_details.short.multi_select = True
        module.search_config = CaseSearch(
            search_label=CaseSearchLabel(label={'en': 'Search'}),
            properties=[CaseSearchProperty(name=field) for field in ['name', 'greatest_fear']],
            data_registry="so_many_cases",
            data_registry_workflow=REGISTRY_WORKFLOW_LOAD_CASE,
        )

        self.assertIn({
            'type': 'data registry multi select',
            'module': {'id': 0, 'unique_id': 'basic_module', 'name': {'en': 'basic module'}}
        }, factory.app.validate_app())

        module.search_config.data_registry_workflow = REGISTRY_WORKFLOW_SMART_LINK
        self.assertIn({
            'type': 'smart links multi select',
            'module': {'id': 0, 'unique_id': 'basic_module', 'name': {'en': 'basic module'}}
        }, factory.app.validate_app())
Example #41
0
    def _get_app(self):
        factory = AppFactory(build_version='2.40.0')
        app = factory.app
        app.langs = ['en', 'fra']

        module, form = factory.new_basic_module('register', 'case')

        '''
            This form has two text questions, one with French audio present and one with it missing.

            It then has three select questions, each with two choices that share text and all
            have French audio specified. One set of choices has audio present for both, one has
            it missing for both, and one has it present for one choice and missing for the other.

            Lastly, it has two select questions, each with three choices that all have different
            text but use the same audio path. One of these two audio files is missing.
        '''
        form.source = self.get_xml('duplicate_text_questions').decode('utf-8')
        for path in form.wrapped_xform().audio_references():
            if 'present' in path or 'one_of_each1' in path:
                app.create_mapping(CommCareAudio(_id=uuid.uuid4().hex), path, save=False)

        return app
Example #42
0
    def setUp(self):
        self.factory = AppFactory()
        self.advanced_module, self.form0 = self.factory.new_advanced_module(
            'advanced_module', 'patient')
        self.form0.xmlns = 'http://openrosa.org/formdesigner/firstform'
        self.form0.actions.open_cases = [
            AdvancedOpenCaseAction(
                case_type="patient",
                case_tag="open__0",
            )
        ]
        self.form0.actions.load_update_cases = [
            LoadUpdateAction(
                case_type="patient",
                case_tag="load_0",
                case_properties={
                    "name": ConditionalCaseUpdate(question_path="/data/name")
                },
                preload={"/data/name": "name"},
                details_module=self.advanced_module.unique_id,
            )
        ]

        self.shadow_form = self.factory.new_shadow_form(self.advanced_module)
        self.shadow_form.shadow_parent_form_id = self.form0.unique_id
        # Shadow form load_update_case actions should contain all case tags from the parent
        self.shadow_form.extra_actions.load_update_cases = [
            LoadUpdateAction(
                case_type="patient",
                case_tag="load_0",
                details_module=self.advanced_module.unique_id,
            )
        ]

        self.basic_module = self.factory.new_basic_module("basic_module",
                                                          "doctor",
                                                          with_form=False)
Example #43
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']")
class FormPreparationV2TestMultiSelect(SimpleTestCase, TestXmlMixin):
    file_path = 'data', 'form_preparation_v2'

    def setUp(self):
        self.factory = AppFactory(domain="multiple-referrals")
        self.factory.app.version = 5
        self.module, self.form = self.factory.new_basic_module(
            'basic', 'person')
        self.form.source = self.get_xml(
            'original_form', override_path=('data', )).decode('utf-8')

        self.module.case_details.short.multi_select = True

    def test_open_case(self):
        self.form.actions.open_case = OpenCaseAction(
            name_update=ConditionalCaseUpdate(
                question_path="/data/question1"), )
        self.form.actions.open_case.condition.type = 'always'
        self.form.actions.update_case = UpdateCaseAction(
            update={
                'question1': ConditionalCaseUpdate(
                    question_path='/data/question1')
            })
        self.form.actions.update_case.condition.type = 'always'
        self.assertXmlEqual(self.get_xml('multi_open_update_case'),
                            self.form.render_xform())

    def test_update_case(self):
        self.factory.form_requires_case(self.form, 'person')
        self.form.actions.update_case = UpdateCaseAction(
            update={
                'question1': ConditionalCaseUpdate(
                    question_path='/data/question1')
            })
        self.form.actions.update_case.condition.type = 'always'
        self.assertXmlEqual(self.get_xml('multi_no_actions'),
                            self.form.render_xform())
Example #45
0
    def test_update_from_specific_build(self, *args):
        factory = AppFactory(self.domain, "Upstream Application")
        m0, f0 = factory.new_basic_module("M1", None)
        f0.source = get_simple_form()
        master_app = factory.app
        master_app.save()
        self.addCleanup(master_app.delete)

        linked_app = LinkedApplication.new_app(self.linked_domain,
                                               "Linked Application")
        linked_app.save()
        self.addCleanup(linked_app.delete)

        copy1 = self._make_build(master_app, True)

        m1, f1 = factory.new_basic_module("M2", None)
        f1.source = get_simple_form()
        master_app.save()  # increment version number
        self._make_build(master_app, True)

        update_linked_app(linked_app, copy1, 'test_update_from_specific_build')
        linked_app = LinkedApplication.get(linked_app._id)
        self.assertEqual(len(linked_app.modules), 1)
        self.assertEqual(linked_app.version, copy1.version)
Example #46
0
    def setUpClass(cls):
        super(TestBuildingSchemaFromApplication, cls).setUpClass()
        cls.current_app = Application.wrap(cls.get_json('basic_application'))

        cls.first_build = Application.wrap(cls.get_json('basic_application'))
        cls.first_build._id = '123'
        cls.first_build.copy_of = cls.current_app.get_id
        cls.first_build.version = 3
        cls.first_build.has_submissions = True

        factory = AppFactory(build_version='2.36.0')
        m0, f0 = factory.new_advanced_module('mod0', 'advanced')
        f0.source = cls.get_xml('repeat_group_form').decode('utf-8')
        f0.xmlns = 'repeat-xmlns'

        factory.form_requires_case(f0, 'case0')
        f0.actions.open_cases = [
            AdvancedOpenCaseAction(
                case_type="advanced",
                case_tag="open_case_0",
                name_update=ConditionalCaseUpdate(
                    question_path="/data/question3/question4"),
                repeat_context="/data/question3",
                case_indices=[CaseIndex(tag='load_case0_0')])
        ]
        cls.advanced_app = factory.app
        cls.advanced_app.save()

        cls.apps = [
            cls.current_app,
            cls.first_build,
            cls.advanced_app,
        ]
        with drop_connected_signals(app_post_save):
            for app in cls.apps:
                app.save()
Example #47
0
    def test_app_strings(self):
        factory = AppFactory(build_version='2.40.0')
        factory.app.langs = ['en', 'es']
        module, form = factory.new_basic_module('my_module', 'cases')
        module.name = {
            'en': 'Fascination Street',
            'es': 'Calle de Fascinación',
        }
        form.name = {
            'en': 'Prayers for Rain',
            'es': 'Oraciones por la Lluvia',
        }

        en_strings = self._generate_app_strings(factory.app, 'en')
        self.assertEqual(en_strings['modules.m0'], module.name['en'])
        self.assertEqual(en_strings['forms.m0f0'], form.name['en'])

        es_strings = self._generate_app_strings(factory.app, 'es')
        self.assertEqual(es_strings['modules.m0'], module.name['es'])
        self.assertEqual(es_strings['forms.m0f0'], form.name['es'])

        default_strings = self._generate_app_strings(factory.app, 'default')
        self.assertEqual(default_strings['modules.m0'], module.name['en'])
        self.assertEqual(default_strings['forms.m0f0'], form.name['en'])
 def setUpClass(cls):
     super(AppManagerDataSourceConfigTest, cls).setUpClass()
     factory = AppFactory(domain=cls.domain)
     # create main form that defines case schema
     m0, f0 = factory.new_basic_module('Main Module', cls.case_type)
     f0.source = get_simple_xform()
     f0.name = {'en': 'Main Form'}
     factory.form_requires_case(f0,
                                case_type=cls.case_type,
                                update={
                                    cp: '/data/{}'.format(cp)
                                    for cp in cls.case_properties.keys()
                                })
     cls.main_form = f0
     # create another module/form to generate a parent case relationship
     # for the main case type
     m1, f1 = factory.new_basic_module('Parent Module', cls.parent_type)
     f1.source = get_simple_xform(
     )  # not used, just needs to be some valid XForm
     f1.name = {'en': 'Parent Form'}
     factory.form_opens_case(f1, case_type=cls.parent_type)
     factory.form_opens_case(f1, case_type=cls.case_type, is_subcase=True)
     cls.app = factory.app
     cls.app.save()
Example #49
0
 def test_custom_variables(self, *args):
     factory = AppFactory()
     module, form = factory.new_basic_module('m0', 'case1')
     factory.form_requires_case(form, 'case')
     short_custom_variables = "<variable function='true()' /><foo function='bar'/>"
     long_custom_variables = (
         '<bar function="true()" />'
         '<baz function="instance(\'locations\')/locations/location[0]"/>'
     )
     module.case_details.short.custom_variables = short_custom_variables
     module.case_details.long.custom_variables = long_custom_variables
     suite = factory.app.create_suite()
     self.assertXmlPartialEqual(
         """
         <partial>
             <variables>
                 {short_variables}
             </variables>
             <variables>
                 {long_variables}
             </variables>
         </partial>
         """.format(short_variables=short_custom_variables, long_variables=long_custom_variables),
         suite,
         "detail/variables"
     )
     self.assertXmlPartialEqual(
         """
         <partial>
             <instance id="casedb" src="jr://instance/casedb"/>
             <instance id="locations" src="jr://fixture/locations"/>
         </partial>
         """.format(short_variables=short_custom_variables, long_variables=long_custom_variables),
         suite,
         "entry[1]/instance"
     )
Example #50
0
    def test_form_data_with_case_properties(self):
        factory = AppFactory()
        self._build_app_with_groups(factory)
        app = factory.app
        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'][1]['children'][0]['save_properties'][0]
        self.assertEqual(group_saves.case_type, 'household')
        self.assertEqual(group_saves.property, 'age')

        q3_loads = modules[0]['forms'][0]['questions'][2]['load_properties'][0]
        self.assertEqual(q3_loads.case_type, 'household')
        self.assertEqual(q3_loads.property, 'polar_bears_seen')
Example #51
0
class TestCaseSearchLabelsMigration(TestCase):
    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')
        self.factory.app.save()

    @classmethod
    def tearDownClass(cls):
        delete_all_apps()
        super(TestCaseSearchLabelsMigration, cls).tearDownClass()

    def test_migration(self):
        # module with default case search labels
        self._remove_new_properties_from_doc(self.factory.app)
        call_command('migrate_case_search_labels', domain=self.domain)
        app, module = self._reload_app_and_module()

        self.assertEqual(self.module.search_config.search_label.label, {'en': 'Search All Cases'})
        self.assertEqual(self.module.search_config.search_again_label.label, {'en': 'Search Again'})

        # module with updated case search labels
        module.search_config.command_label = {'en': 'Find my cases'}
        module.search_config.again_label = {'en': 'Find Again', 'fr': 'trouve encore'}
        app.save()

        self._remove_new_properties_from_doc(app)
        call_command('migrate_case_search_labels', domain=self.domain)

        app, module = self._reload_app_and_module()
        self.assertEqual(module.search_config.search_label.label, {'en': 'Find my cases'})
        self.assertEqual(module.search_config.search_again_label.label,
                         {'en': 'Find Again', 'fr': 'trouve encore'})

    @staticmethod
    def _remove_new_properties_from_doc(app):
        # remove the new properties from doc as how it would be during migration
        app_doc = app.to_json()
        module = app_doc["modules"][0]
        module["search_config"].pop("search_label")
        module["search_config"].pop("search_again_label")
        app.get_db().save_docs([app_doc])

    def _reload_app_and_module(self):
        app = get_app(self.domain, self.factory.app.get_id)
        return app, list(app.get_modules())[0]
Example #52
0
    def test_case_list_registration_form_advanced_autoload(self):
        factory = AppFactory(build_version='2.9.0')

        register_module, register_form = factory.new_advanced_module(
            'register_dugong', 'dugong')
        factory.form_opens_case(register_form)
        register_form.actions.load_update_cases.append(
            LoadUpdateAction(case_tag='usercase',
                             auto_select=AutoSelectCase(
                                 mode=AUTO_SELECT_USERCASE, )))

        case_module, update_form = factory.new_advanced_module(
            'update_dugong', 'dugong')
        factory.form_requires_case(update_form)

        case_module.case_list_form.form_id = register_form.get_unique_id()
        case_module.case_list_form.label = {'en': 'Register another Dugong'}
        self.assertXmlEqual(self.get_xml('case-list-form-advanced-autoload'),
                            factory.app.create_suite())
    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.0')
        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())
Example #54
0
    def test_fixture_to_case_selection_parent_child(self):
        factory = AppFactory(build_version='2.9')

        m0, m0f0 = factory.new_basic_module('parent', 'parent')
        m0.fixture_select.active = True
        m0.fixture_select.fixture_type = 'province'
        m0.fixture_select.display_column = 'display_name'
        m0.fixture_select.variable_column = 'var_name'
        m0.fixture_select.xpath = 'province = $fixture_value'

        factory.form_requires_case(m0f0)

        m1, m1f0 = factory.new_basic_module('child', 'child')
        m1.fixture_select.active = True
        m1.fixture_select.fixture_type = 'city'
        m1.fixture_select.display_column = 'display_name'
        m1.fixture_select.variable_column = 'var_name'
        m1.fixture_select.xpath = 'city = $fixture_value'

        factory.form_requires_case(m1f0, parent_case_type='parent')

        self.assertXmlEqual(self.get_xml('fixture-to-case-selection-parent-child'), factory.app.create_suite())
Example #55
0
    def test_grid_menu_for_some(self):
        factory = AppFactory(build_version='2.24.3')
        factory.app.create_profile()
        factory.app.grid_form_menus = 'some'
        factory.new_basic_module('registration', 'patient')
        factory.new_basic_module('visit', 'patient visit')
        factory.app.get_module(1).display_style = 'grid'
        root_xpath = './menu[@id="root"]'
        grid_module_xpath = './menu[@id="m1"]'

        # with Modules Menu to be list should not render root menu and render module w/ style=grid
        factory.app.use_grid_menus = False
        suite = factory.app.create_suite()
        self.assertXmlDoesNotHaveXpath(suite, root_xpath)
        self.assertXmlHasXpath(suite, grid_module_xpath)
        self.assertXmlPartialEqual(
            '<partial><menu id="m1" style="grid"><text><locale id="modules.m1"/></text>\
            <command id="m1-f0"/></menu></partial>',
            suite,
            grid_module_xpath
        )

        # with Modules Menu to be grid should render both root menu and module w/ style=grid
        factory.app.use_grid_menus = True
        suite = factory.app.create_suite()
        self.assertXmlHasXpath(suite, root_xpath)
        self.assertXmlPartialEqual(
            '<partial><menu id="root" style="grid"><text/></menu></partial>',
            suite,
            root_xpath
        )
        self.assertXmlPartialEqual(
            '<partial><menu id="m1" style="grid"><text><locale id="modules.m1"/></text>\
            <command id="m1-f0"/></menu></partial>',
            suite,
            grid_module_xpath
        )

        # with module itself being the root should render root menu style=grid with module content
        factory.app.get_module(1).put_in_root = True
        suite = factory.app.create_suite()
        self.assertXmlPartialEqual(
            '<partial><menu id="root" style="grid"><text><locale id="modules.m1"/></text>\
            <command id="m1-f0"/></menu></partial>',
            suite,
            root_xpath
        )
Example #56
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')
Example #57
0
    def test_case_list_form_media(self):
        app = AppFactory.case_list_form_app_factory().app
        app.build_spec = self.min_spec

        no_media_xml = self.XML_without_media("case_list_form.m0", for_action_menu=True)
        self.assertXmlPartialEqual(
            no_media_xml,
            app.create_suite(),
            "./detail[@id='m0_case_short']/action/display"
        )

        app.get_module(0).case_list_form.set_icon('en', self.image_path)
        app.get_module(0).case_list_form.set_audio('en', self.audio_path)

        XML = self.makeXML("case_list_form.m0", "case_list_form.m0.icon", "case_list_form.m0.audio")
        self.assertXmlPartialEqual(XML, app.create_suite(), "./detail[@id='m0_case_short']/action/display")
        self._assert_app_strings_available(app, 'en')

        icon_locale = id_strings.case_list_form_icon_locale(app.get_module(0))
        audio_locale = id_strings.case_list_form_audio_locale(app.get_module(0))
        self._test_correct_icon_translations(app, app.get_module(0).case_list_form, icon_locale)
        self._test_correct_audio_translations(app, app.get_module(0).case_list_form, audio_locale)
Example #58
0
    def test_empty_module_errors(self, *args):
        factory = AppFactory(build_version='2.24.0')
        app = factory.app
        m1 = factory.new_basic_module('register', 'case', with_form=False)
        factory.new_advanced_module('update', 'case', with_form=False)

        m2 = factory.new_basic_module('update', 'case', with_form=False)
        m2.case_list = CaseList(show=True, label={'en': "case_list"})

        factory.new_shadow_module('update', m1, with_form=False)
        errors = app.validate_app()

        standard_module_error = {
            'type': 'no forms or case list',
            'module': {'id': 0, 'name': {'en': 'register module'}},
        }
        advanced_module_error = {
            'type': 'no forms or case list',
            'module': {'id': 1, 'name': {'en': 'update module'}},
        }
        self._clean_unique_id(errors)
        self.assertEqual(len(errors), 2)
        self.assertIn(standard_module_error, errors)
        self.assertIn(advanced_module_error, errors)
Example #59
0
    def test_tiered_select_with_advanced_module_as_parent_with_filters(self):
        factory = AppFactory(build_version='2.25')
        parent_module, parent_form = factory.new_advanced_module(
            'parent', 'parent')
        parent_module.case_details.short.filter = 'parent_filter = 1'

        child_module, child_form = factory.new_basic_module('child', 'child')
        child_form.xmlns = 'http://id_m1-f0'
        child_module.case_details.short.filter = 'child_filter = 1'
        factory.form_requires_case(child_form)

        # make child module point to advanced module as parent
        child_module.parent_select.active = True
        child_module.parent_select.module_id = parent_module.unique_id

        self.assertXmlPartialEqual(
            self.get_xml('advanced_module_parent_filters'),
            factory.app.create_suite(), "./entry[2]")
Example #60
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()