Merging of SWF-367 back into trunk. This has all of the SWF 2.0 goodies.
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
package org.springframework.faces.ui.resource;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.shale.test.mock.MockResponseWriter;
|
||||
import org.easymock.EasyMock;
|
||||
import org.springframework.faces.webflow.JSFMockHelper;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.context.FlowDefinitionRequestInfo;
|
||||
import org.springframework.webflow.context.RequestPath;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
public class FlowResourceHelperTests extends TestCase {
|
||||
|
||||
RequestContext requestContext = createMock(RequestContext.class);
|
||||
ExternalContext externalContext = createMock(ExternalContext.class);
|
||||
FlowResourceHelper resourceHelper = new FlowResourceHelper();
|
||||
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
JSFMockHelper jsf = new JSFMockHelper();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsf.setUp();
|
||||
jsf.facesContext().setResponseWriter(new MockResponseWriter(writer, "text/html", "UTF-8"));
|
||||
expect(requestContext.getExternalContext()).andStubReturn(externalContext);
|
||||
RequestContextHolder.setRequestContext(requestContext);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsf.tearDown();
|
||||
}
|
||||
|
||||
public final void testRenderScriptLink() throws IOException {
|
||||
|
||||
String scriptPath = "/dojo/dojo.js";
|
||||
String expectedUrl = "/context/spring/resources/dojo/dojo.js";
|
||||
|
||||
FlowDefinitionRequestInfo expectedRequest = new FlowDefinitionRequestInfo("resources", new RequestPath(
|
||||
scriptPath), null, null);
|
||||
|
||||
expect(externalContext.buildFlowDefinitionUrl(requestInfoMatches(expectedRequest))).andReturn(expectedUrl);
|
||||
|
||||
replay(new Object[] { requestContext, externalContext });
|
||||
|
||||
resourceHelper.renderScriptLink(jsf.facesContext(), scriptPath);
|
||||
resourceHelper.renderScriptLink(jsf.facesContext(), scriptPath);
|
||||
|
||||
verify(new Object[] { externalContext });
|
||||
|
||||
String expectedOutput = "<script type=\"text/javascript\" src=\"" + expectedUrl + "\"/>";
|
||||
|
||||
assertEquals(expectedOutput, writer.toString());
|
||||
|
||||
}
|
||||
|
||||
public final void testRenderStyleLink() throws IOException {
|
||||
|
||||
String scriptPath = "/dijit/themes/dijit.css";
|
||||
String expectedUrl = "/context/spring/resources/dijit/themes/dijit.css";
|
||||
|
||||
FlowDefinitionRequestInfo expectedRequest = new FlowDefinitionRequestInfo("resources", new RequestPath(
|
||||
scriptPath), null, null);
|
||||
|
||||
expect(externalContext.buildFlowDefinitionUrl(requestInfoMatches(expectedRequest))).andReturn(expectedUrl);
|
||||
|
||||
replay(new Object[] { requestContext, externalContext });
|
||||
|
||||
resourceHelper.renderStyleLink(jsf.facesContext(), scriptPath);
|
||||
resourceHelper.renderStyleLink(jsf.facesContext(), scriptPath);
|
||||
|
||||
verify(new Object[] { externalContext });
|
||||
|
||||
String expectedOutput = "<link type=\"text/css\" rel=\"stylesheet\" href=\"" + expectedUrl + "\"/>";
|
||||
|
||||
assertEquals(expectedOutput, writer.toString());
|
||||
}
|
||||
|
||||
static FlowDefinitionRequestInfo requestInfoMatches(FlowDefinitionRequestInfo info) {
|
||||
EasyMock.reportMatcher(new RequestInfoMatcher(info));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.springframework.faces.ui.resource;
|
||||
|
||||
import org.easymock.IArgumentMatcher;
|
||||
import org.springframework.webflow.context.FlowDefinitionRequestInfo;
|
||||
|
||||
class RequestInfoMatcher implements IArgumentMatcher {
|
||||
|
||||
private FlowDefinitionRequestInfo expected;
|
||||
|
||||
public RequestInfoMatcher(FlowDefinitionRequestInfo expected) {
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
public void appendTo(StringBuffer buffer) {
|
||||
buffer.append("/" + expected.getFlowDefinitionId() + expected.getRequestPath());
|
||||
}
|
||||
|
||||
public boolean matches(Object actual) {
|
||||
FlowDefinitionRequestInfo actualRequest = (FlowDefinitionRequestInfo) actual;
|
||||
return expected.getFlowDefinitionId().equals(actualRequest.getFlowDefinitionId())
|
||||
&& expected.getRequestPath().equals(actualRequest.getRequestPath());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.springframework.faces.ui.resource;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.context.RequestPath;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
|
||||
public class ResolveAndRenderResourceActionTests extends TestCase {
|
||||
|
||||
ExternalContext externalContext = createMock(ExternalContext.class);
|
||||
RequestContext requestContext = createMock(RequestContext.class);
|
||||
ServletContext servletContext = new MimeAwareMockServletContext();
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
RequestPath requestPath;
|
||||
String[] requestElements;
|
||||
|
||||
ResolveAndRenderResourceAction action;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
action = new ResolveAndRenderResourceAction();
|
||||
|
||||
expect(requestContext.getExternalContext()).andStubReturn(externalContext);
|
||||
expect(externalContext.getContext()).andStubReturn(servletContext);
|
||||
expect(externalContext.getResponse()).andStubReturn(response);
|
||||
expect(externalContext.getRequest()).andStubReturn(request);
|
||||
expect(externalContext.getResponseWriter()).andStubReturn(new PrintWriter(new StringWriter()));
|
||||
}
|
||||
|
||||
public final void testExecute() throws Exception {
|
||||
|
||||
requestPath = new RequestPath("/ext/ext.js");
|
||||
|
||||
expect(externalContext.getRequestPath()).andStubReturn(requestPath);
|
||||
|
||||
replay(new Object[] { requestContext, externalContext });
|
||||
|
||||
action.execute(requestContext);
|
||||
}
|
||||
|
||||
private class MimeAwareMockServletContext extends MockServletContext {
|
||||
|
||||
public String getMimeType(String filePath) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.component.UICommand;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.MethodBinding;
|
||||
import javax.faces.el.MethodNotFoundException;
|
||||
import javax.faces.event.ActionEvent;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class FlowActionListenerTests extends TestCase {
|
||||
|
||||
FlowActionListener listener = new FlowActionListener();
|
||||
|
||||
JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsfMock.setUp();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsfMock.tearDown();
|
||||
}
|
||||
|
||||
public final void testProcessAction() {
|
||||
|
||||
String outcome = "foo";
|
||||
MethodBinding binding = new MethodBindingStub(outcome);
|
||||
UICommand commandButton = new UICommand();
|
||||
commandButton.setAction(binding);
|
||||
ActionEvent event = new ActionEvent(commandButton);
|
||||
|
||||
listener.processAction(event);
|
||||
|
||||
assertTrue("The event was not signaled", jsfMock.externalContext().getRequestMap().containsKey(
|
||||
JsfView.EVENT_KEY));
|
||||
assertEquals("The event should be " + outcome, outcome, jsfMock.externalContext().getRequestMap().get(
|
||||
JsfView.EVENT_KEY));
|
||||
}
|
||||
|
||||
public final void testProcessAction_NullOutcome() {
|
||||
|
||||
String outcome = null;
|
||||
MethodBinding binding = new MethodBindingStub(outcome);
|
||||
UICommand commandButton = new UICommand();
|
||||
commandButton.setAction(binding);
|
||||
ActionEvent event = new ActionEvent(commandButton);
|
||||
|
||||
listener.processAction(event);
|
||||
|
||||
assertFalse("An unexpected event was signaled", jsfMock.externalContext().getRequestMap().containsKey(
|
||||
JsfView.EVENT_KEY));
|
||||
}
|
||||
|
||||
private class MethodBindingStub extends MethodBinding {
|
||||
|
||||
String result;
|
||||
|
||||
public MethodBindingStub(String result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public Class getType(FacesContext context) throws MethodNotFoundException {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public Object invoke(FacesContext context, Object[] args) throws EvaluationException, MethodNotFoundException {
|
||||
return this.result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.faces.application.FacesMessage;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.binding.message.Message;
|
||||
import org.springframework.binding.message.MessageContext;
|
||||
import org.springframework.binding.message.MessageResolver;
|
||||
import org.springframework.binding.message.Severity;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
public class FlowFacesContextTests extends TestCase {
|
||||
|
||||
JSFMockHelper jsf = new JSFMockHelper();
|
||||
|
||||
FacesContext facesContext;
|
||||
|
||||
RequestContext requestContext = createMock(RequestContext.class);
|
||||
|
||||
MessageContext messageContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
jsf.setUp();
|
||||
facesContext = new FlowFacesContext(jsf.facesContext());
|
||||
RequestContextHolder.setRequestContext(requestContext);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsf.tearDown();
|
||||
}
|
||||
|
||||
public final void testCurrentInstance() {
|
||||
assertSame(FacesContext.getCurrentInstance(), facesContext);
|
||||
}
|
||||
|
||||
public final void testAddMessage() {
|
||||
messageContext = new TestAddMessageContext();
|
||||
expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
replay(new Object[] { requestContext });
|
||||
|
||||
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "foo", "foo"));
|
||||
|
||||
assertEquals("Message count is incorrect", 1, ((TestAddMessageContext) messageContext).messageCount);
|
||||
}
|
||||
|
||||
public final void testGetMessages() {
|
||||
messageContext = new TestGetMessagesContext();
|
||||
expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
replay(new Object[] { requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator<FacesMessage> i = facesContext.getMessages();
|
||||
while (i.hasNext()) {
|
||||
assertNotNull(i.next());
|
||||
iterationCount++;
|
||||
}
|
||||
assertEquals(3, iterationCount);
|
||||
}
|
||||
|
||||
public final void testGetMessagesByClientId() {
|
||||
messageContext = new TestGetMessagesContext();
|
||||
expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
replay(new Object[] { requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator<FacesMessage> i = facesContext.getMessages("componentId");
|
||||
while (i.hasNext()) {
|
||||
assertNotNull(i.next());
|
||||
iterationCount++;
|
||||
}
|
||||
assertEquals(1, iterationCount);
|
||||
}
|
||||
|
||||
public final void testGetClientIdsWithMessages() {
|
||||
messageContext = new TestGetMessagesContext();
|
||||
expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
replay(new Object[] { requestContext });
|
||||
|
||||
int iterationCount = 0;
|
||||
Iterator<String> i = facesContext.getClientIdsWithMessages();
|
||||
while (i.hasNext()) {
|
||||
String id = i.next();
|
||||
assertEquals("componentId", id);
|
||||
iterationCount++;
|
||||
}
|
||||
assertEquals(1, iterationCount);
|
||||
}
|
||||
|
||||
public final void testGetMaximumSeverity() {
|
||||
messageContext = new TestGetMessagesContext();
|
||||
expect(requestContext.getMessageContext()).andStubReturn(messageContext);
|
||||
replay(new Object[] { requestContext });
|
||||
|
||||
assertEquals(FacesMessage.SEVERITY_ERROR, facesContext.getMaximumSeverity());
|
||||
}
|
||||
|
||||
private class TestAddMessageContext implements MessageContext {
|
||||
int messageCount = 0;
|
||||
|
||||
public void addMessage(MessageResolver messageResolver) {
|
||||
messageCount++;
|
||||
}
|
||||
|
||||
public Message[] getMessages() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Message[] getMessages(Object source) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
public void clearMessages() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
}
|
||||
|
||||
private class TestGetMessagesContext implements MessageContext {
|
||||
|
||||
Message[] messages;
|
||||
|
||||
TestGetMessagesContext() {
|
||||
messages = new Message[3];
|
||||
messages[0] = new Message(null, "foo", Severity.INFO);
|
||||
messages[1] = new Message("componentId", "bar", Severity.WARNING);
|
||||
messages[2] = new Message(null, "baz", Severity.ERROR);
|
||||
}
|
||||
|
||||
public void addMessage(MessageResolver messageResolver) {
|
||||
|
||||
}
|
||||
|
||||
public Message[] getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public Message[] getMessages(Object source) {
|
||||
return new Message[] { messages[1] };
|
||||
}
|
||||
|
||||
public void clearMessages() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Auto-generated method stub");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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.faces.webflow;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.faces.webflow.FlowNavigationHandlerArgumentExtractor;
|
||||
import org.springframework.faces.webflow.JsfExternalContext;
|
||||
import org.springframework.webflow.executor.support.FlowExecutorArgumentExtractionException;
|
||||
|
||||
public class FlowNavigationHandlerArgumentExtractorTests extends TestCase {
|
||||
|
||||
private FlowNavigationHandlerArgumentExtractor extractor;
|
||||
|
||||
private MockFacesContext facesContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
extractor = new FlowNavigationHandlerArgumentExtractor();
|
||||
facesContext = new MockFacesContext();
|
||||
facesContext.setExternalContext(new MockJsfExternalContext());
|
||||
}
|
||||
|
||||
public void testExtractFlowId() {
|
||||
JsfExternalContext context = new JsfExternalContext(facesContext);
|
||||
context.handleNavigationCalled("action", "flowId:foo");
|
||||
String flowId = extractor.extractFlowId(context);
|
||||
assertEquals("Wrong flow id", "foo", flowId);
|
||||
}
|
||||
|
||||
public void testExtractFlowIdWrongFormat() {
|
||||
JsfExternalContext context = new JsfExternalContext(facesContext);
|
||||
context.handleNavigationCalled("action", "bogus:foo");
|
||||
try {
|
||||
extractor.extractFlowId(context);
|
||||
fail();
|
||||
} catch (FlowExecutorArgumentExtractionException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testExtractEventId() {
|
||||
JsfExternalContext context = new JsfExternalContext(facesContext);
|
||||
context.handleNavigationCalled("action", "submit");
|
||||
String eventId = extractor.extractEventId(context);
|
||||
assertEquals("Wrong event id", "submit", eventId);
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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.faces.webflow;
|
||||
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.PropertyNotFoundException;
|
||||
import javax.faces.el.PropertyResolver;
|
||||
import javax.faces.el.ReferenceSyntaxException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.springframework.faces.webflow.el.FlowPropertyResolver;
|
||||
import org.springframework.webflow.execution.FlowExecution;
|
||||
import org.springframework.webflow.test.MockFlowSession;
|
||||
|
||||
/**
|
||||
* @author Colin Sampaleanu
|
||||
* @since 1.0
|
||||
*/
|
||||
public class FlowPropertyResolverTests extends TestCase {
|
||||
|
||||
private FlowPropertyResolver resolver;
|
||||
|
||||
private FlowExecution flowEx;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
resolver = new FlowPropertyResolver(new OriginalPropertyResolver());
|
||||
flowEx = (FlowExecution) EasyMock.createMock(FlowExecution.class);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
resolver = null;
|
||||
}
|
||||
|
||||
public void testGetTypeBaseIndex() {
|
||||
Class type = resolver.getType(flowEx, 22);
|
||||
assertNull("can't get property from flow via index", type);
|
||||
}
|
||||
|
||||
public void testGetTypeBaseProperty() {
|
||||
MockFlowSession flowSession = new MockFlowSession();
|
||||
flowSession.getScope().put("name", "joe");
|
||||
flowEx.getActiveSession();
|
||||
EasyMock.expectLastCall().andReturn(flowSession);
|
||||
EasyMock.replay(new Object[] { flowEx });
|
||||
Class type = resolver.getType(flowEx, "name");
|
||||
assertTrue("returned type must match property type", type.equals(String.class));
|
||||
}
|
||||
|
||||
public void testGetValueBaseIndex() {
|
||||
try {
|
||||
resolver.getValue(flowEx, 2);
|
||||
fail("not legal to get flow property by index");
|
||||
} catch (ReferenceSyntaxException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetValueBaseProperty() {
|
||||
MockFlowSession flowSession = new MockFlowSession();
|
||||
flowSession.getScope().put("name", "joe");
|
||||
flowEx.getActiveSession();
|
||||
EasyMock.expectLastCall().andReturn(flowSession);
|
||||
EasyMock.replay(new Object[] { flowEx });
|
||||
Object value = resolver.getValue(flowEx, "name");
|
||||
assertTrue("must return expected property", value.equals("joe"));
|
||||
}
|
||||
|
||||
public void testSetValueBaseIndex() {
|
||||
try {
|
||||
resolver.setValue(flowEx, 2, "whatever");
|
||||
fail("not legal to set flow property by index");
|
||||
} catch (ReferenceSyntaxException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testSetValueBaseProperty() {
|
||||
MockFlowSession flowSession = new MockFlowSession();
|
||||
flowEx.getActiveSession();
|
||||
EasyMock.expectLastCall().andReturn(flowSession);
|
||||
EasyMock.replay(new Object[] { flowEx });
|
||||
resolver.setValue(flowEx, "name", "joe");
|
||||
assertTrue(flowSession.getScope().get("name").equals("joe"));
|
||||
}
|
||||
|
||||
private static class OriginalPropertyResolver extends PropertyResolver {
|
||||
|
||||
public Class getType(Object base, int index) throws EvaluationException, PropertyNotFoundException {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public Class getType(Object base, Object property) throws EvaluationException, PropertyNotFoundException {
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
public Object getValue(Object base, int index) throws EvaluationException, PropertyNotFoundException {
|
||||
return new String("Some value");
|
||||
}
|
||||
|
||||
public Object getValue(Object base, Object property) throws EvaluationException, PropertyNotFoundException {
|
||||
return new String("Some value");
|
||||
}
|
||||
|
||||
public boolean isReadOnly(Object base, int index) throws EvaluationException, PropertyNotFoundException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isReadOnly(Object base, Object property) throws EvaluationException, PropertyNotFoundException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setValue(Object base, int index, Object value) throws EvaluationException,
|
||||
PropertyNotFoundException {
|
||||
}
|
||||
|
||||
public void setValue(Object base, Object property, Object value) throws EvaluationException,
|
||||
PropertyNotFoundException {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.faces.webflow.FlowExecutionHolder;
|
||||
import org.springframework.faces.webflow.FlowSystemCleanupFilter;
|
||||
import org.springframework.mock.web.MockFilterChain;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.webflow.context.ExternalContextHolder;
|
||||
import org.springframework.webflow.engine.impl.FlowExecutionImpl;
|
||||
import org.springframework.webflow.execution.FlowExecutionContextHolder;
|
||||
import org.springframework.webflow.test.MockExternalContext;
|
||||
|
||||
public class FlowSystemCleanupFilterTests extends TestCase {
|
||||
|
||||
private FlowSystemCleanupFilter filter;
|
||||
|
||||
private ServletRequest request;
|
||||
|
||||
private ServletResponse response;
|
||||
|
||||
private FilterChain chain;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
filter = new FlowSystemCleanupFilter();
|
||||
request = new MockHttpServletRequest();
|
||||
request.setAttribute(getFlowExecutionHolderKey(), new FlowExecutionHolder(new FlowExecutionImpl()));
|
||||
response = new MockHttpServletResponse();
|
||||
chain = new MockFilterChain();
|
||||
FlowExecutionContextHolder.setFlowExecutionContext(new FlowExecutionImpl());
|
||||
ExternalContextHolder.setExternalContext(new MockExternalContext());
|
||||
}
|
||||
|
||||
public void testCleanup() throws ServletException, IOException {
|
||||
filter.doFilter(request, response, chain);
|
||||
|
||||
assertNull("Should have cleaned up the flow execution", request.getAttribute(getFlowExecutionHolderKey()));
|
||||
try {
|
||||
FlowExecutionContextHolder.getFlowExecutionContext();
|
||||
fail("Should have an empty holder");
|
||||
} catch (IllegalStateException e) {
|
||||
}
|
||||
try {
|
||||
ExternalContextHolder.getExternalContext();
|
||||
fail("Should have an empty holder");
|
||||
} catch (IllegalStateException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testExceptionThrown() throws ServletException, IOException {
|
||||
try {
|
||||
filter.doFilter(request, response, new ExceptionThrowingMockFilterChain());
|
||||
} catch (RuntimeException e) {
|
||||
assertNull("Should have cleaned up the flow execution", request.getAttribute(getFlowExecutionHolderKey()));
|
||||
try {
|
||||
FlowExecutionContextHolder.getFlowExecutionContext();
|
||||
fail("Should have an empty holder");
|
||||
} catch (IllegalStateException e1) {
|
||||
}
|
||||
try {
|
||||
ExternalContextHolder.getExternalContext();
|
||||
fail("Should have an empty holder");
|
||||
} catch (IllegalStateException e1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getFlowExecutionHolderKey() {
|
||||
return FlowExecutionHolder.class.getName();
|
||||
}
|
||||
|
||||
private class ExceptionThrowingMockFilterChain extends MockFilterChain {
|
||||
|
||||
public void doFilter(ServletRequest request, ServletResponse response) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 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.faces.webflow;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.EvaluationException;
|
||||
import javax.faces.el.VariableResolver;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.springframework.faces.webflow.FlowExecutionHolder;
|
||||
import org.springframework.faces.webflow.FlowExecutionHolderUtils;
|
||||
import org.springframework.faces.webflow.el.FlowVariableResolver;
|
||||
import org.springframework.webflow.execution.FlowExecution;
|
||||
import org.springframework.webflow.execution.repository.FlowExecutionKey;
|
||||
|
||||
/**
|
||||
* Unit tests for the FlowVariableResolver class.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class FlowVariableResolverTests extends TestCase {
|
||||
|
||||
private FlowVariableResolver tested;
|
||||
|
||||
private TestableVariableResolver variableResolver;
|
||||
|
||||
private MockFacesContext mockFacesContext;
|
||||
|
||||
private MockJsfExternalContext mockJsfExternalContext;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
mockFacesContext = new MockFacesContext();
|
||||
mockJsfExternalContext = new MockJsfExternalContext();
|
||||
mockFacesContext.setExternalContext(mockJsfExternalContext);
|
||||
variableResolver = new TestableVariableResolver();
|
||||
tested = new FlowVariableResolver(variableResolver);
|
||||
}
|
||||
|
||||
public void testResolveVariableNotFlowScope() {
|
||||
Object result = tested.resolveVariable(mockFacesContext, "some name");
|
||||
assertTrue("not resolved using delegate", variableResolver.resolvedUsingDelegate);
|
||||
assertSame(variableResolver.expected, result);
|
||||
}
|
||||
|
||||
public void testResolveVariableFlowScopeWithNoThreadLocal() {
|
||||
try {
|
||||
tested.resolveVariable(mockFacesContext, "flowScope");
|
||||
fail("EvaluationException expected");
|
||||
} catch (EvaluationException expected) {
|
||||
|
||||
}
|
||||
assertFalse("resolved using delegate", variableResolver.resolvedUsingDelegate);
|
||||
}
|
||||
|
||||
public void testResolveVariableFlowScopeWithThreadLocal() {
|
||||
FlowExecution flowExecutionMock = (FlowExecution) EasyMock.createMock(FlowExecution.class);
|
||||
FlowExecutionKey key = null;
|
||||
FlowExecutionHolder holder = new FlowExecutionHolder(key, flowExecutionMock, null);
|
||||
FlowExecutionHolderUtils.setFlowExecutionHolder(holder, mockFacesContext);
|
||||
EasyMock.replay(new Object[] { flowExecutionMock });
|
||||
|
||||
Object result = tested.resolveVariable(mockFacesContext, "flowScope");
|
||||
|
||||
EasyMock.verify(new Object[] { flowExecutionMock });
|
||||
assertFalse("resolved using delegate", variableResolver.resolvedUsingDelegate);
|
||||
assertSame(flowExecutionMock, result);
|
||||
}
|
||||
|
||||
private static class TestableVariableResolver extends VariableResolver {
|
||||
private boolean resolvedUsingDelegate;
|
||||
|
||||
private Object expected = new Object();
|
||||
|
||||
public Object resolveVariable(FacesContext arg0, String arg1) throws EvaluationException {
|
||||
resolvedUsingDelegate = true;
|
||||
return expected;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.jboss.el.ExpressionFactoryImpl;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.faces.el.Jsf11ELExpressionParser;
|
||||
import org.springframework.faces.webflow.el.DelegatingFlowVariableResolver;
|
||||
import org.springframework.faces.webflow.el.FlowPropertyResolver;
|
||||
import org.springframework.faces.webflow.el.FlowVariableResolver;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.jsf.DelegatingVariableResolver;
|
||||
import org.springframework.webflow.definition.registry.FlowDefinitionResource;
|
||||
import org.springframework.webflow.execution.FlowExecutionException;
|
||||
import org.springframework.webflow.execution.ViewSelection;
|
||||
import org.springframework.webflow.test.MockFlowServiceLocator;
|
||||
import org.springframework.webflow.test.execution.AbstractXmlFlowExecutionTests;
|
||||
|
||||
public class JSF11ManagedBeanAccessTests extends AbstractXmlFlowExecutionTests {
|
||||
|
||||
JSFMockHelper jsf;
|
||||
JSFManagedBean jsfBean;
|
||||
JSFModel jsfModel;
|
||||
FlowPhaseListener flowPhaseListener;
|
||||
FlowNavigationHandler flowNavigationHandler;
|
||||
MockService service;
|
||||
GenericWebApplicationContext ctx;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
service = (MockService) EasyMock.createMock(MockService.class);
|
||||
jsf = new JSFMockHelper();
|
||||
jsf.setUp();
|
||||
configureJSFForSWF();
|
||||
}
|
||||
|
||||
private void configureJSFForSWF() {
|
||||
DelegatingVariableResolver dvr = new DelegatingVariableResolver(jsf.application().getVariableResolver());
|
||||
DelegatingFlowVariableResolver dfvr = new DelegatingFlowVariableResolver(dvr);
|
||||
FlowVariableResolver fvr = new FlowVariableResolver(dfvr);
|
||||
jsf.application().setVariableResolver(fvr);
|
||||
FlowPropertyResolver fpr = new FlowPropertyResolver(jsf.application().getPropertyResolver());
|
||||
jsf.application().setPropertyResolver(fpr);
|
||||
|
||||
flowNavigationHandler = new FlowNavigationHandler(jsf.application().getNavigationHandler());
|
||||
jsf.application().setNavigationHandler(flowNavigationHandler);
|
||||
|
||||
jsf.externalContext().getRequestMap().put("JsfBean", new JSFManagedBean());
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
jsf.tearDown();
|
||||
}
|
||||
|
||||
public void testManagedBeanExpression() {
|
||||
ValueBinding vb = jsf.application().createValueBinding("#{JsfBean}");
|
||||
jsfBean = (JSFManagedBean) vb.getValue(jsf.facesContext());
|
||||
assertNotNull(jsfBean);
|
||||
}
|
||||
|
||||
public void testSWFExplicitlyScopedPropertyInjection() {
|
||||
testManagedBeanExpression();
|
||||
startFlow();
|
||||
|
||||
ValueBinding propBinding = jsf.application().createValueBinding("#{flowScope.jsfModel}");
|
||||
jsfModel = (JSFModel) propBinding.getValue(jsf.facesContext());
|
||||
assertNotNull(jsfModel);
|
||||
}
|
||||
|
||||
public void testManagedBeanPropertyAsArgument() {
|
||||
testManagedBeanExpression();
|
||||
jsfBean.setProp1("arg");
|
||||
service.doSomething(jsfBean.getProp1());
|
||||
EasyMock.replay(new Object[] { service });
|
||||
|
||||
startFlow();
|
||||
signalEvent("event1");
|
||||
EasyMock.verify(new Object[] { service });
|
||||
assertCurrentStateEquals("viewState2");
|
||||
}
|
||||
|
||||
public void testEvalManagedBeanMethod() {
|
||||
testManagedBeanExpression();
|
||||
startFlow();
|
||||
|
||||
ValueBinding propBinding = jsf.application().createValueBinding("#{flowScope.jsfModel}");
|
||||
jsfModel = (JSFModel) propBinding.getValue(jsf.facesContext());
|
||||
assertNotNull(jsfModel);
|
||||
jsfModel.setValue("foo");
|
||||
|
||||
signalEvent("event2");
|
||||
assertFalse(jsfBean.getValues().isEmpty());
|
||||
String addedValue = jsfBean.getValues().get(0).toString();
|
||||
assertEquals(jsfModel.getValue(), addedValue);
|
||||
assertCurrentStateEquals("viewState2");
|
||||
}
|
||||
|
||||
public void testSWFScopedPropertyInjection() {
|
||||
startFlow();
|
||||
|
||||
ValueBinding propBinding = jsf.application().createValueBinding("#{flowScopedModel}");
|
||||
jsfModel = (JSFModel) propBinding.getValue(jsf.facesContext());
|
||||
assertNotNull("This test won't pass until custom scopes are implemented.", jsfModel);
|
||||
}
|
||||
|
||||
protected ViewSelection startFlow() throws FlowExecutionException {
|
||||
ViewSelection view = super.startFlow();
|
||||
FlowExecutionHolder holder = new FlowExecutionHolder(getFlowExecution());
|
||||
FlowExecutionHolderUtils.setFlowExecutionHolder(holder, jsf.facesContext());
|
||||
holder.setViewSelection(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
protected FlowDefinitionResource getFlowDefinitionResource() {
|
||||
try {
|
||||
return createFlowDefinitionResource(ResourceUtils.getFile(
|
||||
"classpath:org/springframework/faces/webflow/jsf-flow.xml").getPath());
|
||||
} catch (FileNotFoundException e) {
|
||||
fail(e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void registerMockServices(MockFlowServiceLocator serviceRegistry) {
|
||||
serviceRegistry.setExpressionParser(new Jsf11ELExpressionParser(new ExpressionFactoryImpl()));
|
||||
serviceRegistry.registerBean("serviceBean", service);
|
||||
|
||||
ctx = new GenericWebApplicationContext();
|
||||
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
|
||||
xmlReader.loadBeanDefinitions(new ClassPathResource("org/springframework/faces/webflow/jsf-flow-beans.xml"));
|
||||
ctx.refresh();
|
||||
|
||||
jsf.externalContext().getApplicationMap().put(
|
||||
GenericWebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ctx);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import org.jboss.el.ExpressionFactoryImpl;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.faces.el.Jsf12ELExpressionParser;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.webflow.test.MockFlowServiceLocator;
|
||||
|
||||
public class JSF12ManagedBeanAccessTests extends JSF11ManagedBeanAccessTests {
|
||||
|
||||
protected void registerMockServices(MockFlowServiceLocator serviceRegistry) {
|
||||
serviceRegistry.setExpressionParser(new Jsf12ELExpressionParser(new ExpressionFactoryImpl()));
|
||||
serviceRegistry.registerBean("serviceBean", service);
|
||||
|
||||
ctx = new GenericWebApplicationContext();
|
||||
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
|
||||
xmlReader.loadBeanDefinitions(new ClassPathResource("org/springframework/faces/webflow/jsf-flow-beans.xml"));
|
||||
ctx.refresh();
|
||||
|
||||
jsf.externalContext().getApplicationMap().put(
|
||||
GenericWebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ctx);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.el.CompositeELResolver;
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.ValueBinding;
|
||||
import javax.faces.event.PhaseEvent;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.event.PhaseListener;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.jboss.el.ExpressionFactoryImpl;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.binding.method.MethodSignature;
|
||||
import org.springframework.binding.method.Parameter;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.webflow.action.AbstractBeanInvokingAction;
|
||||
import org.springframework.webflow.action.EvaluateAction;
|
||||
import org.springframework.webflow.action.SetAction;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.context.ExternalContextHolder;
|
||||
import org.springframework.webflow.context.servlet.ServletExternalContext;
|
||||
import org.springframework.webflow.core.expression.el.RequestContextELResolver;
|
||||
import org.springframework.webflow.core.expression.el.ScopeSearchingELResolver;
|
||||
import org.springframework.webflow.core.expression.el.WebFlowELExpressionParser;
|
||||
import org.springframework.webflow.engine.ActionState;
|
||||
import org.springframework.webflow.engine.EndState;
|
||||
import org.springframework.webflow.engine.Flow;
|
||||
import org.springframework.webflow.engine.TargetStateResolver;
|
||||
import org.springframework.webflow.engine.Transition;
|
||||
import org.springframework.webflow.engine.TransitionCriteria;
|
||||
import org.springframework.webflow.engine.ViewState;
|
||||
import org.springframework.webflow.engine.impl.FlowExecutionImplFactory;
|
||||
import org.springframework.webflow.engine.support.DefaultTargetStateResolver;
|
||||
import org.springframework.webflow.engine.support.EventIdTransitionCriteria;
|
||||
import org.springframework.webflow.execution.Action;
|
||||
import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.FlowExecution;
|
||||
import org.springframework.webflow.execution.FlowExecutionKey;
|
||||
import org.springframework.webflow.execution.FlowExecutionKeyFactory;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.ScopeType;
|
||||
|
||||
public class JSFFlowExecutionTests extends TestCase {
|
||||
|
||||
JSFMockHelper jsf;
|
||||
JSFManagedBean jsfBean;
|
||||
JSFModel jsfModel;
|
||||
MockViewHandler viewHandler;
|
||||
MockService service;
|
||||
GenericWebApplicationContext ctx;
|
||||
TrackingPhaseListener trackingListener;
|
||||
|
||||
Flow flow;
|
||||
FlowExecution execution;
|
||||
|
||||
ExpressionParser parser = new WebFlowELExpressionParser(new ExpressionFactoryImpl());
|
||||
|
||||
/**
|
||||
* TODO - The management of the JSF mocks has gotten rather convoluted now that we are tearing down and rebuilding
|
||||
* the FacesContext multiple times per request. Consider enhancing JSFMockHelper to manage things more appropriately
|
||||
* for SWF usage.
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
service = EasyMock.createMock(MockService.class);
|
||||
|
||||
trackingListener = new TrackingPhaseListener();
|
||||
jsfRequestSetup();
|
||||
|
||||
flow = Flow.create("jsf-flow", null);
|
||||
|
||||
ViewState view1 = new ViewState(flow, "viewState1", new JsfViewFactory(new TestLifecycle(jsf.lifecycle()),
|
||||
parser.parseExpression("view1", RequestContext.class, String.class, null)));
|
||||
view1.getTransitionSet().add(new Transition(on("event1"), to("doSomething")));
|
||||
view1.getTransitionSet().add(new Transition(on("event2"), to("evalSomething")));
|
||||
|
||||
ActionState doSomething = new ActionState(flow, "doSomething");
|
||||
doSomething.getActionList().add(
|
||||
new StubBeanAction(new MethodSignature("doSomething", new Parameter(String.class, parser
|
||||
.parseExpression("#{JsfBean.prop1}", RequestContext.class, String.class, null)))));
|
||||
doSomething.getTransitionSet().add(new Transition(on("success"), to("viewState2")));
|
||||
|
||||
ActionState evalSomething = new ActionState(flow, "evalSomething");
|
||||
evalSomething.getEntryActionList().add(
|
||||
new SetAction(parser.parseExpression("#{requestContext.flowScope.jsfModel}", RequestContext.class,
|
||||
String.class, null), ScopeType.FLOW, parser.parseExpression("#{'foo'}", RequestContext.class,
|
||||
String.class, null)));
|
||||
evalSomething.getActionList().add(
|
||||
new EvaluateAction(parser.parseExpression("#{JsfBean.addValue(jsfModel)}", RequestContext.class,
|
||||
String.class, null)));
|
||||
evalSomething.getTransitionSet().add(new Transition(on("success"), to("viewState2")));
|
||||
|
||||
ViewState viewState2 = new ViewState(flow, "viewState2", new JsfViewFactory(new TestLifecycle(jsf.lifecycle()),
|
||||
parser.parseExpression("view2", RequestContext.class, String.class, null)));
|
||||
viewState2.getEntryActionList().add(new ViewState2SetupAction());
|
||||
viewState2.getTransitionSet().add(new Transition(on("event1"), to("endState1")));
|
||||
|
||||
new EndState(flow, "endState1");
|
||||
|
||||
FlowExecutionImplFactory factory = new FlowExecutionImplFactory();
|
||||
factory.setExecutionKeyFactory(new SimpleFlowExecutionKeyFactory());
|
||||
execution = factory.createFlowExecution(flow);
|
||||
}
|
||||
|
||||
private void jsfRequestSetup() throws Exception {
|
||||
jsf = new JSFMockHelper();
|
||||
jsf.tearDown();
|
||||
jsf.setUp();
|
||||
FacesContext flowContext = new FlowFacesContext(jsf.facesContext());
|
||||
org.apache.shale.test.mock.MockFacesContext.setCurrentInstance(flowContext);
|
||||
|
||||
viewHandler = new NoRenderViewHandler();
|
||||
jsf.application().setViewHandler(viewHandler);
|
||||
trackingListener.reset();
|
||||
jsf.lifecycle().addPhaseListener(trackingListener);
|
||||
|
||||
CompositeELResolver baseResolver = (CompositeELResolver) jsf.facesContext().getELContext().getELResolver();
|
||||
baseResolver.add(new RequestContextELResolver());
|
||||
baseResolver.add(new ScopeSearchingELResolver());
|
||||
|
||||
jsf.externalContext().getRequestMap().put("JsfBean", new JSFManagedBean());
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsf.tearDown();
|
||||
}
|
||||
|
||||
public void testManagedBeanExpression() {
|
||||
ValueBinding vb = jsf.application().createValueBinding("#{JsfBean}");
|
||||
jsfBean = (JSFManagedBean) vb.getValue(jsf.facesContext());
|
||||
assertNotNull(jsfBean);
|
||||
}
|
||||
|
||||
/*
|
||||
* public void testBeanAction() throws Exception { startFlow();
|
||||
*
|
||||
* jsfRequestSetup();
|
||||
*
|
||||
* testManagedBeanExpression(); jsfBean.setProp1("arg"); service.doSomething(jsfBean.getProp1());
|
||||
* EasyMock.replay(new Object[] { service });
|
||||
*
|
||||
* jsf.externalContext().getRequestMap().put(JsfView.EVENT_KEY, "event1");
|
||||
*
|
||||
* UIViewRoot existingRoot = new UIViewRoot(); existingRoot.setViewId("view1");
|
||||
* viewHandler.setRestoreView(existingRoot);
|
||||
*
|
||||
* execution.resume(getExternalContext());
|
||||
*
|
||||
* EasyMock.verify(new Object[] { service });
|
||||
*
|
||||
* ViewState currentState = (ViewState) execution.getActiveSession().getState(); assertEquals("viewState2",
|
||||
* currentState.getId()); }
|
||||
*
|
||||
* public void testEvalAction() throws Exception { startFlow();
|
||||
*
|
||||
* jsfRequestSetup();
|
||||
*
|
||||
* testManagedBeanExpression();
|
||||
*
|
||||
* jsf.externalContext().getRequestMap().put(JsfView.EVENT_KEY, "event2");
|
||||
*
|
||||
* UIViewRoot existingRoot = new UIViewRoot(); existingRoot.setViewId("view1");
|
||||
* viewHandler.setRestoreView(existingRoot);
|
||||
*
|
||||
* execution.resume(getExternalContext());
|
||||
*
|
||||
* assertFalse(jsfBean.getValues().isEmpty()); String addedValue = jsfBean.getValues().get(0).toString();
|
||||
* assertEquals(addedValue, "foo");
|
||||
*
|
||||
* ViewState currentState = (ViewState) execution.getActiveSession().getState(); assertEquals("viewState2",
|
||||
* currentState.getId()); }
|
||||
*/
|
||||
private static TransitionCriteria on(String event) {
|
||||
return new EventIdTransitionCriteria(event);
|
||||
}
|
||||
|
||||
private static TargetStateResolver to(String stateId) {
|
||||
return new DefaultTargetStateResolver(stateId);
|
||||
}
|
||||
|
||||
private void startFlow() {
|
||||
UIViewRoot view = new UIViewRoot();
|
||||
view.setViewId("view1");
|
||||
viewHandler.setCreateView(view);
|
||||
execution.start(getExternalContext());
|
||||
}
|
||||
|
||||
private ExternalContext getExternalContext() {
|
||||
jsf.request().setPathElements("myApp", "", "/flow", null);
|
||||
ExternalContext ext = new ServletExternalContext(jsf.servletContext(), jsf.request(), jsf.response());
|
||||
ExternalContextHolder.setExternalContext(ext);
|
||||
return ext;
|
||||
}
|
||||
|
||||
private class TestLifecycle extends FlowLifecycle {
|
||||
|
||||
boolean executed = false;
|
||||
|
||||
public TestLifecycle(Lifecycle delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
public void execute(FacesContext context) throws FacesException {
|
||||
assertFalse("Lifecycle executed more than once", executed);
|
||||
super.execute(context);
|
||||
executed = true;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
executed = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class StubBeanAction extends AbstractBeanInvokingAction {
|
||||
|
||||
protected StubBeanAction(MethodSignature methodSignature) {
|
||||
super(methodSignature);
|
||||
}
|
||||
|
||||
protected Object getBean(RequestContext context) throws Exception {
|
||||
return service;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class SimpleFlowExecutionKeyFactory implements FlowExecutionKeyFactory {
|
||||
public FlowExecutionKey getKey(FlowExecution execution) {
|
||||
return new FlowExecutionKey() {
|
||||
public String toString() {
|
||||
return "key";
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private class NoRenderViewHandler extends MockViewHandler {
|
||||
|
||||
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
private class TrackingPhaseListener implements PhaseListener {
|
||||
|
||||
private List phaseCallbacks = new ArrayList();
|
||||
|
||||
public void afterPhase(PhaseEvent event) {
|
||||
String phaseCallback = "AFTER_" + event.getPhaseId();
|
||||
assertFalse("Phase callback " + phaseCallback + " already executed.", phaseCallbacks
|
||||
.contains(phaseCallback));
|
||||
phaseCallbacks.add(phaseCallback);
|
||||
}
|
||||
|
||||
public void beforePhase(PhaseEvent event) {
|
||||
String phaseCallback = "BEFORE_" + event.getPhaseId();
|
||||
assertFalse("Phase callback " + phaseCallback + " already executed.", phaseCallbacks
|
||||
.contains(phaseCallback));
|
||||
phaseCallbacks.add(phaseCallback);
|
||||
}
|
||||
|
||||
public PhaseId getPhaseId() {
|
||||
return PhaseId.ANY_PHASE;
|
||||
}
|
||||
|
||||
public List getPhaseCallbacks() {
|
||||
return phaseCallbacks;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
phaseCallbacks.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ViewState2SetupAction implements Action {
|
||||
|
||||
public Event execute(RequestContext context) throws Exception {
|
||||
jsfRequestSetup();
|
||||
UIViewRoot newRoot = new UIViewRoot();
|
||||
newRoot.setViewId("view2");
|
||||
viewHandler.setCreateView(newRoot);
|
||||
return new Event(this, "success");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,14 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.lifecycle.LifecycleFactory;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
|
||||
import org.apache.shale.test.base.AbstractJsfTestCase;
|
||||
import org.apache.shale.test.mock.MockApplication;
|
||||
import org.apache.shale.test.mock.MockExternalContext;
|
||||
import org.apache.shale.test.mock.MockFacesContextFactory;
|
||||
import org.apache.shale.test.mock.MockHttpServletRequest;
|
||||
import org.apache.shale.test.mock.MockHttpServletResponse;
|
||||
import org.apache.shale.test.mock.MockHttpSession;
|
||||
@@ -11,7 +16,6 @@ import org.apache.shale.test.mock.MockLifecycle;
|
||||
import org.apache.shale.test.mock.MockLifecycleFactory;
|
||||
import org.apache.shale.test.mock.MockRenderKit;
|
||||
import org.apache.shale.test.mock.MockServletConfig;
|
||||
import org.apache.shale.test.mock.MockFacesContext;
|
||||
import org.apache.shale.test.mock.MockServletContext;
|
||||
|
||||
/**
|
||||
@@ -24,7 +28,10 @@ public class JSFMockHelper {
|
||||
|
||||
private JSFMock mock = new JSFMock();
|
||||
|
||||
public MockApplication application() {
|
||||
public Application application() {
|
||||
if (mock.application() == null) {
|
||||
return mock.facesContext.getApplication();
|
||||
}
|
||||
return mock.application();
|
||||
}
|
||||
|
||||
@@ -36,11 +43,11 @@ public class JSFMockHelper {
|
||||
return mock.externalContext();
|
||||
}
|
||||
|
||||
public MockFacesContext facesContext() {
|
||||
public FlowFacesContext facesContext() {
|
||||
return mock.facesContext();
|
||||
}
|
||||
|
||||
public MockFacesContextFactory facesContextFactory() {
|
||||
public FlowFacesContextFactory facesContextFactory() {
|
||||
return mock.facesContextFactory();
|
||||
}
|
||||
|
||||
@@ -86,12 +93,70 @@ public class JSFMockHelper {
|
||||
super("JSFMock");
|
||||
}
|
||||
|
||||
FlowFacesContextFactory facesContextFactory;
|
||||
FlowFacesContext facesContext;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
// Thread.currentThread().setContextClassLoader(
|
||||
// new URLClassLoader(new URL[0], this.getClass().getClassLoader()));
|
||||
|
||||
// Set up Servlet API Objects
|
||||
servletContext = new MockServletContext();
|
||||
config = new MockServletConfig(servletContext);
|
||||
session = new MockHttpSession();
|
||||
session.setServletContext(servletContext);
|
||||
request = new MockHttpServletRequest(session);
|
||||
request.setServletContext(servletContext);
|
||||
response = new MockHttpServletResponse();
|
||||
|
||||
// Set up JSF API Objects
|
||||
FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
|
||||
"org.apache.shale.test.mock.MockApplicationFactory");
|
||||
FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
|
||||
"org.springframework.faces.webflow.MockBaseFacesContextFactory");
|
||||
FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY,
|
||||
"org.springframework.faces.webflow.FlowFacesContextFactory");
|
||||
FactoryFinder
|
||||
.setFactory(FactoryFinder.LIFECYCLE_FACTORY, "org.apache.shale.test.mock.MockLifecycleFactory");
|
||||
FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
|
||||
"org.apache.shale.test.mock.MockRenderKitFactory");
|
||||
|
||||
externalContext = new MockExternalContext(servletContext, request, response);
|
||||
lifecycleFactory = (MockLifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||
lifecycle = (MockLifecycle) lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||
facesContextFactory = (FlowFacesContextFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||
facesContext = (FlowFacesContext) facesContextFactory.getFacesContext(servletContext, request, response,
|
||||
lifecycle);
|
||||
externalContext = (MockExternalContext) facesContext.getExternalContext();
|
||||
UIViewRoot root = new UIViewRoot();
|
||||
root.setViewId("/viewId");
|
||||
root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
|
||||
facesContext.setViewRoot(root);
|
||||
RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
|
||||
renderKit = new MockRenderKit();
|
||||
renderKitFactory.addRenderKit(RenderKitFactory.HTML_BASIC_RENDER_KIT, renderKit);
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
application = null;
|
||||
config = null;
|
||||
externalContext = null;
|
||||
if (facesContext != null) {
|
||||
facesContext.release();
|
||||
}
|
||||
facesContext = null;
|
||||
lifecycle = null;
|
||||
lifecycleFactory = null;
|
||||
renderKit = null;
|
||||
request = null;
|
||||
response = null;
|
||||
servletContext = null;
|
||||
session = null;
|
||||
FactoryFinder.releaseFactories();
|
||||
|
||||
}
|
||||
|
||||
public MockApplication application() {
|
||||
@@ -106,11 +171,11 @@ public class JSFMockHelper {
|
||||
return externalContext;
|
||||
}
|
||||
|
||||
public MockFacesContext facesContext() {
|
||||
public FlowFacesContext facesContext() {
|
||||
return facesContext;
|
||||
}
|
||||
|
||||
public MockFacesContextFactory facesContextFactory() {
|
||||
public FlowFacesContextFactory facesContextFactory() {
|
||||
return facesContextFactory;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.PhaseEvent;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.event.PhaseListener;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.jboss.el.ExpressionFactoryImpl;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.core.expression.el.WebFlowELExpressionParser;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.execution.ViewFactory;
|
||||
import org.springframework.webflow.test.MockExternalContext;
|
||||
|
||||
public class JsfRenderFinalResponseActionTests extends TestCase {
|
||||
|
||||
private static final String VIEW_ID = "testView.xhtml";
|
||||
|
||||
private ViewFactory factory;
|
||||
|
||||
private JsfRenderFinalResponseAction finalResponseAction;
|
||||
|
||||
private JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
private RequestContext context = EasyMock.createMock(RequestContext.class);
|
||||
|
||||
private ViewHandler viewHandler = new NoRenderViewHandler();
|
||||
|
||||
private TestLifecycle lifecycle;
|
||||
|
||||
private PhaseListener trackingListener;
|
||||
|
||||
private StringWriter output = new StringWriter();
|
||||
|
||||
ExpressionParser parser = new WebFlowELExpressionParser(new ExpressionFactoryImpl());
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
configureJsf();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsfMock.tearDown();
|
||||
}
|
||||
|
||||
private void configureJsf() throws Exception {
|
||||
|
||||
jsfMock.setUp();
|
||||
|
||||
trackingListener = new TrackingPhaseListener();
|
||||
jsfMock.lifecycle().addPhaseListener(trackingListener);
|
||||
jsfMock.facesContext().setViewRoot(null);
|
||||
jsfMock.application().setViewHandler(viewHandler);
|
||||
lifecycle = new TestLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression("#{'" + VIEW_ID + "'}", RequestContext.class,
|
||||
String.class, null));
|
||||
finalResponseAction = new JsfRenderFinalResponseAction(factory);
|
||||
RequestContextHolder.setRequestContext(context);
|
||||
ExternalContext ext = new MockExternalContext();
|
||||
EasyMock.expect(context.getExternalContext()).andStubReturn(ext);
|
||||
AttributeMap flash = new LocalAttributeMap();
|
||||
EasyMock.expect(context.getFlashScope()).andStubReturn(flash);
|
||||
}
|
||||
|
||||
public void testRender() throws Exception {
|
||||
|
||||
UIViewRoot newRoot = new UIViewRoot();
|
||||
newRoot.setViewId(VIEW_ID);
|
||||
newRoot.setRenderKitId("TEST_KIT");
|
||||
((MockViewHandler) viewHandler).setCreateView(newRoot);
|
||||
|
||||
EasyMock.replay(new Object[] { context });
|
||||
|
||||
finalResponseAction.execute(context);
|
||||
|
||||
assertTrue(newRoot.isTransient());
|
||||
assertTrue(((NoRenderViewHandler) viewHandler).rendered);
|
||||
}
|
||||
|
||||
private class TestLifecycle extends FlowLifecycle {
|
||||
|
||||
boolean executed = false;
|
||||
|
||||
public TestLifecycle(Lifecycle delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
public void execute(FacesContext context) throws FacesException {
|
||||
assertFalse("Lifecycle executed more than once", executed);
|
||||
super.execute(context);
|
||||
executed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class TrackingPhaseListener implements PhaseListener {
|
||||
|
||||
private List<String> phaseCallbacks = new ArrayList<String>();
|
||||
|
||||
public void afterPhase(PhaseEvent event) {
|
||||
String phaseCallback = "AFTER_" + event.getPhaseId();
|
||||
assertFalse("Phase callback " + phaseCallback + " already executed.", phaseCallbacks
|
||||
.contains(phaseCallback));
|
||||
phaseCallbacks.add(phaseCallback);
|
||||
}
|
||||
|
||||
public void beforePhase(PhaseEvent event) {
|
||||
String phaseCallback = "BEFORE_" + event.getPhaseId();
|
||||
assertFalse("Phase callback " + phaseCallback + " already executed.", phaseCallbacks
|
||||
.contains(phaseCallback));
|
||||
phaseCallbacks.add(phaseCallback);
|
||||
}
|
||||
|
||||
public PhaseId getPhaseId() {
|
||||
return PhaseId.ANY_PHASE;
|
||||
}
|
||||
|
||||
public List getPhaseCallbacks() {
|
||||
return phaseCallbacks;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class NoRenderViewHandler extends MockViewHandler {
|
||||
boolean rendered = false;
|
||||
|
||||
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException {
|
||||
rendered = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.event.PhaseEvent;
|
||||
import javax.faces.event.PhaseId;
|
||||
import javax.faces.event.PhaseListener;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.EasyMock;
|
||||
import org.jboss.el.ExpressionFactoryImpl;
|
||||
import org.springframework.binding.expression.ExpressionParser;
|
||||
import org.springframework.webflow.context.ExternalContext;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.core.collection.LocalAttributeMap;
|
||||
import org.springframework.webflow.core.expression.el.WebFlowELExpressionParser;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
import org.springframework.webflow.execution.View;
|
||||
import org.springframework.webflow.execution.ViewFactory;
|
||||
import org.springframework.webflow.test.MockExternalContext;
|
||||
|
||||
public class JsfViewFactoryTests extends TestCase {
|
||||
|
||||
private static final String VIEW_ID = "testView.xhtml";
|
||||
|
||||
private ViewFactory factory;
|
||||
|
||||
private JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
private RequestContext context = EasyMock.createMock(RequestContext.class);
|
||||
|
||||
private AttributeMap flashMap = new LocalAttributeMap();
|
||||
|
||||
private ViewHandler viewHandler = new MockViewHandler();
|
||||
|
||||
private Lifecycle lifecycle;
|
||||
|
||||
private PhaseListener trackingListener;
|
||||
|
||||
private ExpressionParser parser = new WebFlowELExpressionParser(new ExpressionFactoryImpl());
|
||||
|
||||
private ExternalContext extContext = new MockExternalContext();
|
||||
|
||||
private String event = "foo";
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
configureJsf();
|
||||
RequestContextHolder.setRequestContext(context);
|
||||
EasyMock.expect(context.getFlashScope()).andStubReturn(flashMap);
|
||||
EasyMock.expect(context.getExternalContext()).andStubReturn(extContext);
|
||||
EasyMock.replay(new Object[] { context });
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsfMock.tearDown();
|
||||
}
|
||||
|
||||
private void configureJsf() throws Exception {
|
||||
jsfMock.setUp();
|
||||
trackingListener = new TrackingPhaseListener();
|
||||
jsfMock.lifecycle().addPhaseListener(trackingListener);
|
||||
jsfMock.facesContext().setViewRoot(null);
|
||||
jsfMock.application().setViewHandler(viewHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* View has not yet been created
|
||||
*/
|
||||
public final void testGetView_Create() {
|
||||
|
||||
lifecycle = new NoEventLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression(VIEW_ID, RequestContext.class, String.class,
|
||||
null));
|
||||
|
||||
UIViewRoot newRoot = new UIViewRoot();
|
||||
newRoot.setViewId(VIEW_ID);
|
||||
((MockViewHandler) viewHandler).setCreateView(newRoot);
|
||||
|
||||
View newView = factory.getView(context);
|
||||
|
||||
assertNotNull("A View was not created", newView);
|
||||
assertTrue("A JsfView was expected", newView instanceof JsfView);
|
||||
assertEquals("View name did not match", VIEW_ID, ((JsfView) newView).getViewRoot().getViewId());
|
||||
assertFalse("An unexpected event was signaled,", newView.eventSignaled());
|
||||
assertFalse("The lifecycle should not have been invoked", ((NoEventLifecycle) lifecycle).executed);
|
||||
}
|
||||
|
||||
/**
|
||||
* View already exists in flash scope and must be restored and the lifecycle executed, no event signaled
|
||||
*/
|
||||
public final void testGetView_Restore_NoEvent() {
|
||||
|
||||
lifecycle = new NoEventLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression(VIEW_ID, RequestContext.class, String.class,
|
||||
null));
|
||||
|
||||
UIViewRoot existingRoot = new UIViewRoot();
|
||||
existingRoot.setViewId(VIEW_ID);
|
||||
((MockViewHandler) viewHandler).setRestoreView(existingRoot);
|
||||
|
||||
View restoredView = factory.getView(context);
|
||||
|
||||
assertNotNull("A View was not restored", restoredView);
|
||||
assertTrue("A JsfView was expected", restoredView instanceof JsfView);
|
||||
assertEquals("View name did not match", VIEW_ID, ((JsfView) restoredView).getViewRoot().getViewId());
|
||||
assertFalse("An unexpected event was signaled,", restoredView.eventSignaled());
|
||||
assertTrue("The lifecycle should have been invoked", ((NoEventLifecycle) lifecycle).executed);
|
||||
}
|
||||
|
||||
/**
|
||||
* View already exists in flowscope and must be restored and the lifecycle executed, an event is signaled
|
||||
*/
|
||||
public final void testGetView_Restore_EventSignaled() {
|
||||
|
||||
lifecycle = new EventSignalingLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression(VIEW_ID, RequestContext.class, String.class,
|
||||
null));
|
||||
|
||||
UIViewRoot existingRoot = new UIViewRoot();
|
||||
existingRoot.setViewId(VIEW_ID);
|
||||
((MockViewHandler) viewHandler).setRestoreView(existingRoot);
|
||||
|
||||
View restoredView = factory.getView(context);
|
||||
|
||||
assertNotNull("A View was not restored", restoredView);
|
||||
assertTrue("A JsfView was expected", restoredView instanceof JsfView);
|
||||
assertEquals("View name did not match", VIEW_ID, ((JsfView) restoredView).getViewRoot().getViewId());
|
||||
assertTrue("No event was signaled,", restoredView.eventSignaled());
|
||||
assertEquals("Event should be " + event, event, restoredView.getEvent().getId());
|
||||
assertTrue("The lifecycle should have been invoked", ((EventSignalingLifecycle) lifecycle).executed);
|
||||
}
|
||||
|
||||
/**
|
||||
* View is restored, and then the same view-state is re-entered at the end of the request
|
||||
* @throws Exception
|
||||
*/
|
||||
/*
|
||||
* public final void testGetView_RestoreTwice() throws Exception {
|
||||
*
|
||||
* lifecycle = new EventSignalingLifecycle(jsfMock.lifecycle()); factory = new JsfViewFactory(lifecycle,
|
||||
* parser.parseExpression(VIEW_ID));
|
||||
*
|
||||
* UIViewRoot existingRoot = new UIViewRoot(); existingRoot.setViewId(VIEW_ID); ((MockViewHandler)
|
||||
* viewHandler).setRestoreView(existingRoot);
|
||||
*
|
||||
* View restoredView = factory.getView(context);
|
||||
*
|
||||
* assertNull("FacesContext was not released", FacesContext.getCurrentInstance());
|
||||
*
|
||||
* configureJsf();
|
||||
*
|
||||
* View recursiveView = factory.getView(context);
|
||||
*
|
||||
* assertNotNull("A View was not restored", restoredView); assertTrue("A JsfView was expected", restoredView
|
||||
* instanceof JsfView); assertEquals("View name did not match", VIEW_ID, ((JsfView)
|
||||
* restoredView).getViewRoot().getViewId()); assertSame("Re-entered view should be the same instance", ((JsfView)
|
||||
* restoredView).getViewRoot(), ((JsfView) recursiveView).getViewRoot()); assertTrue("No event was signaled,",
|
||||
* restoredView.eventSignaled()); assertEquals("Event should be " + event, event, restoredView.getEvent().getId());
|
||||
* assertTrue("The lifecycle should have been invoked", lifecycle.executed); }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Third party sets the view root before RESTORE_VIEW
|
||||
*/
|
||||
public final void testGetView_ExternalViewRoot() {
|
||||
|
||||
lifecycle = new NoEventLifecycle(jsfMock.lifecycle());
|
||||
factory = new JsfViewFactory(lifecycle, parser.parseExpression(VIEW_ID, RequestContext.class, String.class,
|
||||
null));
|
||||
|
||||
UIViewRoot newRoot = new UIViewRoot();
|
||||
newRoot.setViewId(VIEW_ID);
|
||||
jsfMock.facesContext().setViewRoot(newRoot);
|
||||
jsfMock.facesContext().renderResponse();
|
||||
|
||||
View newView = factory.getView(context);
|
||||
|
||||
assertNotNull("A View was not created", newView);
|
||||
assertTrue("A JsfView was expected", newView instanceof JsfView);
|
||||
assertEquals("View name did not match", VIEW_ID, ((JsfView) newView).getViewRoot().getViewId());
|
||||
assertSame("View root was not the third party instance", newRoot, ((JsfView) newView).getViewRoot());
|
||||
assertFalse("An unexpected event was signaled,", newView.eventSignaled());
|
||||
assertFalse("The lifecycle should not have been invoked", ((NoEventLifecycle) lifecycle).executed);
|
||||
}
|
||||
|
||||
private class NoEventLifecycle extends FlowLifecycle {
|
||||
|
||||
boolean executed = false;
|
||||
|
||||
public NoEventLifecycle(Lifecycle delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
public void execute(FacesContext context) throws FacesException {
|
||||
assertFalse("Lifecycle executed more than once", executed);
|
||||
super.execute(context);
|
||||
executed = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class EventSignalingLifecycle extends FlowLifecycle {
|
||||
boolean executed = false;
|
||||
|
||||
public EventSignalingLifecycle(Lifecycle delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute(FacesContext context) throws FacesException {
|
||||
assertFalse("Lifecycle executed more than once", executed);
|
||||
super.execute(context);
|
||||
extContext.getRequestMap().put(JsfView.EVENT_KEY, event);
|
||||
executed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private class TrackingPhaseListener implements PhaseListener {
|
||||
|
||||
private List phaseCallbacks = new ArrayList();
|
||||
|
||||
public void afterPhase(PhaseEvent event) {
|
||||
String phaseCallback = "AFTER_" + event.getPhaseId();
|
||||
assertFalse("Phase callback " + phaseCallback + " already executed.", phaseCallbacks
|
||||
.contains(phaseCallback));
|
||||
phaseCallbacks.add(phaseCallback);
|
||||
}
|
||||
|
||||
public void beforePhase(PhaseEvent event) {
|
||||
String phaseCallback = "BEFORE_" + event.getPhaseId();
|
||||
assertFalse("Phase callback " + phaseCallback + " already executed.", phaseCallbacks
|
||||
.contains(phaseCallback));
|
||||
phaseCallbacks.add(phaseCallback);
|
||||
}
|
||||
|
||||
public PhaseId getPhaseId() {
|
||||
return PhaseId.ANY_PHASE;
|
||||
}
|
||||
|
||||
public List getPhaseCallbacks() {
|
||||
return phaseCallbacks;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.component.UIForm;
|
||||
import javax.faces.component.UIInput;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.component.html.HtmlForm;
|
||||
import javax.faces.component.html.HtmlInputText;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.render.RenderKitFactory;
|
||||
import javax.faces.render.Renderer;
|
||||
import javax.faces.render.ResponseStateManager;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.shale.test.mock.MockRenderKit;
|
||||
import org.apache.shale.test.mock.MockResponseWriter;
|
||||
import org.apache.shale.test.mock.MockStateManager;
|
||||
import org.easymock.EasyMock;
|
||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||
import org.springframework.webflow.execution.FlowExecutionContext;
|
||||
import org.springframework.webflow.execution.FlowExecutionKey;
|
||||
import org.springframework.webflow.execution.RequestContext;
|
||||
import org.springframework.webflow.execution.RequestContextHolder;
|
||||
|
||||
public class JsfViewTests extends TestCase {
|
||||
|
||||
private static final String VIEW_ID = "testView.xhtml";
|
||||
|
||||
private JsfView view;
|
||||
|
||||
private JSFMockHelper jsfMock = new JSFMockHelper();
|
||||
|
||||
private StringWriter output = new StringWriter();
|
||||
|
||||
private RequestContext requestContext = EasyMock.createMock(RequestContext.class);
|
||||
private FlowExecutionContext flowExecutionContext = EasyMock.createMock(FlowExecutionContext.class);
|
||||
private MutableAttributeMap flashMap = EasyMock.createMock(MutableAttributeMap.class);
|
||||
|
||||
private FlowExecutionKey key = new FlowExecutionKey() {
|
||||
|
||||
public String toString() {
|
||||
return "MOCK_KEY";
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
|
||||
jsfMock.setUp();
|
||||
jsfMock.application().setViewHandler(new MockViewHandler());
|
||||
jsfMock.application().setStateManager(new TestStateManager());
|
||||
jsfMock.facesContext().setResponseWriter(new MockResponseWriter(output, null, null));
|
||||
|
||||
RenderKitFactory rkf = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
|
||||
rkf.addRenderKit("TEST_KIT", new TestRenderKit());
|
||||
|
||||
UIViewRoot viewToRender = new UIViewRoot();
|
||||
viewToRender.setRenderKitId("TEST_KIT");
|
||||
viewToRender.setViewId(VIEW_ID);
|
||||
jsfMock.facesContext().setViewRoot(viewToRender);
|
||||
|
||||
UIForm form = new HtmlForm();
|
||||
form.setId("myForm");
|
||||
|
||||
UIInput input = new HtmlInputText();
|
||||
input.setId("foo");
|
||||
|
||||
form.getChildren().add(input);
|
||||
viewToRender.getChildren().add(form);
|
||||
|
||||
view = new JsfView(viewToRender, jsfMock.lifecycle());
|
||||
|
||||
RequestContextHolder.setRequestContext(requestContext);
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
jsfMock.tearDown();
|
||||
}
|
||||
|
||||
public final void testRender() {
|
||||
|
||||
EasyMock.expect(requestContext.getFlashScope()).andStubReturn(flashMap);
|
||||
EasyMock.expect(requestContext.getFlowExecutionContext()).andStubReturn(flowExecutionContext);
|
||||
EasyMock.expect(flowExecutionContext.getKey()).andStubReturn(key);
|
||||
EasyMock.expect(flashMap.put(EasyMock.matches(JsfView.STATE_KEY), EasyMock.anyObject())).andStubReturn(null);
|
||||
EasyMock.expect(flashMap.put(EasyMock.matches("renderResponse"), EasyMock.anyObject())).andStubReturn(null);
|
||||
EasyMock.expect(flashMap.put(EasyMock.matches("responseComplete"), EasyMock.anyObject())).andStubReturn(null);
|
||||
|
||||
EasyMock.replay(new Object[] { requestContext, flowExecutionContext, flashMap });
|
||||
|
||||
view.render();
|
||||
|
||||
EasyMock.verify(new Object[] { requestContext, flowExecutionContext, flashMap });
|
||||
assertNull("The FacesContext was not released", FacesContext.getCurrentInstance());
|
||||
assertTrue(output.getBuffer().toString().contains(key.toString()));
|
||||
}
|
||||
|
||||
public final void testRenderException() {
|
||||
|
||||
EasyMock.expect(requestContext.getFlashScope()).andStubReturn(flashMap);
|
||||
EasyMock.expect(flashMap.put(EasyMock.matches("renderResponse"), EasyMock.anyObject())).andStubReturn(null);
|
||||
EasyMock.expect(flashMap.put(EasyMock.matches("responseComplete"), EasyMock.anyObject())).andStubReturn(null);
|
||||
|
||||
EasyMock.replay(new Object[] { requestContext, flowExecutionContext, flashMap });
|
||||
|
||||
jsfMock.application().setViewHandler(new ExceptionalViewHandler());
|
||||
|
||||
try {
|
||||
view.render();
|
||||
} catch (FacesException ex) {
|
||||
assertNull("The FacesContext was not released", FacesContext.getCurrentInstance());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ExceptionalViewHandler extends MockViewHandler {
|
||||
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException {
|
||||
throw new IOException("Rendering blew up");
|
||||
}
|
||||
}
|
||||
|
||||
private class TestStateManager extends MockStateManager {
|
||||
public SerializedView saveSerializedView(FacesContext context) {
|
||||
SerializedView state = new SerializedView(new Object[] { "tree_state" }, new Object[] { "component_state" });
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestRenderKit extends MockRenderKit {
|
||||
Renderer renderer = new Renderer() {
|
||||
};
|
||||
|
||||
public Renderer getRenderer(String family, String rendererType) {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public ResponseStateManager getResponseStateManager() {
|
||||
return new FlowResponseStateManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.FactoryFinder;
|
||||
import javax.faces.application.Application;
|
||||
import javax.faces.application.ApplicationFactory;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
|
||||
import org.apache.shale.test.mock.MockFacesContext12;
|
||||
|
||||
public class MockBaseFacesContext extends MockFacesContext12 {
|
||||
|
||||
private Application application;
|
||||
|
||||
public MockBaseFacesContext() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MockBaseFacesContext(ExternalContext externalContext) {
|
||||
super(externalContext);
|
||||
}
|
||||
|
||||
public MockBaseFacesContext(ExternalContext externalContext, Lifecycle lifecycle) {
|
||||
super(externalContext, lifecycle);
|
||||
}
|
||||
|
||||
public Application getApplication() {
|
||||
if (application == null) {
|
||||
ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder
|
||||
.getFactory(FactoryFinder.APPLICATION_FACTORY);
|
||||
application = applicationFactory.getApplication();
|
||||
}
|
||||
return application;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.springframework.faces.webflow;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.context.ExternalContext;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.FacesContextFactory;
|
||||
import javax.faces.lifecycle.Lifecycle;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.shale.test.mock.MockExternalContext;
|
||||
|
||||
public class MockBaseFacesContextFactory extends FacesContextFactory {
|
||||
|
||||
public FacesContext getFacesContext(Object context, Object request, Object response, Lifecycle lifecycle)
|
||||
throws FacesException {
|
||||
|
||||
ExternalContext ext = new MockExternalContext((ServletContext) context, (HttpServletRequest) request,
|
||||
(HttpServletResponse) response);
|
||||
|
||||
return new MockBaseFacesContext(ext, lifecycle);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,11 +20,14 @@ import java.util.Locale;
|
||||
|
||||
import javax.faces.FacesException;
|
||||
import javax.faces.application.ViewHandler;
|
||||
import javax.faces.application.StateManager.SerializedView;
|
||||
import javax.faces.component.UIViewRoot;
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
public class MockViewHandler extends ViewHandler {
|
||||
private UIViewRoot viewRoot;
|
||||
private UIViewRoot createViewRoot;
|
||||
|
||||
private UIViewRoot restoreViewRoot;
|
||||
|
||||
public Locale calculateLocale(FacesContext context) {
|
||||
return null;
|
||||
@@ -35,15 +38,23 @@ public class MockViewHandler extends ViewHandler {
|
||||
}
|
||||
|
||||
public UIViewRoot createView(FacesContext context, String viewId) {
|
||||
return viewRoot;
|
||||
return createViewRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the view root that this mpck is supposed to create.
|
||||
* @param viewRoot the view to set.
|
||||
* Set the view root that this mock is supposed to create
|
||||
* @param createViewRoot the view to set.
|
||||
*/
|
||||
public void setCreateView(UIViewRoot viewRoot) {
|
||||
this.viewRoot = viewRoot;
|
||||
public void setCreateView(UIViewRoot createViewRoot) {
|
||||
this.createViewRoot = createViewRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the view root that this mock is supposed to restore
|
||||
* @param restoreViewRoot the view to set.
|
||||
*/
|
||||
public void setRestoreView(UIViewRoot restoreViewRoot) {
|
||||
this.restoreViewRoot = restoreViewRoot;
|
||||
}
|
||||
|
||||
public String getActionURL(FacesContext context, String viewId) {
|
||||
@@ -54,11 +65,17 @@ public class MockViewHandler extends ViewHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Really simple implementation to exercise rendering and state saving
|
||||
*/
|
||||
public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException {
|
||||
context.getViewRoot().encodeAll(context);
|
||||
SerializedView state = context.getApplication().getStateManager().saveSerializedView(context);
|
||||
context.getRenderKit().getResponseStateManager().writeState(context, state);
|
||||
}
|
||||
|
||||
public UIViewRoot restoreView(FacesContext context, String viewId) {
|
||||
return null;
|
||||
return restoreViewRoot;
|
||||
}
|
||||
|
||||
public void writeState(FacesContext context) throws IOException {
|
||||
|
||||
Reference in New Issue
Block a user