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 test_non_case_props(self): """We have special syntax in case lists and case details which should be hidden or shown for the usercase """ app = self.get_test_app() app.modules[0].case_details.short.columns = [ DetailColumn( header={'en': 'Owner Name'}, model='case', field='#owner_name', format='plain', case_tile_field='header' ), DetailColumn( header={'en': 'Username'}, model='case', field='user/username', format='plain', case_tile_field='header' ), ] metadata = app.get_case_metadata() prop = metadata.get_type('parent').get_property('#owner_name') self.assertFalse(prop.short_details) self.assertFalse(prop.long_details) # user properties should be shown under the usercase type prop = metadata.get_type(USERCASE_TYPE).get_property('username') self.assertTrue(prop.short_details) self.assertFalse(prop.long_details)
def _add_columns_for_case_details(_module): _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'), ]
def test_case_detail_tabs_with_nodesets_for_sorting_search_only_field( self, *args): app_json = self.get_json("app_case_detail_tabs_with_nodesets") app = Application.wrap(app_json) # update app to add in 2 new columns both with the field 'gender' # 1. add a column to the 2nd tab that is marked as 'search only'. # This should get sorting applied to it tab_spans = app.modules[0].case_details.long.get_tab_spans() # 2. add a second column to the last tab which already has a 'gender' field # This should result in the 'gender' field being displayed as well # as being used for sorting sorted_gender_col = DetailColumn.from_json( app_json["modules"][0]["case_details"]["long"]["columns"][-1]) app.modules[0].case_details.long.columns.insert( tab_spans[1][1] - 1, sorted_gender_col) plain_gender_col = DetailColumn.from_json( app_json["modules"][0]["case_details"]["long"]["columns"][-1]) plain_gender_col.format = "plain" index = len(app.modules[0].case_details.long.columns) - 1 app.modules[0].case_details.long.columns.insert( index, plain_gender_col) self.assertXmlPartialEqual( self.get_xml( "suite-case-detail-tabs-with-nodesets-for-sorting-search-only" ), app.create_suite(), './detail[@id="m0_case_long"]')
def setUp(self): self.domain = 'test-domain' create_domain(self.domain) self.app = Application.new_app(self.domain, "TestApp", application_version=APP_V1) for i in range(3): module = self.app.add_module( Module.new_module("Module%d" % i, "en")) for j in range(3): self.app.new_form(module.id, name="Form%s-%s" % (i, j), attachment=self.xform_str, lang="en") module = self.app.get_module(i) detail = module.ref_details.short detail.columns.append( DetailColumn(header={"en": "test"}, model="case", field="test", format="plain")) detail.columns.append( DetailColumn(header={"en": "age"}, model="case", field="age", format="years-ago")) self.app.save() self.build1 = {'version': '1.2.dev', 'build_number': 7106} self.build2 = {'version': '2.7.0', 'build_number': 20655} add_build(**self.build1) add_build(**self.build2)
def setUp(self): self.domain = 'test-domain' create_domain(self.domain) self.app = Application.new_app("test_domain", "TestApp", application_version=APP_V1) for i in range(3): module = self.app.new_module("Module%d" % i, "en") for j in range(3): self.app.new_form(module.id, name="Form%s-%s" % (i, j), attachment=self.xform_str, lang="en") module = self.app.get_module(i) detail = module.get_detail("ref_short") detail.append_column( DetailColumn(name={"en": "test"}, model="case", field="test", format="plain", enum={})) detail.append_column( DetailColumn(name={"en": "age"}, model="case", field="age", format="years-ago", enum={})) self.app.save()
def setUp(self): super(AppManagerTest, self).setUp() self.app = Application.new_app(self.domain, "TestApp") for i in range(3): module = self.app.add_module( Module.new_module("Module%d" % i, "en")) for j in range(3): self.app.new_form(module.id, name="Form%s-%s" % (i, j), attachment=self.xform_str, lang="en") module = self.app.get_module(i) detail = module.ref_details.short detail.columns.append( DetailColumn(header={"en": "test хнЧ unicode"}, model="case", field="test", format="plain")) detail.columns.append( DetailColumn(header={"en": "age"}, model="case", field="age", format="years-ago")) self.app.save()
def test_multiple_parents_case_lists(self): """If the case has multiple parents, and you reference a parent property in the case list, we can't tell which parent will be shown """ app, _ = self.get_test_app() # module 1 has case type 'child' which has a single parent, 'parent' app.modules[1].case_details.short.columns = [ DetailColumn(header={'en': 'Parent prop reference'}, model='case', field='parent/from_child', format='plain', case_tile_field='header'), ] # module 4 has type "extension" which has 2 relationships with the # reference 'host': 'child' and 'other_child' app.modules[4].case_details.short.columns = [ DetailColumn(header={'en': 'Parent prop reference'}, model='case', field='host/parent_property_reference', format='plain', case_tile_field='header'), ] metadata = app.get_case_metadata() self.assertEqual((metadata.get_type('parent').get_property( 'from_child').short_details[0].module_id), app.modules[1].unique_id) for type_ in ('other_child', 'child'): self.assertEqual((metadata.get_type(type_).get_property( 'parent_property_reference').short_details[0].module_id), app.modules[4].unique_id)
def test_non_case_props(self): """We have special syntax in case lists and case details which shouldn't show up in the view for case types """ app, _ = self.get_test_app() app.modules[0].case_details.short.columns = [ DetailColumn(header={'en': 'Owner Name'}, model='case', field='#owner_name', format='plain', case_tile_field='header'), DetailColumn(header={'en': 'Username'}, model='case', field='user/username', format='plain', case_tile_field='header'), ] metadata = app.get_case_metadata() prop = metadata.get_type('parent').get_property('#owner_name') self.assertFalse(prop.short_details) self.assertFalse(prop.long_details) prop = metadata.get_type('parent').get_property('user/username', allow_parent=True) self.assertFalse(prop.short_details) self.assertFalse(prop.long_details)
def create_temp_sort_column(sort_element, order): """ Used to create a column for the sort only properties to add the field to the list of properties and app strings but not persist anything to the detail data. """ from corehq.apps.app_manager.models import DetailColumn col = DetailColumn( model='case', field=sort_element.field, format='invisible', header=sort_element.display, ) col._i = order return col
def create_temp_sort_column(sort_element, order): """ Used to create a column for the sort only properties to add the field to the list of properties and app strings but not persist anything to the detail data. """ from corehq.apps.app_manager.models import DetailColumn col = DetailColumn( model='case', field=sort_element.field, format='invisible', header=sort_element.display, ) col._i = order return col
def setUp(self): self.app = Application.new_app(DOMAIN, "Untitled Application") self.app.build_spec = BuildSpec(version='tests', build_number=1) 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' # chosen xpath just used to reference more instances - not considered valid to use in apps self.module.case_details.short.columns.append( DetailColumn.wrap( dict( header={"en": "report_name"}, model="case", format="calculate", field="whatever", calc_xpath="instance('reports')/report[1]/name", ))) self.module.case_details.long.columns.append( DetailColumn.wrap( dict( header={"en": "ledger_name"}, model="case", format="calculate", field="whatever", calc_xpath="instance('ledgerdb')/ledgers/name/name", ))) 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 test_case_list_form_parent_child_basic(self): # * Register house (case type = house, basic) # * Register house form # * Register person (case type = person, parent select = 'Register house', basic) # * Register person form # * Manager person (case type = person, case list form = 'Register person form', basic) # * Manage person form factory = AppFactory(build_version='2.9.0') register_house_module, register_house_form = factory.new_basic_module('register_house', 'house') factory.form_opens_case(register_house_form) register_person_module, register_person_form = factory.new_basic_module('register_person', 'house') factory.form_requires_case(register_person_form) factory.form_opens_case(register_person_form, case_type='person', is_subcase=True) person_module, update_person_form = factory.new_basic_module( 'update_person', 'person', case_list_form=register_person_form ) factory.form_requires_case(update_person_form, parent_case_type='house') register_person_module.case_details.short.columns.append( DetailColumn( header={'en': 'a'}, model='case', field='parent/case_name', # Include a parent case property in the case list format='plain', ) ) self.assertXmlEqual(self.get_xml('case-list-form-suite-parent-child-basic'), factory.app.create_suite())
def _get_detail_column(indicator_name): from corehq.apps.app_manager.models import DetailColumn return DetailColumn( header={"en": "i1"}, model="case", field="indicator:cc/{}".format(indicator_name), format="plain")
def _add_form_detail_variable(self): self.module.case_details.short.columns.append( DetailColumn( header={'en': 'Next due'}, model='case', field='schedule:nextdue', format='plain', ))
def setUp(self): self.app = Application.new_app(DOMAIN, "Untitled Application") self.app.build_spec = BuildSpec(version='2.35.0', build_number=1) 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' # chosen xpath just used to reference more instances - not considered valid to use in apps self.module.case_details.short.columns.append( DetailColumn.wrap(dict( header={"en": "report_name"}, model="case", format="calculate", field="whatever", calc_xpath="instance('reports')/report[1]/name", )) ) self.module.case_details.long.columns.append( DetailColumn.wrap(dict( header={"en": "ledger_name"}, model="case", format="calculate", field="whatever", calc_xpath="instance('ledgerdb')/ledgers/name/name", )) ) 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='ɨŧsȺŧɍȺᵽ', defaultValue=( "instance('casedb')/case" "[@case_id='instance('commcaresession')/session/data/case_id']" "/ɨŧsȺŧɍȺᵽ") ), DefaultCaseSearchProperty( property='name', defaultValue="instance('locations')/locations/location[@id=123]/@type", ), ], )
def add_module_case_detail_column(module, display, field, trans, lang='en'): assert display in ('short', 'long') details = module.case_details.long if display == 'long' else module.case_details.short details.columns.append(DetailColumn( format='plain', field=field, header={lang: trans}, model='case', ))
def test_case_detail_icon_mapping(self): app = Application.new_app('domain', 'Untitled Application', application_version=APP_V2) 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'}), ], ), ] key1_varname = '10' key2_varname = hashlib.md5('age > 50').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}, ''))"> <variable name="h{key2_varname}"> <locale id="m0.case_short.case_age_1.enum.h{key2_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, ) # 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{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_workflow_registry_module_previous_screen_after_case_list_form(self): factory = AppFactory(DOMAIN, "App with DR", build_version='2.53.0') m0, f0 = factory.new_basic_module("new case", "case") factory.form_opens_case(f0, "case") m1, f1 = factory.new_basic_module("update case", "case") factory.form_requires_case(f1, "case") m1.case_details.long.columns.append( DetailColumn.wrap(dict( header={"en": "name"}, model="case", format="plain", field="whatever", )) ) m1.search_config = CaseSearch( properties=[ CaseSearchProperty(name='name', label={'en': 'Name'}), ], data_registry="myregistry", data_registry_workflow=REGISTRY_WORKFLOW_LOAD_CASE, ) m1.case_list_form.form_id = f0.get_unique_id() m1.case_list_form.label = {'en': 'New Case'} f1.post_form_workflow = WORKFLOW_PREVIOUS app = Application.wrap(factory.app.to_json()) app._id = "123" suite = app.create_suite() self.assertXmlPartialEqual( """ <partial> <create> <command value="'m1'"/> <query id="results" value="http://localhost:8000/a/test_domain/phone/registry_case/123/"> <data key="case_type" ref="'case'"/> <data key="x_commcare_data_registry" ref="'myregistry'"/> <data key="case_id" ref="instance('commcaresession')/session/data/case_id"/> </query> <datum id="case_id" value="instance('commcaresession')/session/data/case_id"/> <query id="registry" value="http://localhost:8000/a/test_domain/phone/registry_case/123/"> <data key="x_commcare_data_registry" ref="'myregistry'"/> <data key="case_type" ref="'case'"/> <data key="case_id" ref="instance('commcaresession')/session/data/case_id"/> </query> </create> </partial> """, suite, "./entry[2]/stack/create" )
def setUpClass(cls): super().setUpClass() cls.user = create_user("admin", "123") CaseSearchConfig.objects.create(domain=cls.domain, enabled=True) household_1 = str(uuid.uuid4()) case_blocks = [ CaseBlock( case_id=household_1, case_type='household', case_name="Villanueva", create=True, ) ] case_blocks.extend([ CaseBlock( case_id=str(uuid.uuid4()), case_type='person', case_name=name, create=True, update=properties, index={ 'parent': IndexAttrs('household', household_id, 'child') } if household_id else None, ) for name, properties, household_id in [ ("Jane", { "family": "Villanueva" }, household_1), ("Xiomara", { "family": "Villanueva" }, household_1), ("Alba", { "family": "Villanueva" }, household_1), ("Rogelio", { "family": "de la Vega" }, household_1), ("Jane", { "family": "Ramos" }, None), ] ]) case_search_es_setup(cls.domain, case_blocks) cls.factory = AppFactory(domain=cls.domain) module, form = cls.factory.new_basic_module('person', 'person') module.search_config = CaseSearch( properties=[CaseSearchProperty(name='name')]) module.case_details.short.columns = [ DetailColumn(format='plain', field=field, header={'en': field}, model='person') for field in ['name', 'parent/name'] ]
def test_advanced_suite_case_list_filter(self): app = Application.wrap(self.get_json('suite-advanced')) clinic_module = app.get_module(0) clinic_module.case_details.short.columns.append( DetailColumn(header={"en": "Filter"}, format='filter', filter_xpath=". = 'danny'", field='filter')) clinic_module_id = clinic_module.unique_id app.get_module(1).get_form( 0).actions.load_update_cases[0].details_module = clinic_module_id self.assertXmlEqual(self.get_xml('suite-advanced-filter'), app.create_suite())
def test_get_related_case_relationships(self): app = Application.new_app(self.domain, "Case Search App") module = app.add_module(Module.new_module("Search Module", "en")) module.case_type = self.case_type detail = module.case_details.short detail.columns.extend([ DetailColumn(header={"en": "x"}, model="case", field="x", format="plain"), DetailColumn(header={"en": "y"}, model="case", field="parent/parent/y", format="plain"), DetailColumn(header={"en": "z"}, model="case", field="host/z", format="plain"), ]) module.search_config.properties = [ CaseSearchProperty( name="texture", label={"en": "Texture"}, ) ] module = app.add_module(Module.new_module("Non-Search Module", "en")) module.case_type = self.case_type detail = module.case_details.short detail.columns.append( DetailColumn(header={"en": "zz"}, model="case", field="parent/zz", format="plain"), ) self.assertEqual(get_related_case_relationships(app, self.case_type), {"parent/parent", "host"}) self.assertEqual(get_related_case_relationships(app, "monster"), set())
def test_case_detail_calculated_conditional_enum(self, *args): app = Application.new_app('domain', 'Untitled Application') module = app.add_module(Module.new_module('Unititled Module', None)) module.case_type = 'patient' module.case_details.short.columns = [ DetailColumn( header={'en': 'Gender'}, model='case', field="if(gender = 'male', 'boy', 'girl')", format='enum', enum=[ MappingItem(key="boy", value={'en': 'Boy'}), MappingItem(key="girl", value={'en': 'Girl'}), ], ), ] icon_mapping_spec = """ <partial> <template> <text> <xpath function="replace(join(' ', if(selected(if(gender = 'male', 'boy', 'girl'), 'boy'), $kboy, ''), if(selected(if(gender = 'male', 'boy', 'girl'), 'girl'), $kgirl, '')), '\\s+', ' ')"> <variable name="kboy"> <locale id="m0.case_short.case_if(gender 'male', 'boy', 'girl')_1.enum.kboy"/> </variable> <variable name="kgirl"> <locale id="m0.case_short.case_if(gender 'male', 'boy', 'girl')_1.enum.kgirl"/> </variable> </xpath> </text> </template> </partial> """ # noqa: #501 # check correct suite is generated self.assertXmlPartialEqual( icon_mapping_spec, app.create_suite(), './detail[@id="m0_case_short"]/field/template') # check app strings mapped correctly app_strings = commcare_translations.loads(app.create_app_strings('en')) self.assertEqual( app_strings[ "m0.case_short.case_if(gender 'male', 'boy', 'girl')_1.enum.kboy"], 'Boy') self.assertEqual( app_strings[ "m0.case_short.case_if(gender 'male', 'boy', 'girl')_1.enum.kgirl"], 'Girl')
def setUp(self): self.app = Application.new_app(DOMAIN, "Untitled Application") self.app._id = '123' 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.reg_module = self.app.add_module(Module.new_module("Registration", None)) self.reg_form = self.app.new_form(1, "Untitled Form", None, attachment=get_simple_form("xmlns1.0")) self.reg_module.case_type = 'case' self.reg_form.actions.open_case = OpenCaseAction( name_update=ConditionalCaseUpdate(question_path="/data/question1") ) self.reg_form.actions.open_case.condition.type = 'always' self.reg_form.post_form_workflow = WORKFLOW_FORM self.reg_form.form_links = [ FormLink(form_id=self.form.get_unique_id()) ] # 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.form = self.module.forms[0]
def test_non_existant_parent(self): """If you reference a parent property in the case list but the case type has no parent, we should tell you """ app, _ = self.get_test_app() app.modules[0].case_details.short.columns = [ DetailColumn(header={'en': 'Parent prop reference'}, model='case', field='parent/doesnt_exist', format='plain', case_tile_field='header'), ] metadata = app.get_case_metadata() prop = metadata.get_type('parent').get_property('parent/doesnt_exist', allow_parent=True) self.assertIsNotNone(prop.short_details[0].error)
def get_app_with_case_search(domain): factory = AppFactory(domain=domain) for case_type, fields in [ ('person', ['name']), ('creative_work', ['name', 'parent/name']), ]: module, _ = factory.new_basic_module(case_type, case_type) module.search_config = CaseSearch( properties=[CaseSearchProperty(name=field) for field in fields]) module.case_details.short.columns = [ DetailColumn(format='plain', field=field, header={'en': field}, model=case_type) for field in fields ] return factory.app
def test_calculate_conditions_no_errors(self): """If you have a calculate condition in your case detail, you are on your own. """ calculation = "instance('casedb')/casedb/case[@case_id = instance('commcaresession')]/session/case_id" app = self.get_test_app() app.modules[0].case_details.short.columns = [ DetailColumn( header={'en': 'Calculate'}, model='case', useXpathExpression=True, field="instance('casedb')/casedb/case[@case_id = instance('commcaresession')]/session/case_id", format='calculate', case_tile_field='header' ), ] metadata = app.get_case_metadata() prop = metadata.get_type('parent').get_property(calculation, allow_parent=True) self.assertIsNone(prop.short_details[0].error)
def test_schedule(self): app = Application.wrap(self.get_json('suite-advanced')) mod = app.get_module(1) mod.has_schedule = True f1 = mod.get_form(0) f2 = mod.get_form(1) f3 = mod.get_form(2) f1.schedule = FormSchedule(anchor='edd', expires=120, post_schedule_increment=15, visits=[ ScheduleVisit(due=5, late_window=4), ScheduleVisit(due=10, late_window=9), ScheduleVisit(due=20, late_window=5) ]) f2.schedule = FormSchedule(anchor='dob', visits=[ ScheduleVisit(due=7, late_window=4), ScheduleVisit(due=15) ]) f3.schedule = FormSchedule(anchor='dob', visits=[ ScheduleVisit(due=9, late_window=1), ScheduleVisit(due=11) ]) mod.case_details.short.columns.append( DetailColumn( header={'en': 'Next due'}, model='case', field='schedule:nextdue', format='plain', )) suite = app.create_suite() self.assertXmlPartialEqual(self.get_xml('schedule-fixture'), suite, './fixture') self.assertXmlPartialEqual(self.get_xml('schedule-entry'), suite, "./detail[@id='m1_case_short']")
def setUp(self): self.app = Application.new_app(DOMAIN, "Untitled Application") self.app.build_spec = BuildSpec(version='2.35.0', build_number=1) 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' # chosen xpath just used to reference more instances - not considered valid to use in apps self.module.case_details.short.columns.append( DetailColumn.wrap( dict( header={"en": "report_name"}, model="case", format="calculate", field="whatever", calc_xpath="instance('reports')/report[1]/name", ))) self.module.case_details.short.columns.append( DetailColumn.wrap( dict( header={"en": "moon"}, model="case", format="calculate", field="whatever", calc_xpath= "instance('item-list:moons')/moons_list/moons[favorite='yes']/name", ))) self.module.case_details.long.columns.append( DetailColumn.wrap( dict( header={"en": "ledger_name"}, model="case", format="calculate", field="whatever", calc_xpath="instance('ledgerdb')/ledgers/name/name", ))) 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'}) ], default_relevant=True, additional_relevant="instance('groups')/groups/group", search_filter= "name = instance('item-list:trees')/trees_list/trees[favorite='yes']/name", default_properties=[ DefaultCaseSearchProperty( property='ɨŧsȺŧɍȺᵽ', defaultValue= ("instance('casedb')/case" "[@case_id='instance('commcaresession')/session/data/case_id']" "/ɨŧsȺŧɍȺᵽ")), DefaultCaseSearchProperty( property='name', defaultValue= "instance('locations')/locations/location[@id=123]/@type", ), ], )
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_case_detail_conditional_enum(self, *args): app = Application.new_app('domain', 'Untitled Application') module = app.add_module(Module.new_module('Unititled Module', None)) module.case_type = 'patient' module.case_details.short.columns = [ DetailColumn( header={'en': 'Gender'}, model='case', field='gender', format='conditional-enum', enum=[ MappingItem(key="gender = 'male' and age <= 21", value={'en': 'Boy'}), MappingItem(key="gender = 'female' and age <= 21", value={'en': 'Girl'}), MappingItem(key="gender = 'male' and age > 21", value={'en': 'Man'}), MappingItem(key="gender = 'female' and age > 21", value={'en': 'Woman'}), ], ), ] key1_varname = hashlib.md5( "gender = 'male' and age <= 21".encode('utf-8')).hexdigest()[:8] key2_varname = hashlib.md5( "gender = 'female' and age <= 21".encode('utf-8')).hexdigest()[:8] key3_varname = hashlib.md5( "gender = 'male' and age > 21".encode('utf-8')).hexdigest()[:8] key4_varname = hashlib.md5( "gender = 'female' and age > 21".encode('utf-8')).hexdigest()[:8] icon_mapping_spec = """ <partial> <template> <text> <xpath function="if(gender = 'male' and age <= 21, $h{key1_varname}, if(gender = 'female' and age <= 21, $h{key2_varname}, if(gender = 'male' and age > 21, $h{key3_varname}, if(gender = 'female' and age > 21, $h{key4_varname}, ''))))"> <variable name="h{key4_varname}"> <locale id="m0.case_short.case_gender_1.enum.h{key4_varname}"/> </variable> <variable name="h{key2_varname}"> <locale id="m0.case_short.case_gender_1.enum.h{key2_varname}"/> </variable> <variable name="h{key3_varname}"> <locale id="m0.case_short.case_gender_1.enum.h{key3_varname}"/> </variable> <variable name="h{key1_varname}"> <locale id="m0.case_short.case_gender_1.enum.h{key1_varname}"/> </variable> </xpath> </text> </template> </partial> """.format( # noqa: #501 key1_varname=key1_varname, key2_varname=key2_varname, key3_varname=key3_varname, key4_varname=key4_varname, ) # check correct suite is generated self.assertXmlPartialEqual( icon_mapping_spec, app.create_suite(), './detail[@id="m0_case_short"]/field/template') # check app strings mapped correctly app_strings = commcare_translations.loads(app.create_app_strings('en')) self.assertEqual( app_strings[ 'm0.case_short.case_gender_1.enum.h{key1_varname}'.format( key1_varname=key1_varname, )], 'Boy') self.assertEqual( app_strings[ 'm0.case_short.case_gender_1.enum.h{key2_varname}'.format( key2_varname=key2_varname, )], 'Girl') self.assertEqual( app_strings[ 'm0.case_short.case_gender_1.enum.h{key3_varname}'.format( key3_varname=key3_varname, )], 'Man') self.assertEqual( app_strings[ 'm0.case_short.case_gender_1.enum.h{key4_varname}'.format( key4_varname=key4_varname, )], 'Woman')