def test_replace_session_references_in_stack(self): children = [ CommandId('m0'), StackDatum(id='a', value=session_var('new_a')), StackDatum(id='b', value=session_var('new_b')), StackDatum( id='c', value="instance('casedb')/case/[@case_id = {a}]/index/parent". format(a=session_var('a'))), StackDatum(id='d', value="if({c}, {c}, {a}]".format(a=session_var('a'), c=session_var('c'))) ] clean = _replace_session_references_in_stack(children) clean_raw = [] for child in clean: if isinstance(child, CommandId): clean_raw.append(child.id) else: clean_raw.append((child.id, child.value)) new_c = "instance('casedb')/case/[@case_id = {a}]/index/parent".format( a=session_var('new_a')) self.assertEqual(clean_raw, [ 'm0', ('a', session_var('new_a')), ('b', session_var('new_b')), ('c', new_c), ('d', "if({c}, {c}, {a}]".format(a=session_var('new_a'), c=new_c)) ])
def _get_reg_form_action(self, module): """ Returns registration form action """ form = self.app.get_form(module.case_list_form.form_id) if self.app.enable_localized_menu_media: case_list_form = module.case_list_form action = LocalizedAction( menu_locale_id=id_strings.case_list_form_locale(module), media_image=case_list_form.uses_image( build_profile_id=self.build_profile_id), media_audio=case_list_form.uses_audio( build_profile_id=self.build_profile_id), image_locale_id=id_strings.case_list_form_icon_locale(module), audio_locale_id=id_strings.case_list_form_audio_locale(module), stack=Stack(), for_action_menu=True, ) else: action = Action(display=Display( text=Text(locale_id=id_strings.case_list_form_locale(module)), media_image=module.case_list_form.default_media_image, media_audio=module.case_list_form.default_media_audio, ), stack=Stack()) frame = PushFrame() frame.add_command(XPath.string(id_strings.form_command(form))) target_form_dm = self.entries_helper.get_datums_meta_for_form_generic( form) source_form_dm = [] if len(module.forms): source_form_dm = self.entries_helper.get_datums_meta_for_form_generic( module.get_form(0)) for target_meta in target_form_dm: if target_meta.requires_selection: # This is true for registration forms where the case being created is a subcase try: [source_dm] = [ source_meta for source_meta in source_form_dm if source_meta.case_type == target_meta.case_type ] except ValueError: pass else: frame.add_datum( StackDatum(id=target_meta.datum.id, value=session_var(source_dm.datum.id))) else: s_datum = target_meta.datum frame.add_datum( StackDatum(id=s_datum.id, value=s_datum.function)) frame.add_datum( StackDatum(id=RETURN_TO, value=XPath.string(id_strings.menu_id(module)))) action.stack.add_frame(frame) return action
def _replace_session_references_in_stack(stack_children, current_session=None): """Given a list of stack children (commands and datums) replace any references in the datum to session variables that have already been added to the session. e.g. <datum id="case_id_a" value="instance('commcaresession')/session/data/case_id_new_a"/> <datum id="case_id_b" value="instance('commcaresession')/session/data/case_id_a"/> ^^^^^^^^^ In the second datum replace ``case_id_a`` with ``case_id_new_a``. We have to do this because stack create blocks do not update the session after each datum is added so items put into the session in one step aren't available to later steps. """ current_session_vars = [datum.id for datum in current_session ] if current_session else [] clean_children = [] child_map = {} for child in stack_children: if not isinstance(child, StackDatum): clean_children.append(child) continue session_vars = session_var_regex.findall(child.value) new_value = child.value for var in session_vars: if var in child_map and var not in current_session_vars: new_value = new_value.replace(session_var(var), child_map[var]) child_map[child.id] = new_value clean_children.append(StackDatum(id=child.id, value=new_value)) return clean_children
def get_datums_matched_to_manual_values(target_frame_elements, manual_values): """ Attempt to match the target session variables with ones that the user has entered manually """ manual_values_by_name = {datum.name: datum.xpath for datum in manual_values} for child in target_frame_elements: if not isinstance(child, WorkflowDatumMeta) or not child.requires_selection: yield child else: manual_value = manual_values_by_name.get(child.id) if manual_value: yield StackDatum(id=child.id, value=manual_value) else: raise SuiteValidationError("Unable to link forms, missing form variable: {}".format( child.id ))
def _make_session_endpoint(self, id_string, module, endpoint_id): stack = Stack() frame = PushFrame() stack.add_frame(frame) frame.add_command(XPath.string(id_string)) arguments = [] helper = WorkflowHelper(self.suite, self.app, self.modules) for child in helper.get_frame_children(id_string, module): if isinstance(child, WorkflowDatumMeta): arguments.append(Argument(id=child.id)) frame.add_datum(StackDatum(id=child.id, value=f"${child.id}")) return SessionEndpoint( id=endpoint_id, arguments=arguments, stack=stack, )
def get_module_contributions(self, module): if module_offers_search(module): domain = self.app.domain details_helper = DetailsHelper(self.app) remote_request = RemoteRequest( post=RemoteRequestPost( url=absolute_reverse('claim_case', args=[domain]), relevant=module.search_config.relevant, data=[ QueryData( key='case_id', ref=QuerySessionXPath('case_id').instance(), # e.g. instance('querysession')/session/data/case_id ), ]), command=Command( id=id_strings.search_command(module), display=Display(text=Text( locale_id=id_strings.case_search_locale(module)), ), ), instances=[ Instance(id=SESSION_INSTANCE, src='jr://instance/session'), Instance(id='casedb', src='jr://instance/casedb'), ], session=RemoteRequestSession( queries=[ RemoteRequestQuery( url=absolute_reverse('remote_search', args=[domain]), storage_instance=RESULTS_INSTANCE, data=[ QueryData(key='case_type', ref="'{}'".format(module.case_type)), ], prompts=[ QueryPrompt( key=p.name, display=Display( text=Text(locale_id=id_strings. search_property_locale( module, p.name)), ), ) for p in module.search_config.properties ]) ], data=[ SessionDatum( id='case_id', nodeset=(CaseTypeXpath(module.case_type).case( instance_name=RESULTS_INSTANCE).select( u'@status', u'open', quote=True)), value='./@case_id', detail_select=details_helper.get_detail_id_safe( module, 'case_short'), detail_confirm=details_helper.get_detail_id_safe( module, 'case_long'), ) ], ), stack=Stack(), ) frame = CreateFrame() # Open first form in module frame.add_command(XPath.string(id_strings.menu_id(module))) frame.add_datum( StackDatum(id='case_id', value=QuerySessionXPath('case_id').instance())) remote_request.stack.add_frame(frame) return [remote_request] return []
def to_stack_datum(self): value = session_var( self.source_id) if self.requires_selection else self.function return StackDatum(id=self.id, value=value)
def _add_datum_for_arg(self, frame, arg_id): frame.add_datum( StackDatum(id=arg_id, value=f"${arg_id}") )