问题
When I transit from view state to decision state or action state all the input set is lost while transitioning to another state. How to do I get the flow scope variable for decision state or action state on transitioning from view state to decision state and action state in junit ?
In my flow definition right now I am in view state when I set the event Id as submit it moves to registerEnroll decision state where it needs flowScope.regform.loyaltyLookUp
value. When I see the flow execution variable map there is nothing inside apart from RegForm object, even though I have set variable in MutableAttributeMap
.
How to set the flow scope variable which will be always available on transitioning to state on junit test case for spring webflow?
In second test case flow is going to else part of decision state even though I have provide flowScope.regform.loyaltyLookUp
in input. What mistake I am doing I am not able to figure out .
xml
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.4.xsd"
start-state="confirmsuccess">
<var name="regform" class="com.shc.ecom.usr.form.Regform" />
<var name="enrollresponse" class="com.shc.ecom.usr.service.adapter.ResponseVO" />
<!-- <input-mapper> <input-attribute name="service" /> <input-attribute
name="regform" /> <input-attribute name="success" /> </input-mapper> <start-state
idref="confirmsuccess" /> -->
<input name="service" />
<input name="regform" />
<input name="success" />
<input name="enrollresponse"/>
<decision-state id="confirmsuccess">
<if test="flowScope.success!=null" then="serviceticketvalidation"
else="saveQueryParamInSession" />
</decision-state>
<decision-state id="serviceticketvalidation">
<if test="flowScope.success=='yes'" then="sywNumAction" else="ssoerrorredirect" />
</decision-state>
<!-- <action-state id="enterCustInfo"> <action bean="regEnrollFormAction"
method="setupForm" > </action> <transition on="success" to="renderform"/>
</action-state> -->
<!-- save query parameter in session -->
<action-state id="saveQueryParamInSession">
<evaluate expression="saveQueryParamInSession.doExecute(flowRequestContext)" />
<transition on="success" to="renderform" />
</action-state>
<view-state id="renderform" view="/regenroll" >
<on-entry>
<evaluate expression="regEnrollFormAction.setupForm(flowRequestContext)" />
<set name="flowScope.sourceSite" value="requestParameters.sid" /> <!-- scope="flow" -->
<set name="flowScope.service" value="requestParameters.service" />
<set name="flowScope.clienthost" value="requestParameters.clienthost" />
<set name="flowScope.target" value="requestParameters.target" />
<set name="flowScope.switchForm" value="requestParameters.switchForm" />
<set name="flowScope.oldlogin" value="requestParameters.oldlogin" />
<set name="flowScope.emailId" value="requestParameters.emailId" />
<set name="flowScope.confirmEmail" value="requestParameters.emailConfirm" />
<set name="flowScope.fname" value="requestParameters.fname" />
<set name="flowScope.lname" value="requestParameters.lname" />
<set name="flowScope.zipCode" value="requestParameters.zip" />
<set name="flowScope.modifyservice" value="requestParameters.modifyservice" />
<set name="flowScope.ocpPage" value="requestParameters.ocpPage" />
<set name="flowScope.fullpage" value="requestParameters.fullpage" />
<set name="flowScope.emailValidateFlag" value="requestParameters.emailValidateFlag" />
<set name="flowScope.mode" value="requestParameters.mode" />
<set name="flowScope.phone" value="requestParameters.phone" />
<set name="flowScope.number" value="requestParameters.number" />
<set name="flowScope.irp" value="requestParameters.irp" />
<set name="flowScope.sywmax" value="requestParameters.sywmax" />
</on-entry>
<transition on="submit" to="registerEnroll">
<evaluate expression="regEnrollFormAction.bindAndValidate(flowRequestContext)"></evaluate>
</transition>
</view-state>
<decision-state id="registerEnroll">
<if test="flowScope.regform.loyaltyLookUp!=null" then="processEnroll"
else="activateEnroll" />
</decision-state>
<action-state id="processEnroll">
<evaluate
expression="ssoGatewayService.register(flowScope.regform,externalContext)" result="flowScope.enrollresponse" result-type="com.shc.ecom.usr.service.adapter.ResponseVO" />
<transition on="success" to="postenroll" />
</action-state>
<decision-state id="postenroll">
<if test="flowScope.enrollresponse.responseCode ==200" then="ccenroll"
else="enrollerror" />
</decision-state>
<decision-state id="ccenroll">
<if test="flowScope.regform.craftsmanAffinity!=null" then="ccAffinityUpdate"
else="go_to_login_flow" />
</decision-state>
<action-state id="ccAffinityUpdate">
<evaluate
expression="ssoGatewayService.updateCCAffinity(flowScope.regform, flowScope.enrollresponse)"
result="enrollresponse" />
<transition on="success" to="postccupdate" />
</action-state>
<decision-state id="postccupdate">
<if test="flowScope.enrollresponse.responseCode==200" then="go_to_login_flow"
else="ccupdateerror" />
</decision-state>
<decision-state id="enrollerror">
<if test="flowScope.enrollresponse.existingUserInd!=null" then="existingUserLogin"
else="captchaValidation" />
</decision-state>
<decision-state id="captchaValidation">
<if test="flowScope.enrollresponse.errorCode eq '401.1'" then="captchaValidationError"
else="loyaltydown" />
</decision-state>
<decision-state id="loyaltydown">
<if test="flowScope.enrollresponse.loyaltyDown!=null" then="loyaltydownerror"
else="showerror" />
</decision-state>
<action-state id="activateEnroll">
<evaluate expression="ssoGatewayService.onlineActivation(flowScope.regform, requestParameters.clienthost,
externalContext, requestParameters.mode, requestParameters.number, requestParameters.phone)"
result = "enrollresponse" />
<transition on="success" to="postenroll" />
</action-state>
<subflow-state id="go_to_login_flow" subflow="shclogin-flow">
<input value="flowScope.regform.password" name="logonPassword"/>
<input value="flowScope.regform.email" name="loginId"/>
<input value="flowScope.regform.sid" name="sourceSiteId"/>
<input value="flowScope.regform.service" name="service"/>
<input value="flowScope.regform.redirectUrl" name="redirectUrl"/>
<input value="flowScope.reglogin" name="reglogin"/>
<input value="flowScope.enrollresponse" name="enrollresponse"/>
<transition on="finish" to="process_and_redirect" />
<transition on="redirect" to="process_and_redirect" />
<transition on="sendtickettomodal_reg" to="sendtickettomodal">
<set name="clienthost" value="requestParameters.clienthost" /> <!-- scope="flow" -->
</transition>
<transition on="pickup_error_redirect_reg" to="ssoerrorredirect" />
<transition on="pickup_error_redirect_login" to="ssoerrorredirect" />
</subflow-state>
<!--
<attribute-mapper>
<input-mapper>
<mapping source="${flowScope.regform.email}" target="loginId" />
<mapping source="${flowScope.regform.password}" target="logonPassword" />
<mapping source="${flowScope.regform.sid}" target="sourceSiteId" />
<mapping source="${flowScope.regform.service}" target="service" />
<mapping source="${flowScope.regform.redirectUrl}" target="redirectUrl" />
<mapping source="${flowScope.reglogin}" target="reglogin" />
<mapping source="${flowScope.enrollresponse}" target="enrollresponse" />
</input-mapper>
</attribute-mapper>
-->
<action-state id="sywNumAction">
<evaluate expression="sywNumSetupAction" />
<transition on="success" to="process_and_redirect" />
</action-state>
<end-state id="process_and_redirect" view="/successconfirmation">
<on-entry>
<set name="sourceSiteId" value="flowScope.regform.sid" />
<set name="sywrNumber" value="flowScope.sywrNumber" />
<set name ="softLinkFlow" value="requestParameters.softLinkFlow" />
<set name ="fullpage" value="requestParameters.fullpage" />
<set name="targetUrl" value="requestParameters.targetUrl" />
</on-entry>
</end-state>
<view-state id="showerror" view="/displayerror">
<on-entry>
<set name="errorCode" value="flowScope.enrollresponse.responseCode" />
<set name="responseString" value="flowScope.enrollresponse.responseString" />
</on-entry>
</view-state>
<view-state id="captchaValidationError" view="/displayerror">
<on-entry>
<set name="errorCode" value="401.1" />
<set name="responseString" value="flowScope.enrollresponse.errorDescription" />
</on-entry>
</view-state>
<view-state id="loyaltydownerror" view="/displayerror">
<on-entry>
<set name="errorCode" value="500.2" />
<set name="responseString" value="flowScope.enrollresponse.responseString" />
</on-entry>
</view-state>
<end-state id="existingUserLogin" view="/existingUserLogin">
<on-entry>
<set name="returnCode" value="'500.110'" />
<set name="clienthost" value="requestParameters.clienthost" />
<set name="emailId" value="flowScope.regform.email" />
</on-entry>
</end-state>
<view-state id="ccupdateerror" view="/ccEnrollError">
<on-entry>
<set name="returnCode" value="'500.111'" />
<set name="clienthost" value="requestParameters.clienthost" />
<set name="emailId" value="flowScope.regform.email" />
</on-entry>
</view-state>
<!-- redirect the next step from login flow -->
<end-state id="ssoerrorredirect" view="/successconfirmationwithssoerror">
<on-entry>
<set name="sourceSiteId" value="flowScope.regform.sid" />
<set name="sywrNumber" value="flowScope.sywrNumber" />
<set name="softLinkFlow" value="requestParameters.softLinkFlow" />
<set name="fullpage" value="requestParameters.fullpage" />
</on-entry>
</end-state>
<!-- adding sywmax parameter for registration flow -->
<end-state id="sendtickettomodal" view="/displayserviceticketandcookie">
<output value="requestScope.syw" name="sywmax"/>
</end-state>
<!--
<output-mapper>
<mapping source="${requestScope.syw" x } target="sywmax" />
</output-mapper>
-->
<global-transitions>
<transition to="showerror"
on-exception="org.springframework.webflow.execution.repository.NoSuchFlowExecutionException" />
<transition to="showerror"
on-exception="org.jasig.cas.services.UnauthorizedSsoServiceException" />
<transition to="showerror"
on-exception="org.jasig.cas.services.UnauthorizedServiceException" />
<transition to="showerror"
on-exception="org.springframework.webflow.execution.FlowExecutionException" />
</global-transitions>
<!-- <bean-import resource="regenroll-beans.xml" /> -->
</flow>
Test case
Second Test is failing
public class TestRegEnrollFlow extends AbstractXmlFlowExecutionTests {
SavingQueryParamInSessionAction saveQueryParamInSession;
SSOGatewayServiceImpl ssoGatewayService;
@Override
protected FlowDefinitionResource getResource(FlowDefinitionResourceFactory resourceFactory) {
return resourceFactory.createFileResource("src/main/webapp/WEB-INF/usr/flows/regEnroll-flow.xml");
}
@Override
protected void configureFlowBuilderContext(MockFlowBuilderContext builderContext) {
// I Have tried even mocking using Easy Mock
saveQueryParamInSession = EasyMock.createMock("saveQueryParamInSession", SavingQueryParamInSessionAction.class);
ssoGatewayService = EasyMock.createMock("ssoGatewayService", SSOGatewayServiceImpl.class);
builderContext.registerBean("saveQueryParamInSession", saveQueryParamInSession);
builderContext.registerBean("sywNumSetupAction", new SywNumSetupAction());
builderContext.registerBean("ssoGatewayService", ssoGatewayService);
builderContext.registerBean("regEnrollFormAction", new RegEnrollFormAction());
}
public void testAction() {
MockExternalContext ctx = new MockExternalContext();
MutableAttributeMap input = new LocalAttributeMap();
input.put("service", "");
input.put("regform", createRegistrationForm());
// this is the line where we are changing the state flow
input.put("success", null);
input.put("externalContext", ctx);
input.put("enrollresponse.responseCode", 200);
input.put("regform.craftsmanAffinity", "any");
startFlow(input, ctx);
assertFlowExecutionActive();
assertCurrentStateEquals("renderform");
assertResponseWrittenEquals("/regenroll", ctx);
}
public void testREgForm() throws Exception {
setCurrentState("renderform");
MockExternalContext context = new MockExternalContext();
context.putRequestParameter("sid", "3");
context.putRequestParameter("service", "qa.ecom.s.com:4380");
context.putRequestParameter("clienthost", "qa.ecom.s.com:4380");
context.putRequestParameter("target", "http://qa.ecom.sears.com:4380/?storeId=10153&catalogId=12605");
context.putRequestParameter("switchForm", "Donald");
context.putRequestParameter("oldlogin", "Donald");
context.putRequestParameter("emailId", "jadiya@gmail.com");
context.putRequestParameter("emailConfirm", "jadiya@gmail.com");
context.putRequestParameter("fname", "Ankur");
context.putRequestParameter("lname", "Jadiya");
context.putRequestParameter("zip", "56005");
context.putRequestParameter("modifyservice", "no");
context.putRequestParameter("ocpPage", "no");
context.putRequestParameter("fullpage", "no");
context.putRequestParameter("emailValidateFlag", "true");
context.putRequestParameter("mode", "active");
context.putRequestParameter("phone", "8884911391");
context.putRequestParameter("number", "883427");
context.putRequestParameter("irp", "true");
context.putRequestParameter("sywmax", "1234567");
context.putRequestParameter("enrollresponse.responseCode","200");
FlowExecution flowExecution = getFlowExecution();
FlowSession session = flowExecution.getActiveSession();
//flowExecution.getConversationScope().put("flowScope.enrollresponse.responseCode", 200);
session.getScope().put("flowScope.regform.loyaltyLookUp", true);
//session.getScope().put("flowScope.enrollresponse.responseCode", "200");
// session.getScope().put("flowScope.enrollresponse", 200);
//session.getScope().put("responseCode", 200);
session.getScope().put("flowScope.regform.craftsmanAffinity", "check");
/*session.getScope().put("enrollresponse.responseCode", 200);*/
// session..put("flowScope.enrollresponse.responseCode", 200);
updateFlowExecution(flowExecution);
ResponseVO value = new ResponseVO(200, "success");
session.getScope().put("enrollresponse", value);
session.getScope().put("flowScope.enrollresponse.responseCode", value);
context.setEventId("submit");
// EasyMock.expect(ssoGatewayService.register(createRegistrationForm(), context)).andReturn(value);
flowExecution.resume(context);
assertCurrentStateEquals("showerror");
}
private Regform createRegistrationForm() {
Regform regform = new Regform();
regform.setEmail("20130410111@gmail.com");
regform.setLname("mike");
regform.setFname("sun");
regform.setPassword("test11");
regform.setSid("3");
regform.setZip("60179");
regform.setLoyaltyLookUp(true);
return regform;
}
}
Error
Caused by: org.springframework.binding.expression.PropertyNotFoundException: Property not found
at org.springframework.binding.expression.spel.SpringELExpression.setValue(SpringELExpression.java:117)
at org.springframework.webflow.action.EvaluateAction.doExecute(EvaluateAction.java:80)
at org.springframework.webflow.action.AbstractAction.execute(AbstractAction.java:188)
at org.springframework.webflow.execution.AnnotatedAction.execute(AnnotatedAction.java:145)
at org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:51)
... 36 more
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1010E:(pos 0): Property or field 'enrollresponse' cannot be set on object of type 'org.springframework.webflow.engine.impl.RequestControlContextImpl' - maybe not public?
at org.springframework.expression.spel.ast.PropertyOrFieldReference.writeProperty(PropertyOrFieldReference.java:270)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.setValue(PropertyOrFieldReference.java:159)
at org.springframework.expression.spel.standard.SpelExpression.setValue(SpelExpression.java:411)
at org.springframework.binding.expression.spel.SpringELExpression.setValue(SpringELExpression.java:114)
... 40 more
回答1:
you are setting this property:
input.put("enrollresponse.responseCode", "200");
but:
- I don't see it anywhere in your flow (maybe in the part you omitted)
- You have to first create the enrollresponse object before setting "responseCode" on it. I think that is causing the error you are having
[EDIT]
you also need to specify the scope for variable in
<set>
element (showrror state). replace:<set name="errorCode" value="flowScope.enrollresponse.responseCode" />
by
<set name="viewScope.errorCode" value="flowScope.enrollresponse.responseCode" />
fix all those issues and try again
来源:https://stackoverflow.com/questions/39010531/not-able-to-get-the-flow-scope-variable-from-one-state-transition-to-another-sta