def test_link_to_child_module(self): factory = AppFactory(build_version='2.9.0/latest') m0, m0f0 = factory.new_basic_module('enroll child', 'child') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_basic_module('child visit', 'child') factory.form_requires_case(m1f0) factory.form_opens_case(m1f0, case_type='visit', is_subcase=True) m2, m2f0 = factory.new_advanced_module('visit history', 'visit', parent_module=m1) factory.form_requires_case(m2f0, 'child') factory.form_requires_case(m2f0, 'visit', parent_case_type='child') m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(xpath="true()", form_id=m1f0.unique_id), ] m1f0.post_form_workflow = WORKFLOW_FORM m1f0.form_links = [ FormLink(xpath="true()", form_id=m2f0.unique_id), ] self.assertXmlPartialEqual(self.get_xml('form_link_tdh'), factory.app.create_suite(), "./entry")
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 = get_simple_form( xmlns='xmlns-0.0') app.get_module(1).get_form(0).source = get_simple_form(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_manual_form_link(self): factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('enroll child', 'child') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_basic_module('child visit', 'child') factory.form_requires_case(m1f0) factory.form_opens_case(m1f0, case_type='visit', is_subcase=True) m2, m2f0 = factory.new_advanced_module('visit history', 'visit', parent_module=m1) factory.form_requires_case(m2f0, 'child') factory.form_requires_case(m2f0, 'visit', parent_case_type='child') m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(xpath="true()", form_id=m1f0.unique_id, datums=[ FormDatum(name='case_id', xpath="instance('commcaresession')/session/data/case_id_new_child_0") ]), ] m1f0.post_form_workflow = WORKFLOW_FORM m1f0.form_links = [ FormLink(xpath="true()", form_id=m2f0.unique_id, datums=[ FormDatum(name='case_id', xpath="instance('commcaresession')/session/data/case_id"), FormDatum(name='case_id_load_visit_0', xpath="instance('commcaresession')/session/data/case_id_new_visit_0"), ]), ] self.assertXmlPartialEqual(self.get_xml('form_link_tdh'), factory.app.create_suite(), "./entry")
def test_link_to_module(self, *args): factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('Update Stripes', 'stripes') factory.form_requires_case(m0f0) m1, m1f0 = factory.new_basic_module('Update Solids', 'solids') factory.form_requires_case(m1f0) m2, m2f0 = factory.new_basic_module('Close Stripes', 'stripes') factory.form_requires_case(m2f0) m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(xpath="true()", module_unique_id=m0.unique_id) ] self.assertXmlPartialEqual( """ <partial> <stack> <create if="true()"> <command value="'m0'"/> </create> </stack> </partial> """, factory.app.create_suite(), "./entry[1]/stack") m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(xpath="true()", module_unique_id=m1.unique_id) ] self.assertXmlPartialEqual( """ <partial> <stack> <create if="true()"> <command value="'m1'"/> </create> </stack> </partial> """, factory.app.create_suite(), "./entry[1]/stack") m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(xpath="true()", module_unique_id=m2.unique_id) ] self.assertXmlPartialEqual( """ <partial> <stack> <create if="true()"> <command value="'m2'"/> </create> </stack> </partial> """, factory.app.create_suite(), "./entry[1]/stack")
def test_form_links_other_child_module(self): # This test demonstrates current behavior that I believe to be flawed factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('parent', 'mother') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_basic_module('child', 'baby', parent_module=m0) factory.form_requires_case(m1f0) m0f1 = factory.new_form(m0) m0f1.post_form_workflow = WORKFLOW_FORM m0f1.form_links = [FormLink(xpath='true()', form_id=m1f0.unique_id)] m2, m2f0 = factory.new_basic_module('other_module', 'baby') m2f0.post_form_workflow = WORKFLOW_FORM m2f0.form_links = [FormLink(xpath='true()', form_id=m1f0.unique_id)] suite_xml = factory.app.create_suite() # m0f1 links to m1f0, a form in its child module. Here's the stack for that: expected = """ <partial> <stack> <create if="true()"> <command value="'m0'"/> <command value="'m1'"/> <datum id="case_id_new_mother_0" value="uuid()"/> <datum id="case_id" value="instance('commcaresession')/session/data/case_id"/> <command value="'m1-f0'"/> </create> </stack> </partial> """ self.assertXmlPartialEqual(expected, suite_xml, "./entry[2]/stack") # m2f0 links to m1f0, a form in a separate child module, here's the stack there expected = """ <partial> <stack> <create if="true()"> <command value="'m0'"/> <command value="'m1'"/> <datum id="case_id_new_mother_0" value="uuid()"/> <datum id="case_id" value="instance('commcaresession')/session/data/case_id"/> <command value="'m1-f0'"/> </create> </stack> </partial> """ self.assertXmlPartialEqual(expected, suite_xml, "./entry[4]/stack")
def test_link_from_child_module(self, *args): factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('Update City', 'city') factory.form_requires_case(m0f0) m1, m1f0 = factory.new_basic_module('Update Person', 'person', parent_module=m0) factory.form_requires_case(m1f0) m2, m2f0 = factory.new_basic_module('Update planet', 'planet') factory.form_requires_case(m2f0) m1f0.post_form_workflow = WORKFLOW_FORM m1f0.form_links = [ FormLink(xpath="true()", module_unique_id=m2.unique_id) ] self.assertXmlPartialEqual( """ <partial> <stack> <create if="true()"> <command value="'m2'"/> </create> </stack> </partial> """, factory.app.create_suite(), "./entry[2]/stack")
def test_link_between_child_modules(self, *args): factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('Update City', 'city') factory.form_requires_case(m0f0) m1, m1f0 = factory.new_basic_module('Update Person', 'person', parent_module=m0) factory.form_requires_case(m1f0) m2, m2f0 = factory.new_basic_module('Close City', 'city') factory.form_requires_case(m2f0) m3, m3f0 = factory.new_basic_module('Close Person', 'person', parent_module=m2) factory.form_requires_case(m3f0) m1f0.post_form_workflow = WORKFLOW_FORM m1f0.form_links = [ FormLink(xpath="true()", module_unique_id=m3.unique_id) ] self.assertXmlPartialEqual( """ <partial> <stack> <create if="true()"> <command value="'m2'"/> <datum id="case_id" value="instance('commcaresession')/session/data/case_id"/> <command value="'m3'"/> </create> </stack> </partial> """, factory.app.create_suite(), "./entry[2]/stack")
def test_form_links_submodule(self): # Test that when linking between two forms in a submodule we match up the # session variables between the source and target form correctly factory = AppFactory(build_version='2.9.0/latest') m0, m0f0 = factory.new_basic_module('child visit', 'child') factory.form_requires_case(m0f0) factory.form_opens_case(m0f0, 'visit', is_subcase=True) m1, m1f0 = factory.new_advanced_module('visit histroy', 'visit', parent_module=m0) factory.form_requires_case(m1f0, 'child') factory.form_requires_case(m1f0, 'visit', parent_case_type='child') m1f1 = factory.new_form(m1) factory.form_requires_case(m1f1, 'child') factory.form_requires_case(m1f1, 'visit', parent_case_type='child') m1f0.post_form_workflow = WORKFLOW_FORM m1f0.form_links = [ FormLink(xpath="true()", form_id=m1f1.unique_id), ] self.assertXmlPartialEqual(self.get_xml('form_link_submodule'), factory.app.create_suite(), "./entry")
def setUp(self): factory = AppFactory(DOMAIN, "App with DR and child modules", build_version='2.53.0') m0, f0 = factory.new_basic_module("case list", "case") factory.form_requires_case(f0) m1, f1 = factory.new_basic_module("child case list", "case", parent_module=m0) m1.parent_select = ParentSelect(active=True, relationship="other", module_id=m0.get_or_create_unique_id()) f2 = factory.new_form(m1) factory.form_requires_case(f1) factory.form_requires_case(f2) m1.search_config = CaseSearch( properties=[CaseSearchProperty(name='name', label={'en': 'Name'})], data_registry="myregistry", data_registry_workflow=REGISTRY_WORKFLOW_LOAD_CASE, ) # link from f1 to f2 (both in the child module) f1.post_form_workflow = WORKFLOW_FORM f1.form_links = [FormLink(form_id=f2.get_unique_id())] factory.app._id = "123" # wrap to have assign_references called self.app = Application.wrap(factory.app.to_json())
def test_form_linking_multiple_case_types(): factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('m0', 'frog') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_basic_module('m1', 'frog') factory.form_requires_case(m1f0) m1.search_config.additional_case_types = ['tadpole'] m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(form_id=m1f0.unique_id), ] suite = factory.app.create_suite() print(suite.decode('utf8')) # ensure that target datum contains both case types datum = extract_xml_partial(suite, "./entry[2]/session/datum[@id='case_id']", wrap=False).decode('utf8') eq(datum, Regex(r"\[@case_type='frog' or @case_type='tadpole'\]")) expected_stack = """ <partial> <create> <command value="'m1'"/> <datum id="case_id" value="instance('commcaresession')/session/data/case_id_new_frog_0"/> <command value="'m1-f0'"/> </create> </partial>""" assert_xml_partial_equal(expected_stack, suite, "./entry[1]/stack/create")
def test_manual_form_link_with_fallback(self): factory = AppFactory(build_version='2.9.0/latest') m0, m0f0 = factory.new_basic_module('enroll child', 'child') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_basic_module('child visit', 'child') factory.form_requires_case(m1f0) factory.form_opens_case(m1f0, case_type='visit', is_subcase=True) m2, m2f0 = factory.new_advanced_module('visit history', 'visit', parent_module=m1) factory.form_requires_case(m2f0, 'child') factory.form_requires_case(m2f0, 'visit', parent_case_type='child') m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(xpath="true()", form_id=m1f0.unique_id, datums=[ FormDatum(name='case_id', xpath="instance('commcaresession')/session/data/case_id_new_child_0") ]), ] m1f0.post_form_workflow = WORKFLOW_FORM condition_for_xpath = "instance('casedb')/casedb/case[@case_id = " \ "instance('commcaresession')/session/data/case_id]/prop = 'value'" m1f0.form_links = [ FormLink(xpath="true()", form_id=m2f0.unique_id, datums=[ FormDatum(name='case_id', xpath="instance('commcaresession')/session/data/case_id"), FormDatum(name='case_id_load_visit_0', xpath="instance('commcaresession')/session/data/case_id_new_visit_0"), ]), FormLink(xpath=condition_for_xpath, form_id=m2f0.unique_id, datums=[ FormDatum(name='case_id', xpath="instance('commcaresession')/session/data/case_id"), FormDatum(name='case_id_load_visit_0', xpath="instance('commcaresession')/session/data/case_id_new_visit_0"), ]), ] m1f0.post_form_workflow_fallback = WORKFLOW_PREVIOUS self.assertXmlPartialEqual(self.get_xml('form_link_tdh_with_fallback_previous'), factory.app.create_suite(), "./entry") m1f0.post_form_workflow_fallback = WORKFLOW_MODULE self.assertXmlPartialEqual(self.get_xml('form_link_tdh_with_fallback_module'), factory.app.create_suite(), "./entry") m1f0.post_form_workflow_fallback = WORKFLOW_ROOT self.assertXmlPartialEqual(self.get_xml('form_link_tdh_with_fallback_root'), factory.app.create_suite(), "./entry")
def test_with_case_management_multiple_links(self): factory = AppFactory(build_version='2.9.0/latest') m0, m0f0 = factory.new_basic_module('m0', 'frog') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_basic_module('m1', 'frog') factory.form_requires_case(m1f0) m1f1 = factory.new_form(m1) factory.form_opens_case(m1f1) m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(xpath="a = 1", form_id=m1f0.unique_id), FormLink(xpath="a = 2", form_id=m1f1.unique_id) ] self.assertXmlPartialEqual(self.get_xml('form_link_multiple'), factory.app.create_suite(), "./entry[1]")
def test_form_linking_from_registry_module(self, *args): self.form.post_form_workflow = WORKFLOW_FORM self.form.form_links = [ FormLink(xpath="(today() - dob) < 7", module_unique_id=self.module.unique_id) ] self.assertXmlPartialEqual( self.get_xml('form_link_followup_module_registry'), self.app.create_suite(), "./entry[1]" )
def test_basic(self): factory = AppFactory(build_version='2.9.0/latest') m0, m0f0 = factory.new_basic_module('m0', 'frog') m1, m1f0 = factory.new_basic_module('m1', 'frog') m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(xpath="(today() - dob) < 7", form_id=m1f0.unique_id) ] self.assertXmlPartialEqual(self.get_xml('form_link_basic'), factory.app.create_suite(), "./entry[1]")
def test_followup_module(self, *args): factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('m0', 'frog') m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [ FormLink(xpath="(today() - dob) < 7", module_unique_id=m0.unique_id) ] factory.form_requires_case(m0f0) self.assertXmlPartialEqual(self.get_xml('form_link_followup_module'), factory.app.create_suite(), "./entry[1]")
def test_reference_to_missing_session_variable_in_stack(self): # http://manage.dimagi.com/default.asp?236750 # # Stack create blocks do not update the session after each datum # so items put into the session in one step aren't available later steps # # <datum id="case_id_A" value="instance('commcaresession')/session/data/case_id_new_A"/> # - <datum id="case_id_B" value="instance('casedb')/casedb/case[@case_id=instance('commcaresession')/session/data/case_id_A]/index/host"/> # + <datum id="case_id_B" value="instance('casedb')/casedb/case[@case_id=instance('commcaresession')/session/data/case_id_new_A]/index/host"/> # # in the above example ``case_id_A`` is being added to the session and then # later referenced. However since the session doesn't get updated # the value isn't available in the session. # # To fix this we need to replace any references to previous variables with the full xpath which # that session variable references. # # See corehq.apps.app_manager.suite_xml.post_process.workflow._replace_session_references_in_stack factory = AppFactory(build_version='2.9.0/latest') m0, m0f0 = factory.new_basic_module('person registration', 'person') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_advanced_module('episode registration', 'episode') factory.form_requires_case(m1f0, case_type='person') factory.form_opens_case(m1f0, case_type='episode', is_subcase=True, is_extension=True) m2, m2f0 = factory.new_advanced_module('tests', 'episode') factory.form_requires_case(m2f0, 'episode') factory.advanced_form_autoloads(m2f0, AUTO_SELECT_CASE, 'host', 'load_episode_0') m1f0.post_form_workflow = WORKFLOW_FORM m1f0.form_links = [ FormLink( xpath="true()", form_id=m2f0.unique_id, datums=[ FormDatum( name='case_id_load_episode_0', xpath= "instance('commcaresession')/session/data/case_id_new_episode_0" ) ]), ] self.assertXmlPartialEqual(self.get_xml('form_link_enikshay'), factory.app.create_suite(), "./entry")
def test_with_case_management_create_update(self, *args): factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('m0', 'frog') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_basic_module('m1', 'frog') factory.form_requires_case(m1f0) m0f0.post_form_workflow = WORKFLOW_FORM m0f0.form_links = [FormLink(xpath='true()', form_id=m1f0.unique_id)] self.assertXmlPartialEqual( self.get_xml('form_link_create_update_case'), factory.app.create_suite(), "./entry[1]")
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_link_to_form_in_parent_module(self, *args): factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('enroll child', 'child') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_basic_module('child visit', 'child') factory.form_requires_case(m1f0) m2, m2f0 = factory.new_advanced_module('visit history', 'visit', parent_module=m1) factory.form_requires_case(m2f0, 'child') # link to child -> edit child m2f0.post_form_workflow = WORKFLOW_FORM m2f0.form_links = [ FormLink(xpath="true()", form_id=m1f0.unique_id), ] self.assertXmlPartialEqual(self.get_xml('form_link_child_modules'), factory.app.create_suite(), "./entry[3]")
def test_form_linking_multiple_case_types_child_module(): factory = AppFactory(build_version='2.9.0') m0, m0f0 = factory.new_basic_module('register', 'jelly_baby') factory.form_opens_case(m0f0) m1, m1f0 = factory.new_basic_module('eat', 'jelly_baby') factory.form_requires_case(m1f0) factory.form_opens_case(m1f0, case_type='taste', is_subcase=True) m1.search_config.additional_case_types = ['liquorice'] m2, m2f0 = factory.new_basic_module('taste history', 'taste', parent_module=m1) factory.form_requires_case(m2f0, 'taste', parent_case_type='jelly_baby') m2.search_config.additional_case_types = ['smell'] m1f0.post_form_workflow = WORKFLOW_FORM m1f0.form_links = [ FormLink(form_id=m2f0.unique_id), ] suite = factory.app.create_suite() print(suite.decode('utf8')) expected_stack = """ <partial> <create> <command value="'m1'"/> <datum id="case_id" value="instance('commcaresession')/session/data/case_id"/> <datum id="case_id_new_taste_0" value="uuid()"/> <command value="'m2'"/> <datum id="case_id_taste" value="instance('commcaresession')/session/data/case_id_new_taste_0"/> <command value="'m2-f0'"/> </create> </partial>""" assert_xml_partial_equal(expected_stack, suite, "./entry[2]/stack/create")
def _edit_form_attr(request, domain, app_id, form_unique_id, attr): """ Called to edit any (supported) form attribute, given by attr """ ajax = json.loads(request.POST.get('ajax', 'true')) resp = {} app = get_app(domain, app_id) try: form = app.get_form(form_unique_id) except FormNotFoundException as e: if ajax: return HttpResponseBadRequest(str(e)) else: messages.error(request, _("There was an error saving, please try again!")) return back_to_main(request, domain, app_id=app_id) lang = request.COOKIES.get('lang', app.langs[0]) def should_edit(attribute): return attribute in request.POST if 'sha1' in request.POST and (should_edit("xform") or "xform" in request.FILES): conflict = _get_xform_conflict_response(form, request.POST['sha1']) if conflict is not None: return conflict if should_edit("name"): name = request.POST['name'] form.name[lang] = name if not form.form_type == "shadow_form": xform = form.wrapped_xform() if xform.exists(): xform.set_name(name) save_xform(app, form, xform.render()) resp['update'] = {'.variable-form_name': clean_trans(form.name, [lang])} if should_edit('comment'): form.comment = request.POST['comment'] if should_edit("xform") or "xform" in request.FILES: try: # support FILES for upload and POST for ajax post from Vellum try: xform = request.FILES.get('xform').read() except Exception: xform = request.POST.get('xform') else: try: xform = str(xform, encoding="utf-8") except Exception: raise Exception("Error uploading form: Please make sure your form is encoded in UTF-8") if request.POST.get('cleanup', False): try: # First, we strip all newlines and reformat the DOM. px = parseString(xform.replace('\r\n', '')).toprettyxml() # Then we remove excess newlines from the DOM output. text_re = re.compile(r'>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL) prettyXml = text_re.sub(r'>\g<1></', px) xform = prettyXml except Exception: pass if xform: if isinstance(xform, str): xform = xform.encode('utf-8') save_xform(app, form, xform) else: raise Exception("You didn't select a form to upload") except Exception as e: notify_exception(request, str(e)) if ajax: return HttpResponseBadRequest(str(e)) else: messages.error(request, str(e)) if should_edit("references") or should_edit("case_references"): form.case_references = _get_case_references(request.POST) if should_edit("show_count"): show_count = request.POST['show_count'] form.show_count = True if show_count == "True" else False if should_edit("put_in_root"): put_in_root = request.POST['put_in_root'] form.put_in_root = True if put_in_root == "True" else False if should_edit('form_filter'): form.form_filter = request.POST['form_filter'] if should_edit('post_form_workflow'): form.post_form_workflow = request.POST['post_form_workflow'] if should_edit('auto_gps_capture'): form.auto_gps_capture = request.POST['auto_gps_capture'] == 'true' if should_edit('is_release_notes_form'): form.is_release_notes_form = request.POST['is_release_notes_form'] == 'true' if should_edit('enable_release_notes'): form.enable_release_notes = request.POST['enable_release_notes'] == 'true' if not form.is_release_notes_form and form.enable_release_notes: return json_response( {'message': _("You can't enable a form as release notes without allowing it as " "a release notes form <TODO messaging>")}, status_code=400 ) if (should_edit("form_links_xpath_expressions") and should_edit("form_links_form_ids") and toggles.FORM_LINK_WORKFLOW.enabled(domain)): form_links = zip( request.POST.getlist('form_links_xpath_expressions'), request.POST.getlist('form_links_form_ids'), [ json.loads(datum_json) if datum_json else [] for datum_json in request.POST.getlist('datums_json') ], ) module_unique_ids = [m.unique_id for m in app.get_modules()] form.form_links = [FormLink( xpath=link[0], form_id=link[1] if link[1] not in module_unique_ids else None, module_unique_id=link[1] if link[1] in module_unique_ids else None, datums=[ FormDatum(name=datum['name'], xpath=datum['xpath']) for datum in link[2] ] ) for link in form_links] if should_edit('post_form_workflow_fallback'): form.post_form_workflow_fallback = request.POST.get('post_form_workflow_fallback') if should_edit('custom_instances'): instances = json.loads(request.POST.get('custom_instances')) try: # validate that custom instances can be added into the XML for instance in instances: etree.fromstring( "<instance id='{}' src='{}' />".format( instance.get('instanceId'), instance.get('instancePath') ) ) except etree.XMLSyntaxError as error: return json_response( {'message': _("There was an issue with your custom instances: {}").format(error)}, status_code=400 ) form.custom_instances = [ CustomInstance( instance_id=instance.get("instanceId"), instance_path=instance.get("instancePath"), ) for instance in instances ] if should_edit('custom_assertions'): assertions = json.loads(request.POST.get('custom_assertions')) try: # validate that custom assertions can be added into the XML for assertion in assertions: etree.fromstring( '<assertion test="{test}"><text><locale id="abc.def"/>{text}</text></assertion>'.format( **assertion ) ) except etree.XMLSyntaxError as error: return json_response( {'message': _("There was an issue with your custom assertions: {}").format(error)}, status_code=400 ) existing_assertions = {assertion.test: assertion for assertion in form.custom_assertions} new_assertions = [] for assertion in assertions: try: new_assertion = existing_assertions[assertion.get('test')] new_assertion.text[lang] = assertion.get('text') except KeyError: new_assertion = CustomAssertion( test=assertion.get('test'), text={lang: assertion.get('text')} ) new_assertions.append(new_assertion) form.custom_assertions = new_assertions if should_edit("shadow_parent"): form.shadow_parent_form_id = request.POST['shadow_parent'] if should_edit("custom_icon_form"): error_message = handle_custom_icon_edits(request, form, lang) if error_message: return json_response( {'message': error_message}, status_code=400 ) if should_edit('session_endpoint_id'): raw_endpoint_id = request.POST['session_endpoint_id'] try: set_session_endpoint(form, raw_endpoint_id, app) except InvalidSessionEndpoint as e: return json_response({'message': str(e)}, status_code=400) if should_edit('function_datum_endpoints'): if request.POST['function_datum_endpoints']: form.function_datum_endpoints = request.POST['function_datum_endpoints'].replace(" ", "").split(",") else: form.function_datum_endpoints = [] handle_media_edits(request, form, should_edit, resp, lang) app.save(resp) notify_form_changed(domain, request.couch_user, app_id, form_unique_id) if ajax: return HttpResponse(json.dumps(resp)) else: return back_to_main(request, domain, app_id=app_id, form_unique_id=form_unique_id)
def _edit_form_attr(request, domain, app_id, form_unique_id, attr): """ Called to edit any (supported) form attribute, given by attr """ ajax = json.loads(request.POST.get('ajax', 'true')) resp = {} app = get_app(domain, app_id) try: form = app.get_form(form_unique_id) except FormNotFoundException as e: if ajax: return HttpResponseBadRequest(unicode(e)) else: messages.error(request, _("There was an error saving, please try again!")) return back_to_main(request, domain, app_id=app_id) lang = request.COOKIES.get('lang', app.langs[0]) def should_edit(attribute): return attribute in request.POST if should_edit("name"): name = request.POST['name'] form.name[lang] = name if not form.form_type == "shadow_form": xform = form.wrapped_xform() if xform.exists(): xform.set_name(name) save_xform(app, form, xform.render()) resp['update'] = { '.variable-form_name': trans(form.name, [lang], use_delim=False) } if should_edit('comment'): form.comment = request.POST['comment'] if should_edit("xform") or "xform" in request.FILES: try: # support FILES for upload and POST for ajax post from Vellum try: xform = request.FILES.get('xform').read() except Exception: xform = request.POST.get('xform') else: try: xform = unicode(xform, encoding="utf-8") except Exception: raise Exception( "Error uploading form: Please make sure your form is encoded in UTF-8" ) if request.POST.get('cleanup', False): try: # First, we strip all newlines and reformat the DOM. px = parseString(xform.replace('\r\n', '')).toprettyxml() # Then we remove excess newlines from the DOM output. text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL) prettyXml = text_re.sub('>\g<1></', px) xform = prettyXml except Exception: pass if xform: save_xform(app, form, xform) else: raise Exception("You didn't select a form to upload") except Exception as e: if ajax: return HttpResponseBadRequest(unicode(e)) else: messages.error(request, unicode(e)) if should_edit("references") or should_edit("case_references"): form.case_references = _get_case_references(request.POST) if should_edit("show_count"): show_count = request.POST['show_count'] form.show_count = True if show_count == "True" else False if should_edit("put_in_root"): put_in_root = request.POST['put_in_root'] form.put_in_root = True if put_in_root == "True" else False if should_edit('form_filter'): form.form_filter = request.POST['form_filter'] if should_edit('post_form_workflow'): form.post_form_workflow = request.POST['post_form_workflow'] if should_edit('auto_gps_capture'): form.auto_gps_capture = request.POST['auto_gps_capture'] == 'true' if should_edit('no_vellum'): form.no_vellum = request.POST['no_vellum'] == 'true' if (should_edit("form_links_xpath_expressions") and should_edit("form_links_form_ids") and toggles.FORM_LINK_WORKFLOW.enabled(domain)): form_links = zip( request.POST.getlist('form_links_xpath_expressions'), request.POST.getlist('form_links_form_ids'), [ json.loads(datum_json) if datum_json else [] for datum_json in request.POST.getlist('datums_json') ], ) form.form_links = [ FormLink(xpath=link[0], form_id=link[1], datums=[ FormDatum(name=datum['name'], xpath=datum['xpath']) for datum in link[2] ]) for link in form_links ] if should_edit('post_form_workflow_fallback'): form.post_form_workflow_fallback = request.POST.get( 'post_form_workflow_fallback') if should_edit('custom_instances'): instances = json.loads(request.POST.get('custom_instances')) try: # validate that custom instances can be added into the XML for instance in instances: etree.fromstring("<instance id='{}' src='{}' />".format( instance.get('instanceId'), instance.get('instancePath'))) except etree.XMLSyntaxError as error: return json_response( { 'message': _("There was an issue with your custom instances: {}"). format(error.message) }, status_code=400) form.custom_instances = [ CustomInstance( instance_id=instance.get("instanceId"), instance_path=instance.get("instancePath"), ) for instance in instances ] if should_edit("shadow_parent"): form.shadow_parent_form_id = request.POST['shadow_parent'] if should_edit("custom_icon_form"): error_message = handle_custom_icon_edits(request, form, lang) if error_message: return json_response({'message': error_message}, status_code=400) handle_media_edits(request, form, should_edit, resp, lang) app.save(resp) notify_form_changed(domain, request.couch_user, app_id, form_unique_id) if ajax: return HttpResponse(json.dumps(resp)) else: return back_to_main(request, domain, app_id=app_id, form_unique_id=form_unique_id)
form.no_vellum = request.POST['no_vellum'] == 'true' if (should_edit("form_links_xpath_expressions") and should_edit("form_links_form_ids") and toggles.FORM_LINK_WORKFLOW.enabled(domain)): form_links = zip( request.POST.getlist('form_links_xpath_expressions'), request.POST.getlist('form_links_form_ids'), [ json.loads(datum_json) if datum_json else [] for datum_json in request.POST.getlist('datums_json') ], ) form.form_links = [FormLink( xpath=link[0], form_id=link[1], datums=[ FormDatum(name=datum['name'], xpath=datum['xpath']) for datum in link[2] ] ) for link in form_links] handle_media_edits(request, form, should_edit, resp, lang) app.save(resp) notify_form_changed(domain, request.couch_user, app_id, unique_form_id) if ajax: return HttpResponse(json.dumps(resp)) else: return back_to_main(request, domain, app_id=app_id, unique_form_id=unique_form_id) @no_conflict_require_POST