def test_child_module_adjusted_datums_basic_module(self):
        """
        Testing that the session variable name for the case_id is correct since
        it will have been adjusted in the suite.xml to match the variable name
        in the root module.
        """
        module = self.app.add_module(Module.new_module('New Module', lang='en'))
        module.case_type = 'guppy'
        form = module.new_form("Untitled Form", "en", self.get_xml('original_form', override_path=('data',)))

        form.requires = 'case'
        form.actions.update_case = UpdateCaseAction(update={'question1': '/data/question1'})
        form.actions.update_case.condition.type = 'always'

        root_module = self.app.add_module(Module.new_module('root module', None))
        root_module.unique_id = 'm_root'
        root_module.case_type = 'test_case_type'

        root_module_form = root_module.new_form('root module form', None)
        root_module_form.requires = 'case'
        root_module_form.actions.update_case = UpdateCaseAction(update={'question1': '/data/question1'})
        root_module_form.actions.update_case.condition.type = 'always'

        # make module a child module of root_module
        module.root_module_id = root_module.unique_id

        module.parent_select.active = True
        module.parent_select.module_id = root_module.unique_id

        self.assertXmlEqual(self.get_xml('child_module_adjusted_case_id_basic'), form.render_xform())
Exemple #2
0
def apps_modules_setup(test_case):
    """
    Additional setUp and tearDown for get_apps_modules tests
    """
    test_case.app.add_module(Module.new_module("Module0", "en"))
    test_case.app.save()

    test_case.other_app = Application.new_app(test_case.project.name, "OtherApp")
    test_case.other_app.add_module(Module.new_module("Module0", "en"))
    test_case.other_app.save()

    test_case.deleted_app = Application.new_app(test_case.project.name, "DeletedApp")
    test_case.deleted_app.add_module(Module.new_module("Module0", "en"))
    test_case.deleted_app.save()
    test_case.deleted_app.delete_app()
    test_case.deleted_app.save()  # delete_app() changes doc_type. This save() saves that.

    test_case.linked_app = create_linked_app(test_case.project.name, test_case.app.id,
                                             test_case.project.name, 'LinkedApp')
    try:
        yield
    finally:
        Application.get_db().delete_doc(test_case.linked_app.id)
        Application.get_db().delete_doc(test_case.deleted_app.id)
        Application.get_db().delete_doc(test_case.other_app.id)
    def test_subcase_repeat_mixed_form(self):
        app = Application.new_app(None, "Untitled Application", application_version=APP_V2)
        module_0 = app.add_module(Module.new_module('parent', None))
        module_0.unique_id = 'm0'
        module_0.case_type = 'parent'
        form = app.new_form(0, "Form", None, attachment=self.get_xml('subcase_repeat_mixed_form_pre'))

        module_1 = app.add_module(Module.new_module('subcase', None))
        module_1.unique_id = 'm1'
        module_1.case_type = 'subcase'

        form.actions.open_case = OpenCaseAction(name_path="/data/parent_name")
        form.actions.open_case.condition.type = 'always'

        form.actions.subcases.append(OpenSubCaseAction(
            case_type=module_1.case_type,
            case_name="/data/first_child_name",
            condition=FormActionCondition(type='always')
        ))
        # subcase in the middle that has a repeat context
        form.actions.subcases.append(OpenSubCaseAction(
            case_type=module_1.case_type,
            case_name="/data/repeat_child/repeat_child_name",
            repeat_context='/data/repeat_child',
            condition=FormActionCondition(type='always')
        ))
        form.actions.subcases.append(OpenSubCaseAction(
            case_type=module_1.case_type,
            case_name="/data/last_child_name",
            condition=FormActionCondition(type='always')
        ))

        self.assertXmlEqual(self.get_xml('subcase_repeat_mixed_form_post'),
                            app.get_module(0).get_form(0).render_xform())
    def test_child_module_adjusted_datums_basic_module(self):
        """
        Testing that the session variable name for the case_id is correct since
        it will have been adjusted in the suite.xml to match the variable name
        in the root module.
        """
        module = self.app.add_module(Module.new_module("New Module", lang="en"))
        module.case_type = "guppy"
        form = module.new_form("Untitled Form", "en", self.get_xml("original"))

        form.requires = "case"
        form.actions.update_case = UpdateCaseAction(update={"question1": "/data/question1"})
        form.actions.update_case.condition.type = "always"

        root_module = self.app.add_module(Module.new_module("root module", None))
        root_module.unique_id = "m_root"
        root_module.case_type = "test_case_type"

        root_module_form = root_module.new_form("root module form", None)
        root_module_form.requires = "case"
        root_module_form.actions.update_case = UpdateCaseAction(update={"question1": "/data/question1"})
        root_module_form.actions.update_case.condition.type = "always"

        # make module a child module of root_module
        module.root_module_id = root_module.unique_id

        module.parent_select.active = True
        module.parent_select.module_id = root_module.unique_id

        self.assertXmlEqual(self.get_xml("child_module_adjusted_case_id_basic"), form.render_xform())
    def setUpClass(cls):
        super(TestDelayedSchema, cls).setUpClass()
        cls.current_app = Application.new_app(cls.domain, "Untitled Application")
        cls.current_app._id = '1234'
        cls.current_app.version = 10
        module = cls.current_app.add_module(Module.new_module('Untitled Module', None))
        form = module.new_form("Untitled Form", 'en', attachment=cls.get_xml('basic_form').decode('utf-8'))
        form.xmlns = cls.xmlns

        cls.build = Application.new_app(cls.domain, "Untitled Application")
        cls.build._id = '5678'
        cls.build.copy_of = cls.current_app._id
        cls.build.version = 5
        cls.build.has_submissions = True
        module = cls.build.add_module(Module.new_module('Untitled Module', None))
        form = module.new_form("Untitled Form", 'en',
                               attachment=cls.get_xml('basic_form_version2').decode('utf-8'))
        form.xmlns = cls.xmlns

        cls.apps = [
            cls.current_app,
            cls.build,
        ]
        with drop_connected_signals(app_post_save):
            for app in cls.apps:
                app.save()
    def setUp(self):
        self.app = Application.new_app('domain', "Untitled Application")

        self.parent = self.app.add_module(Module.new_module('Parent Module', None))
        self.app.new_form(self.parent.id, "Parent Form", None)

        self.child = self.app.add_module(Module.new_module('Child Module', None))
        self.child.root_module_id = self.parent.unique_id
        self.app.new_form(self.child.id, "Child Form", None)

        self.shadow = self.app.add_module(ShadowModule.new_module('Shadow Module', None))
Exemple #7
0
    def _get_family_app(self):
        app = Application.new_app('domain', "Untitled Application")

        parent = app.add_module(Module.new_module('module', None))
        app.new_form(parent.id, "Untitled Form", None)

        child = app.add_module(Module.new_module('module', None))
        child.root_module_id = parent.unique_id

        app.new_form(child.id, "Untitled Form", None)
        shadow = app.add_module(ShadowModule.new_module('module', None))

        return (app, shadow)
    def test_overwrite_app_maintain_ids(self):
        module = self.plain_master_app.add_module(Module.new_module('M1', None))
        module.new_form('f1', None, self.get_xml('very_simple_form').decode('utf-8'))

        module = self.linked_app.add_module(Module.new_module('M1', None))
        module.new_form('f1', None, self.get_xml('very_simple_form').decode('utf-8'))

        id_map_before = _get_form_id_map(self.linked_app)

        overwrite_app(self.linked_app, self.plain_master_app, {})
        self.assertEqual(
            id_map_before,
            _get_form_id_map(LinkedApplication.get(self.linked_app._id))
        )
Exemple #9
0
    def new_edit_subject_module(self, app, reg_form_id):

        def add_edit_form_to_module(module_):
            edit_form = module_.new_form('Edit Subject', None)
            edit_form.get_unique_id()
            edit_form.source = self.get_subject_form_source('Edit Subject')
            edit_form.requires = 'case'
            update = dict(self.case_update, name='/data/' + CC_SUBJECT_KEY)
            preload = {v: k for k, v in update.items()}
            edit_form.actions.case_preload = PreloadAction(
                preload=preload,
                condition=FormActionCondition(type='always')
            )
            edit_form.actions.update_case = UpdateCaseAction(
                update=update,
                condition=FormActionCondition(type='always')
            )

        module = app.add_module(Module.new_module('Study Subjects', None))
        module.unique_id = 'study_subjects'
        module.case_type = 'subject'
        module.case_list_form = CaseListForm(
            form_id=reg_form_id,
            label={'en': 'Register Subject'}
        )
        add_edit_form_to_module(module)
        return module
    def test_child_module_adjusted_datums_advanced_module(self):
        """
        Testing that the session variable name for the case_id is correct since
        it will have been adjusted in the suite.xml to match the variable name
        in the root module.
        """
        module = self.app.add_module(AdvancedModule.new_module("New Module", lang="en"))
        module.case_type = "test_case_type"
        form = module.new_form("Untitled Form", "en", self.get_xml("original_form", override_path=("data",)))

        form.actions.load_update_cases.append(
            LoadUpdateAction(
                case_type=module.case_type, case_tag="load_1", case_properties={"question1": "/data/question1"}
            )
        )

        root_module = self.app.add_module(Module.new_module("root module", None))
        root_module.unique_id = "m_root"
        root_module.case_type = module.case_type

        root_module_form = root_module.new_form("root module form", None)
        root_module_form.requires = "case"
        root_module_form.actions.update_case = UpdateCaseAction(update={"question1": "/data/question1"})
        root_module_form.actions.update_case.condition.type = "always"

        # make module a child module of root_module
        module.root_module_id = root_module.unique_id

        self.assertXmlEqual(self.get_xml("child_module_adjusted_case_id_advanced"), form.render_xform())
Exemple #11
0
def new_module(request, domain, app_id):
    "Adds a module to an app"
    app = get_app(domain, app_id)
    lang = request.COOKIES.get('lang', app.langs[0])
    name = request.POST.get('name')
    module_type = request.POST.get('module_type', 'case')
    if module_type == 'case':
        module = app.add_module(Module.new_module(name, lang))
        module_id = module.id
        app.new_form(module_id, "Untitled Form", lang)
        app.save()
        response = back_to_main(request, domain, app_id=app_id, module_id=module_id)
        response.set_cookie('suppress_build_errors', 'yes')
        return response
    elif module_type in MODULE_TYPE_MAP:
        fn = MODULE_TYPE_MAP[module_type][FN]
        validations = MODULE_TYPE_MAP[module_type][VALIDATIONS]
        error = next((v[1] for v in validations if v[0](app)), None)
        if error:
            messages.warning(request, error)
            return back_to_main(request, domain, app_id=app.id)
        else:
            return fn(request, domain, app, name, lang)
    else:
        logger.error('Unexpected module type for new module: "%s"' % module_type)
        return back_to_main(request, domain, app_id=app_id)
    def test_child_module_adjusted_datums(self):
        """
        Testing that the session variable name for the case_id is correct since
        it will have been adjusted in the suite.xml to match the variable name
        in the root module.
        """
        self.form.actions.load_update_cases.append(LoadUpdateAction(
            case_type=self.module.case_type,
            case_tag='load_1',
            case_properties={'question1': '/data/question1'}
        ))

        root_module = self.app.add_module(Module.new_module('root module', None))
        root_module.unique_id = 'm_root'
        root_module.case_type = self.module.case_type

        root_module_form = self.app.new_form(1, 'root module form', None)
        root_module_form.requires = 'case'
        root_module_form.actions.update_case = UpdateCaseAction(update={'question1': '/data/question1'})
        root_module_form.actions.update_case.condition.type = 'always'

        # make module a child module of root_module
        self.module.root_module_id = root_module.unique_id

        self.assertXmlEqual(self.get_xml('child_module_adjusted_case_id'), self.form.render_xform())
Exemple #13
0
    def create_two_module_app(self, domain_name, app_name):

        app = Application.new_app(domain_name, app_name)
        app.add_module(Module.new_module('Module 1', None))
        app.add_module(Module.new_module('Module 2', None))

        for m_id in range(2):
            app.new_form(m_id, "Form", None)

        app.save()

        print "Application {app_name}: {app_url} created in domain {domain_name}".format(
            app_name=app_name,
            app_url=reverse('view_app', args=[domain_name, app._id], absolute=True),
            domain_name=domain_name
        )
Exemple #14
0
 def setUp(self):
     self.app = Application.new_app(DOMAIN, "Untitled Application")
     self.module = self.app.add_module(Module.new_module("Untitled Module", None))
     self.app.new_form(0, "Untitled Form", None)
     self.module.case_type = 'case'
     self.module.search_config = CaseSearch(
         command_label={'en': 'Search Patients Nationally'},
         properties=[
             CaseSearchProperty(name='name', label={'en': 'Name'}),
             CaseSearchProperty(name='dob', label={'en': 'Date of birth'})
         ],
         relevant="{} and {}".format("instance('groups')/groups/group", CLAIM_DEFAULT_RELEVANT_CONDITION),
         default_properties=[
             DefaultCaseSearchProperty(
                 property=u'ɨŧsȺŧɍȺᵽ',
                 defaultValue=(
                     u"instance('casedb')/case"
                     u"[@case_id='instance('commcaresession')/session/data/case_id']"
                     u"/ɨŧsȺŧɍȺᵽ")
             ),
             DefaultCaseSearchProperty(
                 property='name',
                 defaultValue="instance('locations')/locations/location[@id=123]/@type",
             ),
         ],
     )
 def setUp(self):
     self.app = Application.new_app('domain', 'New App', APP_V2)
     self.app.version = 3
     self.module = self.app.add_module(Module.new_module('New Module', lang='en'))
     self.form = self.app.new_form(0, 'New Form', lang='en')
     self.module.case_type = 'test_case_type'
     self.form.source = self.get_xml('original')
Exemple #16
0
    def test_case_tile_pull_down(self):
        app = Application.new_app('domain', 'Untitled Application')

        module = app.add_module(Module.new_module('Untitled Module', None))
        module.case_type = 'patient'
        module.case_details.short.use_case_tiles = True
        module.case_details.short.persist_tile_on_forms = True
        module.case_details.short.pull_down_tile = True

        module.case_details.short.columns = [
            DetailColumn(
                header={'en': 'a'},
                model='case',
                field='a',
                format='plain',
                case_tile_field='header'
            ),
            DetailColumn(
                header={'en': 'b'},
                model='case',
                field='b',
                format='plain',
                case_tile_field='top_left'
            ),
            DetailColumn(
                header={'en': 'c'},
                model='case',
                field='c',
                format='enum',
                enum=[
                    MappingItem(key='male', value={'en': 'Male'}),
                    MappingItem(key='female', value={'en': 'Female'}),
                ],
                case_tile_field='sex'
            ),
            DetailColumn(
                header={'en': 'd'},
                model='case',
                field='d',
                format='plain',
                case_tile_field='bottom_left'
            ),
            DetailColumn(
                header={'en': 'e'},
                model='case',
                field='e',
                format='date',
                case_tile_field='date'
            ),
        ]

        form = app.new_form(0, "Untitled Form", None)
        form.xmlns = 'http://id_m0-f0'
        form.requires = 'case'

        self.assertXmlPartialEqual(
            self.get_xml('case_tile_pulldown_session'),
            app.create_suite(),
            "./entry/session"
        )
    def build_app_with_recently_fixed_form(self, mock):
        """
        Generates an app with a form that:
        - had an "undefined" xmlns
        - had forms submitted with the bad xmlns
        - had xmlns changed to something real
        - had forms submitted with real xmlns
        """
        form_name = "Untitled Form"

        app = Application.new_app(DOMAIN, 'Normal App')
        module = app.add_module(Module.new_module('New Module', lang='en'))
        form_source = self.get_xml('form_template').decode('utf-8').format(
            xmlns="undefined", name=form_name
        )
        form = module.new_form(form_name, "en", form_source)
        app.save()
        bad_build = app.make_build()
        bad_build.save()

        bad_xform = self._submit_form(form.xmlns, form_name, app._id, bad_build._id)

        xmlns = generate_random_xmlns()
        form = app.get_form(form.unique_id)
        form.source = self.get_xml('form_template').decode('utf-8').format(
            xmlns=xmlns, name=form_name
        )
        form.xmlns = xmlns
        app.save()

        good_build = app.make_build()
        good_build.save()
        good_xform = self._submit_form(form.xmlns, form_name, app._id, good_build._id)

        return form, good_build, bad_build, good_xform, bad_xform
    def build_app_with_bad_form(self, mock):
        """
        Generates an app with one normal form, and one form with "undefined" xmlns
        Generates submissions against both forms.
        """
        xmlns = generate_random_xmlns()
        good_form_name = "Untitled Form"
        bad_form_name = "Bad Form"

        app = Application.new_app(DOMAIN, 'Normal App')
        module = app.add_module(Module.new_module('New Module', lang='en'))
        good_form_source = self.get_xml('form_template').decode('utf-8').format(xmlns=xmlns, name=good_form_name)
        good_form = module.new_form(good_form_name, "en", good_form_source)
        bad_form_source = self.get_xml('form_template').decode('utf-8').format(
            xmlns="undefined", name=bad_form_name)
        bad_form = module.new_form(bad_form_name, "en", bad_form_source)
        app.save()
        build = app.make_build()
        build.save()

        good_xform = self._submit_form(xmlns, good_form_name, app._id, build._id)

        bad_xforms = []
        for i in range(2):
            bad_xform = self._submit_form("undefined", bad_form_name, app._id, build._id)
            bad_xforms.append(bad_xform)

        return good_form, bad_form, good_xform, bad_xforms
 def setUp(self):
     self.app = Application.new_app("domain", "New App", APP_V2)
     self.app.version = 3
     self.module = self.app.add_module(Module.new_module("New Module", lang="en"))
     self.form = self.app.new_form(0, "New Form", lang="en")
     self.module.case_type = "test_case_type"
     self.form.source = self.get_xml("original_form", override_path=("data",))
    def test_case_list_lookup_w_extras_and_responses(self):
        app = Application.new_app('domain', 'Untitled Application')
        module = app.add_module(Module.new_module('Untitled Module', None))
        module.case_type = 'patient'
        module.case_details.short.lookup_enabled = True
        module.case_details.short.lookup_action = "callout.commcarehq.org.dummycallout.LAUNCH"
        module.case_details.short.lookup_extras = [
            {'key': 'action_0', 'value': 'com.biometrac.core.SCAN'},
            {'key': "action_1", 'value': "com.biometrac.core.IDENTIFY"},
        ]
        module.case_details.short.lookup_responses = [
            {"key": "match_id_0"},
            {"key": "match_id_1"},
        ]

        expected = """
        <partial>
            <lookup action="callout.commcarehq.org.dummycallout.LAUNCH">
                <extra key="action_0" value="com.biometrac.core.SCAN"/>
                <extra key="action_1" value="com.biometrac.core.IDENTIFY"/>
                <response key="match_id_0"/>
                <response key="match_id_1"/>
            </lookup>
        </partial>
        """

        self.assertXmlPartialEqual(
            expected,
            app.create_suite(),
            "./detail/lookup"
        )
 def _make_module(self, app, module_id, case_type):
     m = app.add_module(Module.new_module('Module{}'.format(module_id), lang='en'))
     m.case_type = case_type
     mf = app.new_form(module_id, 'form {}'.format(case_type), lang='en')
     mf.actions.open_case = OpenCaseAction(name_path="/data/question1", external_id=None)
     mf.actions.open_case.condition.type = 'always'
     return m
    def test_child_module_adjusted_datums_advanced_module(self):
        """
        Testing that the session variable name for the case_id is correct since
        it will have been adjusted in the suite.xml to match the variable name
        in the root module.
        """
        module = self.app.add_module(AdvancedModule.new_module('New Module', lang='en'))
        module.case_type = 'test_case_type'
        form = module.new_form("Untitled Form", "en",
                               self.get_xml('original_form', override_path=('data',)).decode('utf-8'))

        form.actions.load_update_cases.append(LoadUpdateAction(
            case_type=module.case_type,
            case_tag='load_1',
            case_properties={'question1': '/data/question1'}
        ))

        root_module = self.app.add_module(Module.new_module('root module', None))
        root_module.unique_id = 'm_root'
        root_module.case_type = module.case_type

        root_module_form = root_module.new_form('root module form', None)
        root_module_form.requires = 'case'
        root_module_form.actions.update_case = UpdateCaseAction(update={'question1': '/data/question1'})
        root_module_form.actions.update_case.condition.type = 'always'

        # make module a child module of root_module
        module.root_module_id = root_module.unique_id

        self.assertXmlEqual(self.get_xml('child_module_adjusted_case_id_advanced'), form.render_xform())
Exemple #23
0
    def test_download_file_bad_xform_404(self):
        '''
        This tests that the `download_file` view returns
        HTTP code 404 for XML that cannot be generated...
        in some sense it does not exist.
        '''

        module = self.app.add_module(Module.new_module("Module0", "en"))

        # These builds are checked in to the repo for use in tests
        build1 = {'version': '1.2.dev', 'build_number': 7106}
        build2 = {'version': '2.7.0', 'build_number': 20655}

        add_build(**build1)
        add_build(**build2)

        with open(os.path.join(os.path.dirname(__file__), "data", "invalid_form.xml")) as f:
            xform_str = f.read()
        self.app.new_form(module.id, name="Form0-0", attachment=xform_str, lang="en")
        self.app.save()

        response = self.client.get(reverse('app_download_file', kwargs=dict(domain=self.domain.name,
                                                                            app_id=self.app.get_id,
                                                                            path='modules-0/forms-0.xml')))
        self.assertEqual(response.status_code, 404)
Exemple #24
0
def new_module(request, domain, app_id):
    "Adds a module to an app"
    app = get_app(domain, app_id)
    from corehq.apps.app_manager.views.utils import get_default_followup_form_xml
    lang = request.COOKIES.get('lang', app.langs[0])
    name = request.POST.get('name')
    module_type = request.POST.get('module_type', 'case')

    if module_type == 'case' or module_type == 'survey':  # survey option added for V2
        if module_type == 'case':
            name = name or 'Case List'
        else:
            name = name or 'Surveys'

        module = app.add_module(Module.new_module(name, lang))
        module_id = module.id

        form_id = None
        unstructured = add_ons.show("empty_case_lists", request, app)
        if module_type == 'case':
            if not unstructured:
                form_id = 0

                # registration form
                register = app.new_form(module_id, _("Registration Form"), lang)
                register.actions.open_case = OpenCaseAction(condition=FormActionCondition(type='always'))
                register.actions.update_case = UpdateCaseAction(
                    condition=FormActionCondition(type='always'))

                # one followup form
                msg = _("This is your follow up form. "
                        "Delete this label and add questions for any follow up visits.")
                attachment = get_default_followup_form_xml(context={'lang': lang, 'default_label': msg})
                followup = app.new_form(module_id, _("Followup Form"), lang, attachment=attachment)
                followup.requires = "case"
                followup.actions.update_case = UpdateCaseAction(condition=FormActionCondition(type='always'))

            _init_module_case_type(module)
        else:
            form_id = 0
            app.new_form(module_id, _("Survey"), lang)

        app.save()
        response = back_to_main(request, domain, app_id=app_id,
                                module_id=module_id, form_id=form_id)
        response.set_cookie('suppress_build_errors', 'yes')
        return response
    elif module_type in MODULE_TYPE_MAP:
        fn = MODULE_TYPE_MAP[module_type][FN]
        validations = MODULE_TYPE_MAP[module_type][VALIDATIONS]
        error = next((v[1] for v in validations if v[0](app)), None)
        if error:
            messages.warning(request, error)
            return back_to_main(request, domain, app_id=app.id)
        else:
            return fn(request, domain, app, name, lang)
    else:
        logger.error('Unexpected module type for new module: "%s"' % module_type)
        return back_to_main(request, domain, app_id=app_id)
 def setUp(self):
     self.domain = 'domain'
     self.app = Application.new_app(self.domain, 'New App')
     self.app.version = 3
     self.module = self.app.add_module(Module.new_module('New Module', lang='en'))
     self.form = self.app.new_form(0, 'New Form', lang='en')
     self.module.case_type = 'test_case_type'
     self.form.source = self.get_xml('original_form', override_path=('data',)).decode('utf-8')
 def setUp(self):
     self.domain = Domain(name='test')
     self.domain.save()
     app = Application.new_app('test', "Test Application", lang='en')
     module = Module.new_module("Untitled Module", 'en')
     app.add_module(module)
     app.new_form(0, "Untitled Form", 'en')
     app.save()
 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 setUp(self):
        self.app = Application.new_app('domain', "Untitled Application", application_version=APP_V2)
        self.app.build_langs = self.app.langs = ['en', 'afr', 'fra']
        module1 = self.app.add_module(Module.new_module('module', None))
        form1 = self.app.new_form(module1.id, "Untitled Form", None)
        form1.source = self.get_xml('initial_xform')

        self.form1_worksheet = self.get_worksheet('module1_form1')
Exemple #29
0
 def _make_module(self, app, module_id, case_type):
     m = app.add_module(Module.new_module('Module{}'.format(module_id), lang='en'))
     m.case_type = case_type
     mf = app.new_form(module_id, 'form {}'.format(case_type), lang='en',
                       attachment=self.get_xml('standard_questions').decode('utf-8'))
     mf.actions.open_case = OpenCaseAction(name_path="/data/question1", external_id=None)
     mf.actions.open_case.condition.type = 'always'
     return m
Exemple #30
0
    def setUp(self):
        self.is_usercase_in_use_patch = patch('corehq.apps.app_manager.models.is_usercase_in_use')
        self.is_usercase_in_use_mock = self.is_usercase_in_use_patch.start()

        self.app = Application.new_app('domain', 'New App')
        self.app.version = 3
        self.fish_module = self.app.add_module(Module.new_module('Fish Module', lang='en'))
        self.fish_module.case_type = 'fish'
        self.fish_form = self.app.new_form(0, 'New Form', lang='en')
        self.fish_form.source = self.get_xml('original')

        self.freshwater_module = self.app.add_module(Module.new_module('Freshwater Module', lang='en'))
        self.freshwater_module.case_type = 'freshwater'
        self.freshwater_form = self.app.new_form(0, 'New Form', lang='en')
        self.freshwater_form.source = self.get_xml('original')

        self.aquarium_module = self.app.add_module(Module.new_module('Aquarium Module', lang='en'))
        self.aquarium_module.case_type = 'aquarium'
Exemple #31
0
 def setUp(self):
     self.app = Application.new_app('domain', "Application")
     self.module = self.app.add_module(Module.new_module('module', None))
     self.form = self.app.new_form(self.module.id, "Form", None)
     self.assertNotEqual(self.form.xmlns, DEFAULT_XMLNS)
 def construct_form(cls):
     app = Application.new_app('domain', 'New App')
     app.add_module(Module.new_module('New Module', lang='en'))
     form = app.new_form(0, 'MySuperSpecialForm', lang='en')
     return form
Exemple #33
0
    def setUp(self):
        super().setUp()
        self.app = Application.new_app(DOMAIN, "Application with Shadow")
        self.app._id = '456'
        self.app.build_spec = BuildSpec(version='2.53.0', build_number=1)
        self.module = self.app.add_module(Module.new_module("Followup", None))
        self.form = self.app.new_form(0, "Untitled Form", None, attachment=get_simple_form("xmlns1.0"))
        self.form.requires = 'case'
        self.module.case_type = 'case'

        self.module.case_details.long.columns.append(
            DetailColumn.wrap(dict(
                header={"en": "name"},
                model="case",
                format="plain",
                field="whatever",
            ))
        )

        self.module.search_config = CaseSearch(
            properties=[
                CaseSearchProperty(name='name', label={'en': 'Name'}),
                CaseSearchProperty(name='favorite_color', label={'en': 'Favorite Color'}, itemset=Itemset(
                    instance_id='item-list:colors', instance_uri='jr://fixture/item-list:colors',
                    nodeset="instance('item-list:colors')/colors_list/colors",
                    label='name', sort='name', value='value'),
                )
            ],
            data_registry="myregistry",
            data_registry_workflow=REGISTRY_WORKFLOW_LOAD_CASE,
            additional_registry_cases=["'another case ID'"],
        )

        self.shadow_module = self.app.add_module(ShadowModule.new_module("Shadow", "en"))
        self.shadow_module.source_module_id = self.module.unique_id

        self.shadow_module.case_details.long.columns.append(
            DetailColumn.wrap(dict(
                header={"en": "name"},
                model="case",
                format="plain",
                field="whatever",
            ))
        )

        self.shadow_module.search_config = CaseSearch(
            properties=[
                CaseSearchProperty(name='name', label={'en': 'Name'}),
                CaseSearchProperty(name='favorite_color', label={'en': 'Texture'}, itemset=Itemset(
                    instance_id='item-list:textures', instance_uri='jr://fixture/item-list:textures',
                    nodeset="instance('item-list:textures')/textures_list/textures",
                    label='name', sort='name', value='value'),
                )
            ],
            data_registry="myregistry",
            data_registry_workflow=REGISTRY_WORKFLOW_LOAD_CASE,
        )

        # wrap to have assign_references called
        self.app = Application.wrap(self.app.to_json())

        # reset to newly wrapped module
        self.module = self.app.modules[0]
        self.shadow_module = self.app.modules[1]
Exemple #34
0
    def test_basic_app(self, mock1, mock2):
        module = self.app.add_module(Module.new_module("Module0", "en"))
        form = self.app.new_form(module.id,
                                 "Form0",
                                 "en",
                                 attachment=get_simple_form(xmlns='xmlns-0.0'))
        self.app.save()
        self._send_to_es(self.app)

        kwargs = {
            'domain': self.project.name,
            'app_id': self.app.id,
        }
        self._test_status_codes([
            'view_app',
            'release_manager',
            AppCaseSummaryView.urlname,
            AppFormSummaryView.urlname,
        ], kwargs)

        build = self.app.make_build()
        build.save()
        self._send_to_es(build)

        content = self._json_content_from_get('current_app_version', {
            'domain': self.project.name,
            'app_id': self.app.id,
        })
        self.assertEqual(content['currentVersion'], 1)
        self.app.save()
        self._send_to_es(self.app)

        content = self._json_content_from_get('current_app_version', {
            'domain': self.project.name,
            'app_id': self.app.id,
        })
        self.assertEqual(content['currentVersion'], 2)

        content = self._json_content_from_get('paginate_releases', {
            'domain': self.project.name,
            'app_id': self.app.id,
        }, {'limit': 5})
        self.assertEqual(len(content['apps']), 1)
        content = content['apps'][0]
        self.assertEqual(content['copy_of'], self.app.id)

        kwargs['module_unique_id'] = module.unique_id
        self._test_status_codes(['view_module'], kwargs)

        del kwargs['module_unique_id']
        kwargs['form_unique_id'] = form.unique_id
        self._test_status_codes(['view_form', 'form_source'], kwargs)

        mock2.side_effect = XFormValidationError('')
        bad_form = self.app.new_form(
            module.id,
            "Form1",
            "en",
            attachment=INVALID_TEMPLATE.format(xmlns='xmlns-0.0'))
        kwargs['form_unique_id'] = bad_form.unique_id
        self.app.save()
        self._test_status_codes(['view_form', 'form_source'], kwargs)

        bad_form = self.app.new_form(module.id,
                                     "Form1",
                                     "en",
                                     attachment="this is not xml")
        kwargs['form_unique_id'] = bad_form.unique_id
        self.app.save()
        self._test_status_codes(['view_form', 'form_source'], kwargs)
Exemple #35
0
    def test_case_detail_icon_mapping(self):
        app = Application.new_app('domain', 'Untitled Application')

        module = app.add_module(Module.new_module('Untitled Module', None))
        module.case_type = 'patient'

        module.case_details.short.columns = [
            DetailColumn(
                header={'en': 'Age range'},
                model='case',
                field='age',
                format='enum-image',
                enum=[
                    MappingItem(key='10',
                                value={'en': 'jr://icons/10-year-old.png'}),
                    MappingItem(key='age > 50',
                                value={'en': 'jr://icons/old-icon.png'}),
                    MappingItem(key='15%',
                                value={'en': 'jr://icons/percent-icon.png'}),
                ],
            ),
        ]

        key1_varname = '10'
        key2_varname = hashlib.md5('age > 50').hexdigest()[:8]
        key3_varname = hashlib.md5('15%').hexdigest()[:8]

        icon_mapping_spec = """
            <partial>
              <template form="image" width="13%">
                <text>
                  <xpath function="if(age = '10', $k{key1_varname}, if(age > 50, $h{key2_varname}, if(age = '15%', $h{key3_varname}, '')))">
                    <variable name="h{key2_varname}">
                      <locale id="m0.case_short.case_age_1.enum.h{key2_varname}"/>
                    </variable>
                    <variable name="h{key3_varname}">
                      <locale id="m0.case_short.case_age_1.enum.h{key3_varname}"/>
                    </variable>
                    <variable name="k{key1_varname}">
                      <locale id="m0.case_short.case_age_1.enum.k{key1_varname}"/>
                    </variable>
                  </xpath>
                </text>
              </template>
            </partial>
        """.format(
            key1_varname=key1_varname,
            key2_varname=key2_varname,
            key3_varname=key3_varname,
        )
        # check correct suite is generated
        self.assertXmlPartialEqual(icon_mapping_spec, app.create_suite(),
                                   './detail/field/template[@form="image"]')
        # check icons map correctly
        app_strings = commcare_translations.loads(app.create_app_strings('en'))
        self.assertEqual(
            app_strings['m0.case_short.case_age_1.enum.h{key3_varname}'.format(
                key3_varname=key3_varname, )], 'jr://icons/percent-icon.png')
        self.assertEqual(
            app_strings['m0.case_short.case_age_1.enum.h{key2_varname}'.format(
                key2_varname=key2_varname, )], 'jr://icons/old-icon.png')
        self.assertEqual(
            app_strings['m0.case_short.case_age_1.enum.k{key1_varname}'.format(
                key1_varname=key1_varname, )], 'jr://icons/10-year-old.png')
Exemple #36
0
 def test_overwrite_all(self):
     dest_module = self.app.add_module(
         Module.new_module('Dest Module', lang='en'))
     dest_detail = getattr(dest_module.case_details, "short")
     dest_detail.overwrite_attrs(self.src_detail, self.all_attrs)
     self.assertEqual(self.src_detail.to_json(), dest_detail.to_json())
Exemple #37
0
    def test_suite_media_with_app_profile(self, *args):
        # Test that suite includes only media relevant to the profile

        app = Application.new_app('domain', "my app")
        app.add_module(Module.new_module("Module 1", None))
        app.new_form(0, "Form 1", None)
        app.build_spec = BuildSpec.from_string('2.21.0/latest')
        app.build_profiles = OrderedDict({
            'en':
            BuildProfile(langs=['en'], name='en-profile'),
            'hin':
            BuildProfile(langs=['hin'], name='hin-profile'),
            'all':
            BuildProfile(langs=['en', 'hin'], name='all-profile'),
        })
        app.langs = ['en', 'hin']

        image_path = 'jr://file/commcare/module0_en.png'
        audio_path = 'jr://file/commcare/module0_en.mp3'
        app.get_module(0).set_icon('en', image_path)
        app.get_module(0).set_audio('en', audio_path)

        # Generate suites and default app strings for each profile
        suites = {}
        locale_ids = {}
        for build_profile_id in app.build_profiles.keys():
            suites[build_profile_id] = app.create_suite(
                build_profile_id=build_profile_id)
            default_app_strings = app.create_app_strings(
                'default', build_profile_id)
            locale_ids[build_profile_id] = {
                line.split('=')[0]
                for line in default_app_strings.splitlines()
            }

        # Suite should have only the relevant images
        media_xml = self.makeXML("modules.m0", "modules.m0.icon",
                                 "modules.m0.audio")
        self.assertXmlPartialEqual(media_xml, suites['all'],
                                   "././menu[@id='m0']/display")

        no_media_xml = self.XML_without_media("modules.m0")
        self.assertXmlPartialEqual(media_xml, suites['en'],
                                   "././menu[@id='m0']/display")

        no_media_xml = self.XML_without_media("modules.m0")
        self.assertXmlPartialEqual(no_media_xml, suites['hin'],
                                   "././menu[@id='m0']/text")

        # Default app strings should have only the relevant locales
        self.assertIn('modules.m0', locale_ids['all'])
        self.assertIn('modules.m0.icon', locale_ids['all'])
        self.assertIn('modules.m0.audio', locale_ids['all'])

        self.assertIn('modules.m0', locale_ids['en'])
        self.assertIn('modules.m0.icon', locale_ids['en'])
        self.assertIn('modules.m0.audio', locale_ids['en'])

        self.assertIn('modules.m0', locale_ids['hin'])
        self.assertNotIn('modules.m0.icon', locale_ids['hin'])
        self.assertNotIn('modules.m0.audio', locale_ids['hin'])
Exemple #38
0
 def setUp(self):
     self.app = Application.new_app('domain', "my app")
     self.module = self.app.add_module(Module.new_module("Module 1", None))
     self.form = self.app.new_form(0, "Form 1", None)
     self.min_spec = BuildSpec.from_string('2.21.0/latest')
     self.app.build_spec = self.min_spec
Exemple #39
0
 def setUp(self):
     self.app = Application.new_app('domain', "Untitled Application")
     self.module = self.app.add_module(
         Module.new_module('Untitled Module', None))
     self.module.case_type = 'another_case_type'
     self.form = self.module.new_form("Untitled Form", None)
    def test(self):
        add_build(version='2.7.0', build_number=20655)
        domain = 'form-versioning-test'

        # set up inital app
        app = Application.new_app(domain, 'Foo', '2.0')
        app.modules.append(Module(forms=[Form(), Form()]))
        app.build_spec = BuildSpec.from_string('2.7.0/latest')
        app.get_module(0).get_form(0).source = BLANK_TEMPLATE.format(
            xmlns='xmlns-0.0')
        app.get_module(0).get_form(1).source = BLANK_TEMPLATE.format(
            xmlns='xmlns-1')
        app.save()

        # make a build
        build1 = app.make_build(previous_version=None)
        build1.save()

        # modify first form
        app.get_module(0).get_form(0).source = BLANK_TEMPLATE.format(
            xmlns='xmlns-0.1')
        app.save()

        # make second build
        build2 = app.make_build(previous_version=build1)
        build2.save()

        # modify first form
        app.get_module(0).get_form(0).source = BLANK_TEMPLATE.format(
            xmlns='xmlns-0.2')
        app.save()
        app.save()
        app.save()

        # make third build
        build3 = app.make_build(previous_version=build2)
        build3.save()

        self.assertEqual(self.get_form_versions(build1), [1, 1])
        self.assertEqual(self.get_form_versions(build2), [2, 1])
        self.assertEqual(self.get_form_versions(build3), [5, 1])

        # revert to build2
        app = app.make_reversion_to_copy(build2)
        app.save()

        # make reverted build
        build4 = app.make_build(previous_version=build3)
        build4.save()

        self.assertEqual(self.get_form_versions(build4), [6, 1])

        # copy app
        xxx_app = import_app(app.export_json(dump_json=False), domain)

        # make build of copy
        xxx_build1 = xxx_app.make_build(previous_version=None)
        xxx_build1.save()

        # modify first form of copy app
        xxx_app.get_module(0).get_form(0).source = BLANK_TEMPLATE.format(
            xmlns='xmlns-0.xxx.0')
        xxx_app.save()

        # make second build of copy
        xxx_build2 = xxx_app.make_build(previous_version=xxx_build1)
        xxx_build2.save()

        self.assertEqual(self.get_form_versions(xxx_build1), [1, 1])
        self.assertEqual(self.get_form_versions(xxx_build2), [2, 1])
    def test_multi_master_form_attributes_and_media_versions(self, *args):
        '''
        This tests a few things related to pulling a linked app from multiple master apps,
        particularly interleaving pulls (pulling master A, then master B, then master A again):
        - Form versions should not change unless the form content changed
        - Form unique ids should be different from the master they came from but consistent across
          versions of the linked app that come from that master.
        - If a new form is added to multiple masters, that form's unique id should be the same
          across all versions of the linked app that pull from any of those masters - that is,
          each XMLNS in the linked app should correspond to one and only one form unique id.
        - Multimedia versions should not change, but should be consistent with the version
          of the linked app where they were introduced.
        '''

        # Add single module and form to both master1 and master2.
        # The module in master1 will also be used for multimedia testing.
        master1_module = self.master1.add_module(
            Module.new_module('Module for master1', None))
        master1_module.new_form('Form for master1', 'en',
                                get_blank_form_xml('Form for master1'))
        master1_map = self._get_form_ids_by_xmlns(self.master1)
        image_path = 'jr://file/commcare/photo.jpg'
        self.master1.create_mapping(CommCareImage(_id='123'), image_path)
        self.master1.get_module(0).set_icon('en', image_path)
        self._make_master1_build(True)
        master2_module = self.master2.add_module(
            Module.new_module('Module for master2', None))
        master2_module.new_form('Form for master2', 'en',
                                get_blank_form_xml('Form for master2'))
        master2_map = self._get_form_ids_by_xmlns(self.master2)
        self._make_master2_build(True)

        # Pull master1, so linked app now has a form. Verify that form xmlnses match.
        self._pull_linked_app(self.master1.get_id)
        linked_master1_build1 = self._make_linked_build()
        linked_master1_build1_form = linked_master1_build1.get_module(
            0).get_form(0)
        linked_master1_map = self._get_form_ids_by_xmlns(self.linked_app)
        self.assertEqual(master1_map, linked_master1_map)
        original_image_version = linked_master1_build1.multimedia_map[
            image_path].version
        self.assertEqual(original_image_version, linked_master1_build1.version)

        # Pull master2, so linked app now has other form. Verify that form xmlnses match but unique ids do not.
        self._pull_linked_app(self.master2.get_id)
        linked_master2_build1 = self._make_linked_build()
        linked_master2_map = self._get_form_ids_by_xmlns(self.linked_app)
        linked_master2_build1_form = linked_master2_build1.get_module(
            0).get_form(0)
        self.assertEqual(master2_map, linked_master2_map)
        self.assertNotEqual(linked_master1_build1_form.unique_id,
                            linked_master2_build1_form.unique_id)

        # Re-pull master1, so linked app is back to the first form, with same xmlns, unique id, and version
        linked_master1_build1 = self._make_master1_build(True)
        self._pull_linked_app(self.master1.get_id)
        linked_master1_build2 = self._make_linked_build()
        linked_master1_build2_form = linked_master1_build2.get_module(
            0).get_form(0)
        self.assertEqual(linked_master1_map,
                         self._get_form_ids_by_xmlns(self.linked_app))
        self.assertEqual(linked_master1_build1_form.xmlns,
                         linked_master1_build2_form.xmlns)
        self.assertEqual(linked_master1_build1_form.unique_id,
                         linked_master1_build2_form.unique_id)
        self.assertEqual(linked_master1_build1_form.get_version(),
                         linked_master1_build2_form.get_version())

        # Update form in master1 and make new linked build, which should update form version
        # Also add audio. The new audio should get the new build version, but the old image should retain
        # the version of the old app.
        wrapped = self.master1.get_module(0).get_form(0).wrapped_xform()
        wrapped.set_name("Updated form for master1")
        self.master1.get_module(0).get_form(0).source = etree.tostring(
            wrapped.xml, encoding='utf-8')
        audio_path = 'jr://file/commcare/scream.mp3'
        self.master1.create_mapping(CommCareAudio(_id='345'), audio_path)
        self.master1.get_module(0).set_audio('en', audio_path)
        self._make_master1_build(True)
        self._pull_linked_app(self.master1.get_id)
        linked_master1_build3 = self._make_linked_build()
        linked_master1_build3_form = linked_master1_build3.get_module(
            0).get_form(0)
        self.assertEqual(linked_master1_build2_form.xmlns,
                         linked_master1_build3_form.xmlns)
        self.assertEqual(linked_master1_build2_form.unique_id,
                         linked_master1_build3_form.unique_id)
        self.assertLess(linked_master1_build2_form.get_version(),
                        linked_master1_build3_form.get_version())
        self.assertEqual(self.linked_app.multimedia_map[image_path].version,
                         original_image_version)
        self.assertGreater(self.linked_app.multimedia_map[audio_path].version,
                           original_image_version)

        # Add another form to both master1 and master2. When master1 is pulled, that form should be assigned a
        # new unique id, and when master2 is pulled, it should retain that id since it has the same xmlns.
        self.master1.get_module(0).new_form(
            'Twin form', None,
            self.get_xml('very_simple_form').decode('utf-8'))
        self._make_master1_build(True)
        self._pull_linked_app(self.master1.get_id)
        xmlns = self.master1.get_module(0).get_form(1).xmlns
        self.master2.get_module(0).new_form(
            'Twin form', None,
            self.get_xml('very_simple_form').decode('utf-8'))
        linked_master1_build4 = self._make_linked_build()
        self._make_master2_build(True)
        self._pull_linked_app(self.master2.get_id)
        linked_master2_build2 = self._make_linked_build()
        self.assertEqual(xmlns, self.master2.get_module(0).get_form(1).xmlns)
        self.assertEqual(
            self._get_form_ids_by_xmlns(linked_master1_build4)[xmlns],
            self._get_form_ids_by_xmlns(self.master1)[xmlns])
        self.assertEqual(
            self._get_form_ids_by_xmlns(linked_master2_build2)[xmlns],
            self._get_form_ids_by_xmlns(self.master2)[xmlns])
def new_module(request, domain, app_id):
    "Adds a module to an app"
    app = get_app(domain, app_id)
    lang = request.COOKIES.get('lang', app.langs[0])
    name = request.POST.get('name')
    module_type = request.POST.get('module_type', 'case')

    if module_type == 'case' or module_type == 'survey':  # survey option added for V2
        if module_type == 'case':
            name = name or 'Case List'
        else:
            name = name or 'Surveys'

        module = app.add_module(Module.new_module(name, lang))
        module_id = module.id

        form_id = None
        unstructured = add_ons.show("empty_case_lists", request, app)
        if module_type == 'case':
            if not unstructured:
                form_id = 0

                # registration form
                register = app.new_form(module_id, _("Registration Form"),
                                        lang)
                register.actions.open_case = OpenCaseAction(
                    condition=FormActionCondition(type='always'))
                register.actions.update_case = UpdateCaseAction(
                    condition=FormActionCondition(type='always'))

                # one followup form
                followup = app.new_form(module_id, _("Followup Form"), lang)
                followup.requires = "case"
                followup.actions.update_case = UpdateCaseAction(
                    condition=FormActionCondition(type='always'))

            _init_module_case_type(module)
        else:
            form_id = 0
            app.new_form(module_id, _("Survey"), lang)

        app.save()
        response = back_to_main(request,
                                domain,
                                app_id=app_id,
                                module_id=module_id,
                                form_id=form_id)
        response.set_cookie('suppress_build_errors', 'yes')
        return response
    elif module_type in MODULE_TYPE_MAP:
        fn = MODULE_TYPE_MAP[module_type][FN]
        validations = MODULE_TYPE_MAP[module_type][VALIDATIONS]
        error = next((v[1] for v in validations if v[0](app)), None)
        if error:
            messages.warning(request, error)
            return back_to_main(request, domain, app_id=app.id)
        else:
            return fn(request, domain, app, name, lang)
    else:
        logger.error('Unexpected module type for new module: "%s"' %
                     module_type)
        return back_to_main(request, domain, app_id=app_id)
Exemple #43
0
    def setUpClass(cls):
        super(ReportFiltersSuiteTest, cls).setUpClass()
        delete_all_users()
        cls.report_id = '7b97e8b53d00d43ca126b10093215a9d'
        cls.report_config_mobile_id = 'a98c812873986df34fd1b4ceb45e6164ae9cc664'
        cls.domain = 'report-filter-test-domain'
        create_domain(cls.domain)
        cls.user = create_restore_user(
            domain=cls.domain,
            username='******',
        )
        MOBILE_UCR.set(cls.domain, True, NAMESPACE_DOMAIN)

        report_configuration = cls.make_report_config(cls.domain,
                                                      cls.report_id)

        # also make a report with a hidden column
        cls.hidden_column_report_id = 'bd2a43018ad9463682165c1bc16347ac'
        cls.hidden_column_mobile_id = '45152061d8dc4d2a8d987a0568abe1ae'
        report_configuration_with_hidden_column = MAKE_REPORT_CONFIG(
            cls.domain,
            cls.hidden_column_report_id,
            columns=[
                FieldColumn(type='field',
                            aggregation="simple",
                            column_id="color_94ec39e6",
                            display="color",
                            field="color_94ec39e6").to_json(),
                FieldColumn(
                    type='field',
                    aggregation="simple",
                    column_id="hidden_color_94ec39e6",
                    display="color",
                    field="color_94ec39e6",
                    visible=False,
                ).to_json(),
            ])
        cls.report_configs_by_id = {
            cls.report_id: report_configuration,
            cls.hidden_column_report_id:
            report_configuration_with_hidden_column
        }
        cls.app = Application.new_app(cls.domain, "Report Filter Test App")
        report_module = cls.app.add_module(
            ReportModule.new_module("Report Module", 'en'))
        report_module.report_context_tile = True
        report_module.report_configs.append(
            ReportAppConfig(
                report_id=cls.report_id,
                header={},
                description="",
                complete_graph_configs={
                    '7451243209119342931':
                    GraphConfiguration(
                        graph_type="bar",
                        series=[
                            GraphSeries(
                                config={},
                                locale_specific_config={},
                                data_path="",
                                x_function="",
                                y_function="",
                            )
                        ],
                    )
                },
                filters=OrderedDict([
                    ('fav_fruit_abc123_1', MobileSelectFilter()),
                    ('computed_owner_name_40cc88a0_1', MobileSelectFilter()),
                ]),
                uuid=cls.report_config_mobile_id,
            ))
        report_module.report_configs.append(
            ReportAppConfig(
                report_id=cls.hidden_column_report_id,
                header={},
                description="",
                complete_graph_configs={},
                filters={},
                uuid=cls.hidden_column_mobile_id,
            ))

        case_module = cls.app.add_module(Module.new_module(
            "Case Module", 'en'))
        case_module.case_type = "fish"
        case_module.report_context_tile = True
        case_form = case_module.new_form("Update Fish", None)
        case_form.requires = "case"
        case_form.xmlns = "http://openrosa.org/formdesigner/2423EFB5-2E8C-4B8F-9DA0-23FFFD4391AF"

        survey_module = cls.app.add_module(
            Module.new_module("Survey Module", 'en'))
        survey_module.report_context_tile = True
        survey_form = survey_module.new_form("Survey", None)
        survey_form.xmlns = "http://openrosa.org/formdesigner/2423EFB5-2E8C-4B8F-9DA0-23FFFD4391AE"

        with mock_report_configurations(cls.report_configs_by_id):
            cls.suite = cls.app.create_suite()
        cls.data = [
            {
                'color_94ec39e6': 'red',
                'count': 2,
                'computed_owner_name_40cc88a0': 'cory',
                'fav_fruit_abc123': 'c'
            },
            {
                'color_94ec39e6': 'black',
                'count': 1,
                'computed_owner_name_40cc88a0': 'ctsims',
                'fav_fruit_abc123': 'b'
            },
            {
                'color_94ec39e6': 'red',
                'count': 3,
                'computed_owner_name_40cc88a0': 'daniel',
                'fav_fruit_abc123': 'b'
            },
        ]
        with mock_report_data(cls.data):
            with mock_report_configuration_get(cls.report_configs_by_id):
                with mock.patch(
                        'corehq.apps.app_manager.fixtures.mobile_ucr.get_apps_in_domain',
                        lambda domain, include_remote: [cls.app]):
                    with mock_datasource_config():
                        fixtures = call_fixture_generator(
                            report_fixture_generator, cls.user)
                        fixture = [
                            f for f in fixtures if f.attrib.get('id') ==
                            ReportFixturesProviderV1.id
                        ][0]
        cls.fixture = ElementTree.tostring(fixture)