Package org.springframework.webflow.engine

Source Code of org.springframework.webflow.engine.FlowTests

/*
* Copyright 2004-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.webflow.engine;

import java.util.ArrayList;

import junit.framework.TestCase;

import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.binding.expression.support.FluentParserContext;
import org.springframework.binding.mapping.impl.DefaultMapper;
import org.springframework.binding.mapping.impl.DefaultMapping;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.webflow.TestException;
import org.springframework.webflow.action.TestMultiAction;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.engine.support.DefaultTargetStateResolver;
import org.springframework.webflow.engine.support.MockTransitionCriteria;
import org.springframework.webflow.engine.support.TransitionExecutingFlowExecutionExceptionHandler;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.FlowExecutionException;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.TestAction;
import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
import org.springframework.webflow.test.MockRequestControlContext;

/**
* Unit test for the Flow class.
*
* @author Keith Donald
*/
public class FlowTests extends TestCase {

  private Flow flow = createSimpleFlow();

  private Flow createSimpleFlow() {
    flow = new Flow("myFlow");
    ViewState state1 = new ViewState(flow, "myState1", new StubViewFactory());
    state1.getTransitionSet().add(new Transition(on("submit"), to("myState2")));
    new EndState(flow, "myState2");
    flow.getGlobalTransitionSet().add(new Transition(on("globalEvent"), to("myState2")));
    return flow;
  }

  public void testAddStates() {
    Flow flow = new Flow("myFlow");
    new EndState(flow, "myState1");
    new EndState(flow, "myState2");
    assertEquals("Wrong start state:", "myState1", flow.getStartState().getId());
    assertEquals("State count wrong:", 2, flow.getStateCount());
    assertTrue(flow.containsState("myState1"));
    assertTrue(flow.containsState("myState2"));
    State state = flow.getStateInstance("myState1");
    assertEquals("Wrong flow:", flow.getId(), state.getFlow().getId());
    assertEquals("Wrong state:", "myState1", flow.getState("myState1").getId());
    assertEquals("Wrong state:", "myState2", flow.getState("myState2").getId());
  }

  public void testAddDuplicateState() {
    Flow flow = new Flow("myFlow");
    new EndState(flow, "myState1");
    try {
      new EndState(flow, "myState1");
      fail("Duplicate state added");
    } catch (IllegalArgumentException e) {
      // expected
    }
  }

  public void testAddSameStateTwice() {
    Flow flow = new Flow("myFlow");
    EndState state = new EndState(flow, "myState1");
    try {
      flow.add(state);
      fail("Should have failed");
    } catch (IllegalArgumentException e) {

    }
    assertEquals("State count wrong:", 1, flow.getStateCount());
  }

  public void testAddStateAlreadyInOtherFlow() {
    Flow otherFlow = new Flow("myOtherFlow");
    State state = new EndState(otherFlow, "myState1");
    Flow flow = new Flow("myFlow");
    try {
      flow.add(state);
      fail("Added state part of another flow");
    } catch (IllegalArgumentException e) {
      // expected
    }
  }

  public void testGetStateNoStartState() {
    Flow flow = new Flow("myFlow");
    try {
      flow.getStartState();
      fail("Retrieved start state when no such state");
    } catch (IllegalStateException e) {
      // expected
    }
  }

  public void testGetStateNoSuchState() {
    try {
      flow.getState("myState3");
      fail("Returned a state that doesn't exist");
    } catch (IllegalArgumentException e) {
      // expected
    }
  }

  public void testGetTransitionableState() {
    assertEquals("Wrong state:", "myState1", flow.getTransitionableState("myState1").getId());
    assertEquals("Wrong state:", "myState1", flow.getState("myState1").getId());
  }

  public void testGetStateNoSuchTransitionableState() {
    try {
      flow.getTransitionableState("myState2");
      fail("End states aren't transtionable");
    } catch (ClassCastException e) {
      // expected
    }
    try {
      flow.getTransitionableState("doesNotExist");
    } catch (IllegalArgumentException e) {
      // expected
    }
  }

  public void testGetPossibleOutcomes() {
    Flow flow = new Flow("myFlow");
    new EndState(flow, "myState1");
    new EndState(flow, "myState2");
    assertEquals("myState1", flow.getPossibleOutcomes()[0]);
    assertEquals("myState2", flow.getPossibleOutcomes()[1]);
  }

  public void testAddActions() {
    flow.getStartActionList().add(new TestMultiAction());
    flow.getStartActionList().add(new TestMultiAction());
    flow.getEndActionList().add(new TestMultiAction());
    assertEquals(2, flow.getStartActionList().size());
    assertEquals(1, flow.getEndActionList().size());
  }

  public void testAddGlobalTransition() {
    Transition t = new Transition(to("myState2"));
    flow.getGlobalTransitionSet().add(t);
    assertSame(t, flow.getGlobalTransitionSet().toArray()[1]);
  }

  public void testStart() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    flow.start(context, new LocalAttributeMap<Object>());
    assertEquals("Wrong start state", "myState1", context.getCurrentState().getId());
  }

  public void testStartWithoutStartState() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    try {
      Flow empty = new Flow("empty");
      empty.start(context, null);
      fail("should have failed");
    } catch (IllegalStateException e) {

    }
  }

  public void testStartWithAction() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    TestAction action = new TestAction();
    flow.getStartActionList().add(action);
    flow.start(context, new LocalAttributeMap<Object>());
    assertEquals("Wrong start state", "myState1", context.getCurrentState().getId());
    assertEquals(1, action.getExecutionCount());
  }

  public void testStartWithVariables() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    flow.addVariable(new FlowVariable("var1", new VariableValueFactory() {
      public Object createInitialValue(RequestContext context) {
        return new ArrayList<Object>();
      }

      public void restoreReferences(Object value, RequestContext context) {
      }
    }));
    flow.start(context, new LocalAttributeMap<Object>());
    context.getFlowScope().getRequired("var1", ArrayList.class);
  }

  public void testStartWithMapper() {
    DefaultMapper attributeMapper = new DefaultMapper();
    ExpressionParser parser = new WebFlowSpringELExpressionParser(new SpelExpressionParser());
    Expression x = parser.parseExpression("attr", new FluentParserContext().evaluate(AttributeMap.class));
    Expression y = parser.parseExpression("flowScope.attr",
        new FluentParserContext().evaluate(RequestContext.class));
    attributeMapper.addMapping(new DefaultMapping(x, y));
    flow.setInputMapper(attributeMapper);
    MockRequestControlContext context = new MockRequestControlContext(flow);
    LocalAttributeMap<Object> sessionInput = new LocalAttributeMap<Object>();
    sessionInput.put("attr", "foo");
    flow.start(context, sessionInput);
    assertEquals("foo", context.getFlowScope().get("attr"));
  }

  public void testStartWithMapperButNoInput() {
    DefaultMapper attributeMapper = new DefaultMapper();
    ExpressionParser parser = new WebFlowSpringELExpressionParser(new SpelExpressionParser());
    Expression x = parser.parseExpression("attr", new FluentParserContext().evaluate(AttributeMap.class));
    Expression y = parser.parseExpression("flowScope.attr",
        new FluentParserContext().evaluate(RequestContext.class));
    attributeMapper.addMapping(new DefaultMapping(x, y));
    flow.setInputMapper(attributeMapper);
    MockRequestControlContext context = new MockRequestControlContext(flow);
    LocalAttributeMap<Object> sessionInput = new LocalAttributeMap<Object>();
    flow.start(context, sessionInput);
    assertTrue(context.getFlowScope().contains("attr"));
    assertNull(context.getFlowScope().get("attr"));
  }

  public void testOnEventNullCurrentState() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    Event event = new Event(this, "foo");
    try {
      context.setCurrentEvent(event);
      flow.handleEvent(context);
    } catch (IllegalStateException e) {

    }
  }

  public void testOnEventInvalidCurrentState() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    context.setCurrentState(flow.getStateInstance("myState2"));
    Event event = new Event(this, "submit");
    context.setCurrentEvent(event);
    try {
      context.setCurrentEvent(event);
      flow.handleEvent(context);
    } catch (IllegalStateException e) {

    }
  }

  public void testOnEvent() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    context.setCurrentState(flow.getStateInstance("myState1"));
    Event event = new Event(this, "submit");
    context.setCurrentEvent(event);
    assertTrue(context.getFlowExecutionContext().isActive());
    context.setCurrentEvent(event);
    flow.handleEvent(context);
    assertTrue(!context.getFlowExecutionContext().isActive());
  }

  public void testOnEventGlobalTransition() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    context.setCurrentState(flow.getStateInstance("myState1"));
    Event event = new Event(this, "globalEvent");
    context.setCurrentEvent(event);
    assertTrue(context.getFlowExecutionContext().isActive());
    context.setCurrentEvent(event);
    flow.handleEvent(context);
    assertTrue(!context.getFlowExecutionContext().isActive());
  }

  public void testOnEventNoTransition() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    context.setCurrentState(flow.getStateInstance("myState1"));
    Event event = new Event(this, "bogus");
    context.setCurrentEvent(event);
    try {
      context.setCurrentEvent(event);
      flow.handleEvent(context);
    } catch (NoMatchingTransitionException e) {

    }
  }

  public void testResume() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    context.setCurrentState(flow.getStateInstance("myState1"));
    flow.resume(context);
    assertTrue(context.getFlowScope().getBoolean("renderCalled"));
  }

  public void testEnd() {
    TestAction action = new TestAction();
    flow.getEndActionList().add(action);
    MockRequestControlContext context = new MockRequestControlContext(flow);
    LocalAttributeMap<Object> sessionOutput = new LocalAttributeMap<Object>();
    flow.end(context, "finish", sessionOutput);
    assertEquals(1, action.getExecutionCount());
  }

  public void testEndWithOutputMapper() {
    DefaultMapper attributeMapper = new DefaultMapper();
    ExpressionParser parser = new WebFlowSpringELExpressionParser(new SpelExpressionParser());
    Expression x = parser.parseExpression("flowScope.attr",
        new FluentParserContext().evaluate(RequestContext.class));
    Expression y = parser.parseExpression("attr", new FluentParserContext().evaluate(MutableAttributeMap.class));
    attributeMapper.addMapping(new DefaultMapping(x, y));
    flow.setOutputMapper(attributeMapper);
    MockRequestControlContext context = new MockRequestControlContext(flow);
    context.getFlowScope().put("attr", "foo");
    LocalAttributeMap<Object> sessionOutput = new LocalAttributeMap<Object>();
    flow.end(context, "finish", sessionOutput);
    assertEquals("foo", sessionOutput.get("attr"));
  }

  public void testHandleException() {
    flow.getExceptionHandlerSet().add(
        new TransitionExecutingFlowExecutionExceptionHandler().add(TestException.class, "myState2"));
    MockRequestControlContext context = new MockRequestControlContext(flow);
    context.setCurrentState(flow.getStateInstance("myState1"));
    FlowExecutionException e = new FlowExecutionException(flow.getId(), flow.getStartState().getId(), "Oops!",
        new TestException());
    flow.handleException(e, context);
    assertFalse(context.getFlowExecutionContext().isActive());
  }

  public void testHandleExceptionNoMatch() {
    MockRequestControlContext context = new MockRequestControlContext(flow);
    FlowExecutionException e = new FlowExecutionException(flow.getId(), flow.getStartState().getId(), "Oops!",
        new TestException());
    try {
      flow.handleException(e, context);
    } catch (FlowExecutionException ex) {
      // expected
    }
  }

  public void testDestroy() {
    GenericApplicationContext context = new GenericApplicationContext();
    context.refresh();
    flow.setApplicationContext(context);
    assertTrue(context.isActive());
    flow.destroy();
    assertFalse(context.isActive());
  }

  public TransitionCriteria on(String eventId) {
    return new MockTransitionCriteria(eventId);
  }

  protected TargetStateResolver to(String stateId) {
    return new DefaultTargetStateResolver(stateId);
  }
}
TOP

Related Classes of org.springframework.webflow.engine.FlowTests

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.