def clean_apk_version(self): # make sure it points to a valid BuildSpec apk_version = self.cleaned_data['apk_version'] if apk_version == LATEST_APK_VALUE: return apk_version try: BuildSpec.from_string(apk_version) return apk_version except ValueError: raise forms.ValidationError( _('Invalid APK version %(version)s'), params={'version': apk_version})
def commcare_version_report(request, template="hqadmin/commcare_version.html"): apps = get_db().view("app_manager/applications_brief").all() menu = CommCareBuildConfig.fetch().menu builds = [item.build.to_string() for item in menu] by_build = dict([(item.build.to_string(), {"label": item.label, "apps": []}) for item in menu]) for app in apps: app = app["value"] app["id"] = app["_id"] if app.get("build_spec"): build_spec = BuildSpec.wrap(app["build_spec"]) build = build_spec.to_string() if by_build.has_key(build): by_build[build]["apps"].append(app) else: by_build[build] = {"label": build_spec.get_label(), "apps": [app]} builds.append(build) tables = [] for build in builds: by_build[build]["build"] = build tables.append(by_build[build]) context = get_hqadmin_base_context(request) context.update({"tables": tables}) context["hide_filters"] = True return render(request, template, context)
def make_app(self, spec): app = Application.new_app('domain', "Untitled Application", application_version=APP_V2) app.build_spec = BuildSpec.from_string('2.9.0/latest') case_type = "frog" for m_spec in spec["m"]: m_type = m_spec['type'] m_class = Module if m_type == 'basic' else AdvancedModule module = app.add_module(m_class.new_module(m_spec['name'], None)) module.unique_id = m_spec['name'] module.case_type = m_spec.get("case_type", "frog") module.root_module_id = m_spec.get("parent", None) for f_spec in m_spec['f']: form_name = f_spec["name"] form = app.new_form(module.id, form_name, None) form.unique_id = form_name for a_spec in f_spec.get('actions', []): if isinstance(a_spec, dict): action = a_spec['action'] case_type = a_spec.get("case_type", case_type) parent = a_spec.get("parent", None) else: action = a_spec if 'open' == action: if m_type == "basic": form.actions.open_case = OpenCaseAction(name_path="/data/question1") form.actions.open_case.condition.type = 'always' else: form.actions.open_cases.append(AdvancedOpenCaseAction( case_type=case_type, case_tag='open_{}'.format(case_type), name_path='/data/name' )) elif 'update' == action: if m_type == "basic": form.requires = 'case' form.actions.update_case = UpdateCaseAction(update={'question1': '/data/question1'}) form.actions.update_case.condition.type = 'always' else: form.actions.load_update_cases.append(LoadUpdateAction( case_type=case_type, case_tag='update_{}'.format(case_type), parent_tag=parent, )) elif 'open_subacse': if m_type == "basic": form.actions.subcases.append(OpenSubCaseAction( case_type=case_type, case_name="/data/question1", condition=FormActionCondition(type='always') )) else: form.actions.open_cases.append(AdvancedOpenCaseAction( case_type=case_type, case_tag='subcase_{}'.format(case_type), name_path='/data/name', parent_tag=parent )) return app
def testCreateJadJar(self, mock): self.app.build_spec = BuildSpec(**self.build1) self.app.create_build_files() self.app.save(increment_version=False) # get a fresh one from the db to make sure attachments aren't cached # since that's closer to the real situation self.app = Application.get(self.app._id) self.app.create_jadjar_from_build_files(save=True) self.app.save(increment_version=False) self._check_has_build_files(self.app, self.jad_jar_paths)
def setUp(self): self.build_profile_id = uuid.uuid4().hex self.app = Application(build_spec=BuildSpec(version='2.7.2'), name="TÉST ÁPP", domain="potter", langs=['en'], build_profiles={ self.build_profile_id: BuildProfile(langs=['en'], name='en-profile') })
def setUpClass(cls): cls.domain = Domain(name='app-manager-testviews-domain', is_active=True) cls.domain.save() cls.username = '******' cls.password = '******' cls.user = WebUser.create(cls.domain.name, cls.username, cls.password, is_active=True) cls.user.is_superuser = True cls.user.save() cls.build = add_build(version='2.7.0', build_number=20655) cls.app = Application.new_app(cls.domain.name, "TestApp", application_version=APP_V1) cls.app.build_spec = BuildSpec.from_string('2.7.0/latest') toggles.CUSTOM_PROPERTIES.set("domain:{domain}".format(domain=cls.domain.name), True)
def get_latest_apk_version(self): from corehq.apps.app_manager.models import LATEST_APK_VALUE from corehq.apps.builds.models import BuildSpec from corehq.apps.builds.utils import get_default_build_spec if self.app.global_app_config.apk_prompt == "off": return {} else: configured_version = self.app.global_app_config.apk_version if configured_version == LATEST_APK_VALUE: value = get_default_build_spec().version else: value = BuildSpec.from_string(configured_version).version force = self.app.global_app_config.apk_prompt == "forced" return {"value": value, "force": force}
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, "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_update_form_references_case_list_form(self): app = Application.new_app('domain', 'Foo') app.modules.append(Module(forms=[Form()])) app.modules.append(Module(forms=[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(1).get_form(0).source = BLANK_TEMPLATE.format(xmlns='xmlns-1') original_form_id = app.get_module(1).get_form(0).unique_id app.get_module(0).case_list_form.form_id = original_form_id copy = Application.from_source(app.export_json(dump_json=False), 'domain') new_form_id = copy.get_module(1).get_form(0).unique_id self.assertNotEqual(original_form_id, new_form_id) self.assertEqual(new_form_id, copy.get_module(0).case_list_form.form_id)
def testCreateJadJar(self): version = "1.2.dev" build_number = 7106 def make_sure_there_is_a_build(): path = os.path.join(os.path.dirname(__file__), "jadjar") jad_path = os.path.join( path, 'CommCare_%s_%s.zip' % (version, build_number)) CommCareBuild.create_from_zip(jad_path, version, build_number) make_sure_there_is_a_build() # make sure this doesn't raise an error self.app.build_spec = BuildSpec(version=version, build_number=build_number) self.app.create_jadjar()
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 setUpClass(cls): cls.domain = Domain(name='app-manager-testviews-domain', is_active=True) cls.domain.save() cls.username = '******' cls.password = '******' cls.user = WebUser.create(cls.domain.name, cls.username, cls.password, is_active=True) cls.user.is_superuser = True cls.user.save() cls.build = add_build(version='2.7.0', build_number=20655) cls.app = Application.new_app(cls.domain.name, "TestApp") cls.app.build_spec = BuildSpec.from_string('2.7.0/latest') toggles.CUSTOM_PROPERTIES.set( "domain:{domain}".format(domain=cls.domain.name), True)
def test_update_form_references_case_list_form(self): app = Application.new_app('domain', 'Foo') app.modules.append(Module(forms=[Form()])) app.modules.append(Module(forms=[Form()])) app.build_spec = BuildSpec.from_string('2.7.0/latest') app.get_module(0).get_form(0).source = get_simple_form( xmlns='xmlns-0.0') app.get_module(1).get_form(0).source = get_simple_form(xmlns='xmlns-1') original_form_id = app.get_module(1).get_form(0).unique_id app.get_module(0).case_list_form.form_id = original_form_id copy = Application.from_source(app.export_json(dump_json=False), 'domain') new_form_id = copy.get_module(1).get_form(0).unique_id self.assertNotEqual(original_form_id, new_form_id) self.assertEqual(new_form_id, copy.get_module(0).case_list_form.form_id)
def test_update_form_references_form_link(self): app = Application.new_app('domain', 'Foo') app.modules.append(Module(forms=[Form()])) 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(1).get_form(0).source = BLANK_TEMPLATE.format(xmlns='xmlns-1') original_form_id1 = app.get_module(1).get_form(0).unique_id original_form_id2 = app.get_module(1).get_form(1).unique_id app.get_module(0).get_form(0).form_links = [ FormLink(xpath="", form_id=original_form_id1), FormLink(xpath="", form_id=original_form_id2), ] copy = Application.from_source(app.export_json(dump_json=False), 'domain') new_form_id1 = copy.get_module(1).get_form(0).unique_id new_form_id2 = copy.get_module(1).get_form(1).unique_id self.assertNotEqual(original_form_id1, new_form_id1) self.assertNotEqual(original_form_id2, new_form_id2) self.assertEqual(new_form_id1, copy.get_module(0).get_form(0).form_links[0].form_id) self.assertEqual(new_form_id2, copy.get_module(0).get_form(0).form_links[1].form_id)
def test_prompt_appearance(self, *args): """Setting the appearance to "barcode" """ # Shouldn't be included for versions before 2.50 self.module.search_config.properties[0].appearance = 'barcode_scan' suite = self.app.create_suite() expected = """ <partial> <prompt key="name"> <display> <text> <locale id="search_property.m0.name"/> </text> </display> </prompt> </partial> """ self.assertXmlPartialEqual( expected, suite, "./remote-request[1]/session/query/prompt[@key='name']") self.app.build_spec = BuildSpec(version='2.50.0', build_number=1) suite = self.app.create_suite() expected = """ <partial> <prompt key="name" appearance="barcode_scan"> <display> <text> <locale id="search_property.m0.name"/> </text> </display> </prompt> </partial> """ self.assertXmlPartialEqual( expected, suite, "./remote-request[1]/session/query/prompt[@key='name']")
def get_build_spec_for_tests(version=None): return BuildSpec({ "version": version or "2.7.0", "build_number": None, "latest": True })
def setUp(self): self.app = Application(build_spec=BuildSpec(version='2.7.0'), name="TÉST ÁPP", domain="potter", langs=['en'])
def setUp(self): self.app = Application(build_spec=BuildSpec(version='2.7.0'))
def test(self, mock): add_build(version='2.7.0', build_number=20655) domain = 'form-versioning-test' # set up inital app factory = AppFactory(domain, 'Foo') m0, f0 = factory.new_basic_module("bar", "bar") f0.source = get_simple_form(xmlns='xmlns-0.0') f1 = factory.new_form(m0) f1.source = get_simple_form(xmlns='xmlns-1') app = factory.app app.build_spec = BuildSpec.from_string('2.7.0/latest') app.save() # make a build build1 = app.make_build() build1.save() # modify first form app.get_module(0).get_form(0).source = get_simple_form( xmlns='xmlns-0.1') app.save() # make second build build2 = app.make_build() build2.save() # modify first form app.get_module(0).get_form(0).source = get_simple_form( xmlns='xmlns-0.2') app.save() app.save() app.save() # make third build build3 = app.make_build() 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() 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() xxx_build1.save() # modify first form of copy app xxx_app.get_module(0).get_form(0).source = get_simple_form( xmlns='xmlns-0.xxx.0') xxx_app.save() # make second build of copy xxx_build2 = xxx_app.make_build() xxx_build2.save() self.assertEqual(self.get_form_versions(xxx_build1), [1, 1]) self.assertEqual(self.get_form_versions(xxx_build2), [2, 1])
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): self.app = Application.new_app("domain", "my app", application_version=APP_V2) 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/latest") self.app.build_spec = self.min_spec
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/latest') self.app.build_spec = self.min_spec
def test_jad_settings(self): self.app.build_spec = BuildSpec(version='2.2.0', build_number=1) self.assertIn('Build-Number', self.app.jad_settings) self.app.build_spec = BuildSpec(version='2.8.0', build_number=1) self.assertNotIn('Build-Number', self.app.jad_settings)
def setUp(self): self.app = Application.new_app(self.project.name, "TestApp") self.app.build_spec = BuildSpec.from_string('2.7.0/latest') self.client.login(username=self.username, password=self.password)
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 testCreateJadJar(self): # make sure this doesn't raise an error self.app.build_spec = BuildSpec(**self.build1) self.app.create_jadjar()
def test(self, mock): add_build(version='2.7.0', build_number=20655) domain = 'form-versioning-test' # set up inital app app = Application.new_app(domain, 'Foo') 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() 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() 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() 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() 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() 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() xxx_build2.save() self.assertEqual(self.get_form_versions(xxx_build1), [1, 1]) self.assertEqual(self.get_form_versions(xxx_build2), [2, 1])
def _get_default(self): return BuildSpec({ "version": "2.7.0", "build_number": None, "latest": True })
def test(self, mock): add_build(version='2.7.0', build_number=20655) domain = 'form-versioning-test' # set up inital app app = Application.new_app(domain, 'Foo') 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() 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() 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() 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() 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() 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() xxx_build2.save() self.assertEqual(self.get_form_versions(xxx_build1), [1, 1]) self.assertEqual(self.get_form_versions(xxx_build2), [2, 1])
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]