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())
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))
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)) )
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())
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())
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 )
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')
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())
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)
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')
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
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'
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
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]
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)
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')
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())
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'])
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
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)
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)