def test_subcase_multiple_repeats(self): self.form.actions.load_update_cases.append(LoadUpdateAction( case_type=self.parent_module.case_type, case_tag='load_1', )) self.form.actions.open_cases.append(AdvancedOpenCaseAction( case_type='child1', case_tag='open_1', name_path='/data/mother_name', case_indices=[CaseIndex(tag='load_1')], repeat_context="/data/child", )) self.form.actions.open_cases[0].open_condition.type = 'if' self.form.actions.open_cases[0].open_condition.question = '/data/child/which_child' self.form.actions.open_cases[0].open_condition.answer = '1' self.form.actions.open_cases.append(AdvancedOpenCaseAction( case_type='child2', case_tag='open_2', name_path='/data/mother_name', case_indices=[CaseIndex(tag='load_1')], repeat_context="/data/child", )) self.form.actions.open_cases[1].open_condition.type = 'if' self.form.actions.open_cases[1].open_condition.question = '/data/child/which_child' self.form.actions.open_cases[1].open_condition.answer = '2' self.assertXmlEqual(self.get_xml('subcase-repeat-multiple'), self.form.render_xform())
def get_test_app(self): app = Application.new_app('domain', 'New App') app._id = uuid.uuid4().hex app.version = 1 m0 = self._make_module(app, 0, 'parent') m0.get_form(0).actions.subcases.extend([ OpenSubCaseAction(case_type='child', reference_id='parent'), OpenSubCaseAction(case_type='other_child', reference_id='parent') ]) m1 = self._make_module(app, 1, 'child') m1.get_form(0).actions.subcases.append( OpenSubCaseAction(case_type='grand child', reference_id='parent')) m2 = self._make_module(app, 2, 'grand child') m3 = app.add_module(AdvancedModule.new_module('Module3', lang='en')) m3.case_type = 'other grand child' m3f0 = m3.new_form('other form', 'en') m3f0.actions.load_update_cases.append( LoadUpdateAction(case_type='child', case_tag='child')) m3f0.actions.open_cases.append( AdvancedOpenCaseAction( name_path='/data/question1', case_type='other grand child', case_indices=[CaseIndex(tag='child', reference_id='father')])) m3f0.actions.open_cases[0].open_condition.type = 'always' m4 = app.add_module(AdvancedModule.new_module('Module4', lang='en')) m4.case_type = 'extension' self._make_module(app, 5, 'other_child') m4f0 = m4.new_form('other form', 'en') m4f0.actions.load_update_cases.extend([ LoadUpdateAction(case_type='child', case_tag='child'), LoadUpdateAction(case_type='other_child', case_tag='other_child'), ]) m4f0.actions.open_cases.extend([ AdvancedOpenCaseAction(name_path='/data/question1', case_type='extension', case_indices=[ CaseIndex(tag='child', relationship='extension', reference_id='host') ]), AdvancedOpenCaseAction( # 'extension' case has 2 parents name_path='/data/question1', case_type='extension', case_indices=[ CaseIndex(tag='other_child', relationship='extension', reference_id='host') ]) ]) m4f0.actions.open_cases[0].open_condition.type = 'always' m4f0.actions.open_cases[1].open_condition.type = 'always' m2.parent_select = ParentSelect(active=True, module_id=m1.unique_id) m1.parent_select = ParentSelect(active=True, module_id=m0.unique_id) return app
def test_relationship_added_to_form(self): self.form.actions.load_update_cases.append(LoadUpdateAction( case_type=self.parent_module.case_type, case_tag='load_1', )) self.form.actions.open_cases.append(AdvancedOpenCaseAction( case_type='child1', case_tag='open_1', name_path='/data/mother_name', case_indices=[CaseIndex(tag='load_1'), CaseIndex(tag='load_1', reference_id='host', relationship='extension')], repeat_context="/data/child", )) self.assertXmlEqual(self.get_xml('extension-case'), self.form.render_xform())
def test_registration_form_subcase_multiple(self): self.form.actions.load_update_cases.append( LoadUpdateAction(case_type="parent", case_tag="parent")) self.form.actions.open_cases = [ AdvancedOpenCaseAction(case_tag="child", case_type="child", name_path="/data/question1", case_indices=[CaseIndex(tag="parent")]), AdvancedOpenCaseAction(case_tag="grandchild", case_type="grandchild", name_path="/data/children/question1", case_indices=[CaseIndex(tag="child")]) ] self.assertFalse(self.form.is_registration_form())
def form_requires_case(form, case_type=None, parent_case_type=None, update=None, preload=None): if form.form_type == 'module_form': form.requires = 'case' if update: form.actions.update_case = UpdateCaseAction(update=update) form.actions.update_case.condition.type = 'always' if preload: form.actions.case_preload = PreloadAction(preload=preload) form.actions.case_preload.condition.type = 'always' if parent_case_type: module = form.get_module() module.parent_select.active = True parent_select_module = next( module for module in module.get_app().get_modules() if module.case_type == parent_case_type ) module.parent_select.module_id = parent_select_module.unique_id else: case_type = case_type or form.get_module().case_type index = len([load for load in form.actions.load_update_cases if load.case_type == case_type]) kwargs = {'case_type': case_type, 'case_tag': 'load_{}_{}'.format(case_type, index)} if update: kwargs['case_properties'] = update if preload: kwargs['preload'] = preload action = LoadUpdateAction(**kwargs) if parent_case_type: parent_action = form.actions.load_update_cases[-1] assert parent_action.case_type == parent_case_type action.case_index = CaseIndex(tag=parent_action.case_tag) form.actions.load_update_cases.append(action)
def setUpClass(cls): super(TestBuildingSchemaFromApplication, cls).setUpClass() cls.current_app = Application.wrap(cls.get_json('basic_application')) cls.first_build = Application.wrap(cls.get_json('basic_application')) cls.first_build._id = '123' cls.first_build.copy_of = cls.current_app.get_id cls.first_build.version = 3 cls.first_build.has_submissions = True factory = AppFactory(build_version='2.36.0') m0, f0 = factory.new_advanced_module('mod0', 'advanced') f0.source = cls.get_xml('repeat_group_form').decode('utf-8') f0.xmlns = 'repeat-xmlns' factory.form_requires_case(f0, 'case0') f0.actions.open_cases = [ AdvancedOpenCaseAction( case_type="advanced", case_tag="open_case_0", name_path="/data/question3/question4", repeat_context="/data/question3", case_indices=[CaseIndex(tag='load_case0_0')]) ] cls.advanced_app = factory.app cls.advanced_app.save() cls.apps = [ cls.current_app, cls.first_build, cls.advanced_app, ] with drop_connected_signals(app_post_save): for app in cls.apps: app.save()
def get_test_app(self): app = Application.new_app('domain', 'New App') app.version = 1 m0 = self._make_module(app, 0, 'parent') m0.get_form(0).actions.subcases.append( OpenSubCaseAction(case_type='child', reference_id='parent')) m1 = self._make_module(app, 1, 'child') m1.get_form(0).actions.subcases.append( OpenSubCaseAction(case_type='grand child', reference_id='parent')) m2 = self._make_module(app, 2, 'grand child') m3 = app.add_module(AdvancedModule.new_module('Module3', lang='en')) m3.case_type = 'other grand child' m3f0 = m3.new_form('other form', 'en') m3f0.actions.load_update_cases.append( LoadUpdateAction(case_type='child', case_tag='child')) m3f0.actions.open_cases.append( AdvancedOpenCaseAction(name_path='/data/question1', case_type='other grand child', case_indices=[CaseIndex(tag='child')])) m3f0.actions.open_cases[0].open_condition.type = 'always' m2.parent_select = ParentSelect(active=True, module_id=m1.unique_id) m1.parent_select = ParentSelect(active=True, module_id=m0.unique_id) expected_hierarchy = { 'parent': { 'child': { 'grand child': {}, 'other grand child': {} } } } return app, expected_hierarchy
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.is_usercase_in_use_mock.return_value = True self.app = Application.new_app('domain', 'New App') self.module = self.app.add_module(AdvancedModule.new_module('Fish Module', None)) self.module.case_type = 'fish' self.form = self.module.new_form('Form', 'en', self.get_xml('original').decode('utf-8')) self.other_module = self.app.add_module(AdvancedModule.new_module('Freshwater Module', lang='en')) self.other_module.case_type = 'freshwater' self.other_form = self.module.new_form('Other Form', 'en', self.get_xml('original').decode('utf-8')) self.case_index = CaseIndex( reference_id='host', relationship='extension', ) self.subcase = AdvancedOpenCaseAction( case_tag='open_freshwater_0', case_type='freshwater', case_name='Wanda', name_update=ConditionalCaseUpdate(question_path='/data/question1'), open_condition=FormActionCondition(type='always'), case_properties={'name': ConditionalCaseUpdate(question_path='/data/question1')}, case_indices=[self.case_index], ) self.form.actions.open_cases.append(self.subcase) self.xform = XForm(self.get_xml('original')) path = 'subcase_0/' self.subcase_block = XFormCaseBlock(self.xform, path)
def form_opens_case(form, case_type=None, is_subcase=False, parent_tag=None, is_extension=False): if form.form_type == 'module_form': if is_subcase: form.actions.subcases.append(OpenSubCaseAction( case_type=case_type, case_name="/data/name", condition=FormActionCondition(type='always') )) else: form.actions.open_case = OpenCaseAction(name_path="/data/name", external_id=None) form.actions.open_case.condition.type = 'always' else: case_type = case_type or form.get_module().case_type action = AdvancedOpenCaseAction( case_type=case_type, case_tag='open_{}'.format(case_type), name_path='/data/name' ) if is_subcase: if not parent_tag: parent_tag = form.actions.load_update_cases[-1].case_tag action.case_indices = [CaseIndex(tag=parent_tag, relationship='extension' if is_extension else 'child')] form.actions.open_cases.append(action)
def test_xform_case_block_index_supports_dynamic_relationship(self): self.subcase.case_indices = [CaseIndex( tag='open_freshwater_0', reference_id='node', relationship='question', relationship_question='/data/question2', )] self.assertXmlEqual(self.get_xml('case_index_relationship_question'), self.form.render_xform())
def test_registration_form_subcase(self): self.form.actions.load_update_cases.append( LoadUpdateAction(case_type="parent", case_tag="parent")) self.form.actions.open_cases = [ AdvancedOpenCaseAction(case_tag="child", case_type="child", name_update=ConditionalCaseUpdate( question_path="/data/question1"), case_indices=[CaseIndex(tag="parent")]) ] self.assertTrue(self.form.is_registration_form())
def test_subcase(self): self.form.actions.load_update_cases.append(LoadUpdateAction( case_type=self.parent_module.case_type, case_tag='load_1', )) self.form.actions.open_cases.append(AdvancedOpenCaseAction( case_type=self.module.case_type, case_tag='open_1', name_path='/data/mother_name', case_indices=[CaseIndex(tag='load_1')] )) self.form.actions.open_cases[0].open_condition.type = 'always' self.assertXmlEqual(self.get_xml('subcase'), self.form.render_xform())
def test_case_index_valid_relationship(self): """ CaseIndex relationship should only allow valid values """ CaseIndex(tag='mother', relationship='child') CaseIndex(tag='mother', relationship='extension') CaseIndex(tag='mother', relationship='question') with self.assertRaises(BadValueError): CaseIndex(tag='mother', relationship='parent') with self.assertRaises(BadValueError): CaseIndex(tag='mother', relationship='host') with self.assertRaises(BadValueError): CaseIndex(tag='mother', relationship='primary') with self.assertRaises(BadValueError): CaseIndex(tag='mother', relationship='replica') with self.assertRaises(BadValueError): CaseIndex(tag='mother', relationship='cousin')
def test_registration_form_autoload_subcase(self): self.form.actions.load_update_cases = [ LoadUpdateAction(case_type="parent", case_tag="parent"), LoadUpdateAction(auto_select=AutoSelectCase( mode=AUTO_SELECT_USERCASE, value_key=""), ) ] self.form.actions.open_cases = [ AdvancedOpenCaseAction(case_tag="child", case_type="child", name_path="/data/question1", case_indices=[CaseIndex(tag="parent")]) ] self.assertTrue(self.form.is_registration_form())
def test_xform_case_block_index_default_relationship(self): """ CaseBlock index relationship should default to "child" """ child = CaseIndex( reference_id='host', relationship='child', ) self.subcase.case_indices = [child] self.add_subcase_block() self.subcase_block.add_index_ref( 'host', self.form.get_case_type(), self.xform.resolve_path("case/@case_id"), ) self.assertXmlEqual(self.get_xml('open_subcase_child'), str(self.xform))
def test_subcase_repeat(self): self.form.actions.load_update_cases.append( LoadUpdateAction( case_type=self.parent_module.case_type, case_tag='load_1', )) self.form.actions.open_cases.append( AdvancedOpenCaseAction(case_type=self.module.case_type, case_tag='open_1', name_update=ConditionalCaseUpdate( question_path='/data/mother_name'), case_indices=[CaseIndex(tag='load_1')], repeat_context="/data/child")) self.form.actions.open_cases[0].open_condition.type = 'always' self.assertXmlEqual(self.get_xml('subcase-repeat'), self.form.render_xform())
def test_subcase_of_open(self): self.form.actions.open_cases.append(AdvancedOpenCaseAction( case_type=self.parent_module.case_type, case_tag='open_1', name_path='/data/mother_name', )) self.form.actions.open_cases.append(AdvancedOpenCaseAction( case_type=self.module.case_type, case_tag='open_2', name_path='/data/mother_name', case_indices=[CaseIndex(tag='open_1')], repeat_context="/data/child" )) for action in self.form.actions.open_cases: action.open_condition.type = 'always' self.assertXmlEqual(self.get_xml('subcase-open'), self.form.render_xform())
def test_case_properties_advanced(self): app = Application.new_app('domain', 'New App') app._id = uuid.uuid4().hex app.version = 1 m0 = app.add_module(AdvancedModule.new_module('Module0', lang='en')) m0.case_type = 'child' m0f0 = m0.new_form( 'other form', 'en', attachment=self.get_xml('standard_questions').decode('utf-8')) m0f0.actions.load_update_cases.append( LoadUpdateAction( case_type='parent', case_tag='parent', case_properties={ 'case_name': ConditionalCaseUpdate(question_path='/data/question1'), 'other': ConditionalCaseUpdate(question_path='/data/question2') })) m0f0.actions.open_cases.append( AdvancedOpenCaseAction( name_update=ConditionalCaseUpdate( question_path='/data/question1'), case_type='child', case_indices=[CaseIndex(tag='parent', reference_id='father')], case_properties={ 'child_other': ConditionalCaseUpdate(question_path='/data/question2') })) m0f0.actions.open_cases[0].open_condition.type = 'always' meta = app.get_case_metadata() self.assertEqual(2, len(meta.case_types)) child_type = meta.get_type('child') parent_type = meta.get_type('parent') self.assertFalse(child_type.has_errors) self.assertFalse(parent_type.has_errors) self.assertEqual({'name', 'child_other'}, {p.name for p in child_type.properties}) self.assertEqual({'case_name', 'other'}, {p.name for p in parent_type.properties})
def handle(self, domain, app_id, module_id, *args, **options): app = get_current_app(domain, app_id) module = app.get_module_by_unique_id(module_id) assert module.doc_type == 'Module', "Only support modules" assert module.display_style == 'list', "Doesn't support grid case lists" assert module.referral_list.show is False, "Doesn't support referral lists" assert module.ref_details.short.columns == [], "Doesn't support ref details" assert module.ref_details.long.columns == [], "Doesn't support ref details" assert module.task_list.show is False, "Doesn't support task lists" latest_build = get_latest_build_version(domain, app_id) if latest_build != app.version: app.validate_app() copy = app.make_build( comment="Build before moving {} to an advanced module".format( module.name), ) copy.save(increment_version=False) module.module_type = 'advanced' module.doc_type = 'AdvancedModule' forms = [] for form in module.forms: # https://github.com/dimagi/commcare-hq/blob/271ab9346745e7a8a4d647db66dc959fbb9f8159/corehq/apps/app_manager/models.py#L3182 assert isinstance(form, Form) new_form = AdvancedForm( name=form.name, form_filter=form.form_filter, media_image=form.media_image, media_audio=form.media_audio, comment=form.comment, ) new_form._parent = module form._parent = module new_form.source = form.source actions = form.active_actions() open = actions.get('open_case', None) update = actions.get('update_case', None) close = actions.get('close_case', None) preload = actions.get('case_preload', None) subcases = actions.get('subcases', None) case_type = module.case_type base_action = None if open: base_action = AdvancedOpenCaseAction( case_type=case_type, case_tag='open_{0}_0'.format(case_type), name_path=open.name_path, open_condition=open.condition, case_properties=update.update if update else {}, ) new_form.actions.open_cases.append(base_action) elif update or preload or close: base_action = LoadUpdateAction( case_type=case_type, case_tag='load_{0}_0'.format(case_type), case_properties=update.update if update else {}, preload=preload.preload if preload else {}, ) if module.parent_select.active: select_chain = get_select_chain(app, module, include_self=False) for n, link in enumerate( reversed(list(enumerate(select_chain)))): i, module = link new_form.actions.load_update_cases.append( LoadUpdateAction( case_type=module.case_type, case_tag='_'.join(['parent'] * (i + 1)), details_module=module.unique_id, case_index=CaseIndex( tag='_'.join(['parent'] * (i + 2)) if n > 0 else ''), )) base_action.case_indices = [CaseIndex(tag='parent')] if close: base_action.close_condition = close.condition new_form.actions.load_update_cases.append(base_action) if subcases: for i, subcase in enumerate(subcases): open_subcase_action = AdvancedOpenCaseAction( case_type=subcase.case_type, case_tag='open_{0}_{1}'.format(subcase.case_type, i + 1), name_path=subcase.case_name, open_condition=subcase.condition, case_properties=subcase.case_properties, repeat_context=subcase.repeat_context, case_indices=[ CaseIndex( tag=base_action.case_tag if base_action else '', reference_id=subcase.reference_id, ) ], ) new_form.actions.open_cases.append(open_subcase_action) new_form.unique_id = form.unique_id forms.append(new_form.to_json()) new_module = module.to_json() new_module['forms'] = forms del new_module['display_style'] del new_module['referral_list'] del new_module['ref_details'] del new_module['task_list'] del new_module[ 'parent_select'] # This is handled in forms for advanced modules new_module = AdvancedModule.wrap(new_module) modules = app.modules mod_index = [ i for i, mod in enumerate(modules) if mod.unique_id == module_id ][0] modules[mod_index] = new_module app.modules = modules app.save() # update xml app = get_current_app(domain, app_id) module = app.get_module_by_unique_id(module_id) for form in module.forms: real_form = app.get_form(form.unique_id) if form.xmlns in (DUE_LIST_XMLNS, IMMUNIZATION_XMLNS): new_form_source = form.source.replace( "instance('commcaresession')/session/data/case_id", "instance('commcaresession')/session/data/case_id_load_tasks_0" ) real_form.source = new_form_source elif form.xmlns == ELIGIBLE_COUPLE_XMLNS: new_form_source = form.source.replace( "instance('commcaresession')/session/data/case_id", "instance('commcaresession')/session/data/case_id_load_person_0" ) real_form.source = new_form_source app.save() copy = app.make_build(comment="{} moved to an advanced module".format( module.name), ) copy.save(increment_version=False)
def test_case_index_default_relationship(self): """ CaseIndex relationship should default to "child" """ case_index = CaseIndex(tag='mother') self.assertEqual(case_index.relationship, 'child')
def test_case_index_support_relationship(self): """ CaseIndex should allow relationship to be set """ case_index = CaseIndex(tag='mother', relationship='extension') self.assertEqual(case_index.relationship, 'extension')