DefaultLogicResult implements LogicResult { public <T> T forwardTo(final Class<T> type) { return proxifier.proxify(type, new MethodInvocation<T>() { public Object intercept(T proxy, Method method, Object[] args, SuperMethod superMethod) { try { logger.debug("Executing {}", Stringnifier.simpleNameFor(method)); ResourceMethod old = methodInfo.getResourceMethod(); methodInfo.setResourceMethod(DefaultResourceMethod.instanceFor(type, method)); Object result = method.invoke(container.instanceFor(type), args); methodInfo.setResourceMethod(old); Type returnType = method.getGenericReturnType(); if (!(returnType == void.class)) { request.setAttribute(extractor.nameFor(returnType), result); } if (!response.isCommitted()) { String path = resolver.pathFor(DefaultResourceMethod.instanceFor(type, method)); logger.debug("Forwarding to {}", path); request.getRequestDispatcher(path).forward(request, response); } return null; } catch (InvocationTargetException e) { if (e.getCause() instanceof RuntimeException) { throw (RuntimeException) e.getCause(); } throw new ProxyInvocationException(e); } catch (Exception e) { throw new ProxyInvocationException(e); } } }); } @Inject  DefaultLogicResult(Proxifier proxifier, Router router, MutableRequest request, MutableResponse response,
			Container container, PathResolver resolver, TypeNameExtractor extractor, FlashScope flash, MethodInfo methodInfo); T forwardTo(final Class<T> type); T redirectTo(final Class<T> type);  }
@Test public void shouldIncludeReturnValueOnForward() throws Exception { givenDispatcherWillBeReturnedWhenRequested(); when(extractor.nameFor(String.class)).thenReturn("string"); logicResult.forwardTo(MyComponent.class).returnsValue(); verify(dispatcher).forward(request, response); verify(request).setAttribute("string", "A value"); }
@Test public void shouldExecuteTheLogicAndRedirectToItsViewOnForward() throws Exception { final MyComponent component = givenDispatcherWillBeReturnedWhenRequested(); assertThat(component.calls, is(0)); logicResult.forwardTo(MyComponent.class).base(); assertThat(component.calls, is(1)); verify(dispatcher).forward(request, response); }
@Test public void shouldForwardToMethodsDefaultViewWhenResponseIsNotCommited() throws Exception { givenDispatcherWillBeReturnedWhenRequested(); when(response.isCommitted()).thenReturn(false); logicResult.forwardTo(MyComponent.class).base(); verify(dispatcher).forward(request, response); }
@Test public void shouldNotForwardToMethodsDefaultViewWhenResponseIsCommited() throws Exception { givenDispatcherWillBeReturnedWhenRequested(); when(response.isCommitted()).thenReturn(true); logicResult.forwardTo(MyComponent.class).base(); verify(dispatcher, never()).forward(request, response); }
@Test(expected=ValidationException.class) public void shouldNotWrapValidationExceptionWhenForwarding() throws Exception { givenDispatcherWillBeReturnedWhenRequested(); when(response.isCommitted()).thenReturn(true); logicResult.forwardTo(MyComponent.class).throwsValidationException(); }
@Test public void shouldForwardToTheRightDefaultValue() throws Exception { Result result = mock(Result.class); PageResult pageResult = new DefaultPageResult(request, response, methodInfo, resolver, proxifier); when(result.use(PageResult.class)).thenReturn(pageResult); when(container.instanceFor(TheComponent.class)).thenReturn(new TheComponent(result)); when(resolver.pathFor(argThat(sameMethodAs(TheComponent.class.getDeclaredMethod("method"))))).thenReturn("controlled!"); when(request.getRequestDispatcher(anyString())).thenThrow(new AssertionError("should have called with the right method!")); doReturn(dispatcher).when(request).getRequestDispatcher("controlled!"); methodInfo.setResourceMethod(DefaultResourceMethod.instanceFor(MyComponent.class, MyComponent.class.getDeclaredMethod("base"))); logicResult.forwardTo(TheComponent.class).method(); }