/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.wicket.request.handler.render; import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.concurrent.atomic.AtomicBoolean; import junit.framework.AssertionFailedError; import org.apache.wicket.core.request.handler.IPageProvider; import org.apache.wicket.core.request.handler.RenderPageRequestHandler; import org.apache.wicket.core.request.handler.RenderPageRequestHandler.RedirectPolicy; import org.apache.wicket.protocol.http.BufferedWebResponse; import org.apache.wicket.request.Url; import org.apache.wicket.request.UrlRenderer; import org.apache.wicket.request.component.IRequestablePage; import org.apache.wicket.request.cycle.RequestCycle; import org.apache.wicket.request.http.WebRequest; import org.apache.wicket.request.http.WebResponse; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Tests for the calculation whether or not to redirect or directly render a page */ public class WebPageRendererTest extends Assert { private RenderPageRequestHandler handler; private RequestCycle requestCycle; private UrlRenderer urlRenderer; private WebRequest request; private WebResponse response; private IRequestablePage page; private IPageProvider provider; /** * Common setup */ @Before public void before() { provider = mock(IPageProvider.class); page = mock(IRequestablePage.class); when(provider.getPageInstance()).thenReturn(page); handler = new RenderPageRequestHandler(provider); requestCycle = mock(RequestCycle.class); urlRenderer = mock(UrlRenderer.class); when(requestCycle.getUrlRenderer()).thenReturn(urlRenderer); request = mock(WebRequest.class); when(requestCycle.getRequest()).thenReturn(request); response = mock(WebResponse.class); when(requestCycle.getResponse()).thenReturn(response); } /** * Tests that when {@link org.apache.wicket.settings.RequestCycleSettings.RenderStrategy#ONE_PASS_RENDER} * is configured there wont be a redirect issued */ @Test public void testOnePassRender() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.onePassRender = true; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("base")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("base/a")); when(request.shouldPreserveClientUrl()).thenReturn(false); renderer.respond(requestCycle); verify(response).write(any(byte[].class)); verify(response, never()).sendRedirect(anyString()); } /** * Tests that when {@link org.apache.wicket.settings.RequestCycleSettings.RenderStrategy#ONE_PASS_RENDER} * is configured there will be a redirect issued if the protocols of the current and target urls * are different * * https://issues.apache.org/jira/browse/WICKET-5522 */ @Test public void testOnePassRenderDifferentProtocols() { final AtomicBoolean responseBuffered = new AtomicBoolean(false); PageRenderer renderer = new TestPageRenderer(handler) { @Override protected boolean isOnePassRender() { return true; } @Override protected void storeBufferedResponse(Url url, BufferedWebResponse response) { responseBuffered.set(true); } }; // uses HTTPS when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("https://host/base")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("http://host/base/a")); when(request.shouldPreserveClientUrl()).thenReturn(false); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); assertTrue(responseBuffered.get()); } /** * Tests that even when {@link org.apache.wicket.settings.RequestCycleSettings.RenderStrategy#ONE_PASS_RENDER} * is configured but the {@link RedirectPolicy} says that it needs to redirect it will redirect. */ @Test public void testOnePassRenderWithAlwaysRedirect() { PageRenderer renderer = new TestPageRenderer(handler) { @Override protected boolean isOnePassRender() { return true; } @Override protected RedirectPolicy getRedirectPolicy() { return RedirectPolicy.ALWAYS_REDIRECT; } }; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("base")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("base/a")); when(request.shouldPreserveClientUrl()).thenReturn(false); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); } /** * Tests that when {@link org.apache.wicket.settings.RequestCycleSettings.RenderStrategy#ONE_PASS_RENDER} * is configured but the current request is Ajax then a redirect should be issued */ @Test public void testOnePassRenderAndAjaxRequest() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.onePassRender = true; renderer.ajax = true; renderer.newPageInstance = true; renderer.pageStateless = true; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("base")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("base/a")); renderer.respond(requestCycle); verify(response).sendRedirect(isNull()); verify(response, never()).write(any(byte[].class)); } /** * Tests that when {@link RenderPageRequestHandler#getRedirectPolicy()} is * {@link RedirectPolicy#NEVER_REDIRECT} there wont be a redirect issued */ @Test public void testRedirectPolicyNever() { PageRenderer renderer = new TestPageRenderer(handler) { @Override protected RedirectPolicy getRedirectPolicy() { return RedirectPolicy.NEVER_REDIRECT; } }; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("base")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("base/a")); when(request.shouldPreserveClientUrl()).thenReturn(false); renderer.respond(requestCycle); verify(response).write(any(byte[].class)); verify(response, never()).sendRedirect(anyString()); } /** * Tests that when the fromUrl and toUrl are the same and * {@link org.apache.wicket.settings.RequestCycleSettings.RenderStrategy#REDIRECT_TO_RENDER} * is configured there wont be a redirect issued */ @Test public void testSameUrlsAndRedirectToRender() { PageRenderer renderer = new TestPageRenderer(handler) { @Override protected boolean isRedirectToRender() { return true; } }; Url sameUrl = Url.parse("anything"); when(urlRenderer.getBaseUrl()).thenReturn(sameUrl); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(sameUrl); when(request.shouldPreserveClientUrl()).thenReturn(false); renderer.respond(requestCycle); verify(response).write(any(byte[].class)); verify(response, never()).sendRedirect(anyString()); } /** * Tests that when the fromUrl and toUrl are the same and the page is not stateless there wont * be a redirect issued */ @Test public void testSameUrlsAndStatefulPage() { when(provider.isNewPageInstance()).thenReturn(false); when(page.isPageStateless()).thenReturn(false); PageRenderer renderer = new TestPageRenderer(handler); Url sameUrl = Url.parse("anything"); when(urlRenderer.getBaseUrl()).thenReturn(sameUrl); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(sameUrl); when(request.shouldPreserveClientUrl()).thenReturn(false); renderer.respond(requestCycle); verify(response).write(any(byte[].class)); verify(response, never()).sendRedirect(anyString()); } /** * Tests that when {@link WebRequest#shouldPreserveClientUrl()} is <code>true</code> no redirect * should occur */ @Test public void testShouldPreserveClientUrl() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.shouldPreserveClientUrl = true; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("something")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("different")); renderer.respond(requestCycle); verify(response).write(any(byte[].class)); verify(response, never()).sendRedirect(anyString()); } /** * Tests that when {@link WebRequest#shouldPreserveClientUrl()} is <code>true</code> * but {@link RenderPageRequestHandler#getRedirectPolicy()} is * {@link RedirectPolicy#ALWAYS_REDIRECT} a redirect must be issued * * https://issues.apache.org/jira/browse/WICKET-5486 */ @Test public void testShouldPreserveClientUrlOverruledByRedirectPolicyAlwaysRedirect() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.shouldPreserveClientUrl = true; renderer.redirectPolicy = RedirectPolicy.ALWAYS_REDIRECT; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("something")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("different")); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); } /** * Tests that when {@link RenderPageRequestHandler#getRedirectPolicy()} is * {@link RedirectPolicy#ALWAYS_REDIRECT} there a redirect must be issued */ @Test public void testRedirectPolicyAlways() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.redirectPolicy = RedirectPolicy.ALWAYS_REDIRECT; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("base")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("base/a")); when(request.shouldPreserveClientUrl()).thenReturn(true); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); } /** * Tests that when the current request is Ajax then a redirect should happen */ @Test public void testSameUrlsAndAjaxRequest() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.ajax = true; Url sameUrl = Url.parse("same"); when(urlRenderer.getBaseUrl()).thenReturn(sameUrl); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(sameUrl); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); } /** * Tests that when {@link org.apache.wicket.settings.RequestCycleSettings.RenderStrategy#REDIRECT_TO_RENDER} * is configured then no matter what are the fromUrl and toUrl a redirect will happen */ @Test public void testRedirectToRender() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.redirectToRender = true; when(provider.getPageInstance()).thenThrow( new AssertionFailedError("no page instance should be created")); when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("a")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("b")); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); } /** * Tests that when target URL is different and session is temporary and page is stateless this * is special case when page is stateless but there is no session so we can't render it to * buffer */ @Test public void testDifferentUrlsTemporarySessionAndStatelessPage() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.redirectToBuffer = true; renderer.sessionTemporary = true; renderer.pageStateless = true; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("a")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("b")); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); } /** * Tests that when URLs are different and we have a page class and not an instance we can * redirect to the url which will instantiate the instance of us */ @Test public void testDifferentUrlsAndNewPageInstance() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.redirectToBuffer = true; renderer.newPageInstance = true; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("a")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("b")); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); } /** * Tests that when during page render another request handler got scheduled. The handler will * want to overwrite the response, so we need to let it */ @Test public void testRedirectToBufferNoPageToRender() { final AtomicBoolean stored = new AtomicBoolean(false); TestPageRenderer renderer = new TestPageRenderer(handler) { @Override protected BufferedWebResponse renderPage(Url targetUrl, RequestCycle requestCycle) { return null; } @Override protected void storeBufferedResponse(Url url, BufferedWebResponse response) { stored.set(true); } }; renderer.redirectToBuffer = true; // needed for earlier checks when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("a")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("b")); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response, never()).write(any(CharSequence.class)); verify(response, never()).sendRedirect(anyString()); Assert.assertFalse(stored.get()); } /** * Tests that when the page is stateless and redirect for stateless pages is disabled then the * page should be written without redirect */ @Test public void testRedirectToBufferStatelessPageAndRedirectIsDisabled() { final AtomicBoolean stored = new AtomicBoolean(false); TestPageRenderer renderer = new TestPageRenderer(handler) { @Override protected boolean enableRedirectForStatelessPage() { return false; } @Override protected void storeBufferedResponse(Url url, BufferedWebResponse response) { stored.set(true); } }; renderer.redirectToBuffer = true; renderer.pageStateless = true; // needed for earlier checks when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("a")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("b")); renderer.respond(requestCycle); verify(response).write(any(byte[].class)); verify(response, never()).sendRedirect(anyString()); Assert.assertFalse(stored.get()); } /** * Tests that when the page is stateless and redirect for stateless pages is enabled then there * should be a redirect */ @Test public void testRedirectToBufferStatelessPageAndRedirectIsEsabled() { final AtomicBoolean stored = new AtomicBoolean(false); PageRenderer renderer = new TestPageRenderer(handler) { @Override protected boolean isRedirectToBuffer() { return true; } @Override protected void storeBufferedResponse(Url url, BufferedWebResponse response) { stored.set(true); } }; when(page.isPageStateless()).thenReturn(true); // needed for earlier checks when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("a")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("b")); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); Assert.assertTrue(stored.get()); } /** * Tests that when the page is stateful and the urls are different then there should be a * redirect */ @Test public void testRedirectToBufferStatefulPage() { final AtomicBoolean stored = new AtomicBoolean(false); PageRenderer renderer = new TestPageRenderer(handler) { @Override protected boolean isRedirectToBuffer() { return true; } @Override protected void storeBufferedResponse(Url url, BufferedWebResponse response) { stored.set(true); } }; // needed for earlier checks when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("a")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("b")); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); Assert.assertTrue(stored.get()); } @Test public void testShouldRenderPageAndWriteResponseCondition() { TestPageRenderer renderer = new TestPageRenderer(handler); // if // the policy is never to redirect renderer.redirectPolicy = RedirectPolicy.NEVER_REDIRECT; renderer.ajax = false; renderer.onePassRender = true; renderer.redirectToRender = true; renderer.shouldPreserveClientUrl = true; renderer.newPageInstance = true; renderer.pageStateless = true; Assert.assertTrue(renderer.shouldRenderPageAndWriteResponse(requestCycle, Url.parse("test"), Url.parse("test"))); renderer.ajax = false; renderer.onePassRender = false; renderer.redirectToRender = false; renderer.shouldPreserveClientUrl = false; renderer.newPageInstance = false; renderer.pageStateless = false; Assert.assertTrue(renderer.shouldRenderPageAndWriteResponse(requestCycle, Url.parse("test1"), Url.parse("test2"))); // or // its NOT ajax and // one pass render mode is on and NOT forced to redirect // or // the targetUrl matches current url and page is NOT stateless and NOT a new instance renderer.redirectPolicy = RedirectPolicy.AUTO_REDIRECT; renderer.ajax = false; renderer.onePassRender = true; Assert.assertTrue(renderer.shouldRenderPageAndWriteResponse(requestCycle, Url.parse("test1"), Url.parse("test2"))); renderer.redirectPolicy = RedirectPolicy.ALWAYS_REDIRECT; renderer.onePassRender = false; renderer.newPageInstance = false; renderer.pageStateless = false; Assert.assertTrue(renderer.shouldRenderPageAndWriteResponse(requestCycle, Url.parse("test"), Url.parse("test"))); // or // the targetUrl matches current url and it's redirect-to-render renderer.redirectToRender = true; Assert.assertTrue(renderer.shouldRenderPageAndWriteResponse(requestCycle, Url.parse("test"), Url.parse("test"))); renderer.pageStateless = true; renderer.newPageInstance = true; renderer.redirectToRender = true; Assert.assertTrue(renderer.shouldRenderPageAndWriteResponse(requestCycle, Url.parse("test"), Url.parse("test"))); // or // the request determines that the current url should be preserved // just render the page renderer.shouldPreserveClientUrl = true; renderer.redirectPolicy = RedirectPolicy.AUTO_REDIRECT; renderer.ajax = false; renderer.onePassRender = false; renderer.redirectToRender = false; renderer.newPageInstance = true; renderer.pageStateless = true; Assert.assertTrue(renderer.shouldRenderPageAndWriteResponse(requestCycle, Url.parse("test1"), Url.parse("test2"))); } @Test public void testShouldNOTRenderPageAndWriteResponseCondition() { TestPageRenderer renderer = new TestPageRenderer(handler); // NOT if the policy is never to redirect renderer.redirectPolicy = RedirectPolicy.AUTO_REDIRECT; // NOT or one pass render mode is on // -> or one pass render mode is on and its NOT ajax and its NOT always redirect renderer.ajax = true; renderer.onePassRender = false; // NOT or the targetUrl matches current url and the page is not stateless // or the targetUrl matches current url, page is stateless but it's redirect-to-render // --> its NOT ajax and // the targetUrl matches current url and the page is NOT stateless and its NOT a new instance // or the targetUrl matches current url and it's redirect-to-render // or the request determines that the current url should be preserved // just render the page renderer.shouldPreserveClientUrl = false; renderer.redirectToRender = true; renderer.newPageInstance = true; renderer.pageStateless = true; Assert.assertFalse(renderer.shouldRenderPageAndWriteResponse(requestCycle, Url.parse("test1"), Url.parse("test2"))); renderer.redirectToRender = false; renderer.newPageInstance = false; renderer.pageStateless = false; Assert.assertFalse(renderer.shouldRenderPageAndWriteResponse(requestCycle, Url.parse("test"), Url.parse("test"))); } @Test public void testShouldRenderPageAndWriteResponseVariationIntegrity() { int count = countVariations(new ShouldRenderPageAndWriteResponseVariations()); Assert.assertEquals(2 * 2 * 2 * 2 * 2 * 2 * 2 * 3, count); } @Test public void shouldRenderPageAndWriteResponseVariation() { String match = " X X " + " XXXX XXXX" + " X X " + " XXXX XXXX" + " " + " " + " " + " " + "XXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX" + " " + " " + " " + " " + " X XXXXXXXX" + " XXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX" + " " + " " + " " + " "; checkVariations(match, new ShouldRenderPageAndWriteResponseVariations()); } @Test public void testShouldRedirectToTargetUrlIntegrity() { int count = countVariations(new ShouldRedirectToTargetUrl()); Assert.assertEquals(2 * 3 * 2 * 2 * 2 * 2 * 2, count); } @Test public void testShouldRedirectToTargetUrl() { String match = "XXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX" + " XXXXX " + "XXXXXXXXXXXXXXXX" + " XXXXX " + "XXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX" + " XXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX" + " XXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXX"; checkVariations(match, new ShouldRedirectToTargetUrl()); } @Test public void shouldRedirectToTargetUrlCondition() { TestPageRenderer renderer = new TestPageRenderer(handler); // if // render policy is always-redirect renderer.ajax = false; renderer.redirectPolicy = RedirectPolicy.ALWAYS_REDIRECT; renderer.redirectToRender = false; renderer.newPageInstance = false; renderer.pageStateless = false; renderer.sessionTemporary = false; Assert.assertTrue(renderer.shouldRedirectToTargetUrl(requestCycle, Url.parse("test1"), Url.parse("test2"))); // or // it's redirect-to-render renderer.redirectPolicy = RedirectPolicy.AUTO_REDIRECT; renderer.redirectToRender = true; Assert.assertTrue(renderer.shouldRedirectToTargetUrl(requestCycle, Url.parse("test1"), Url.parse("test2"))); // or // its ajax and the targetUrl matches current url renderer.redirectToRender = false; renderer.ajax = true; Assert.assertTrue(renderer.shouldRedirectToTargetUrl(requestCycle, Url.parse("test"), Url.parse("test"))); // or // targetUrl DONT matches current url and // is new page instance // or // session is temporary and page is stateless renderer.ajax = false; renderer.newPageInstance = true; Assert.assertTrue(renderer.shouldRedirectToTargetUrl(requestCycle, Url.parse("test1"), Url.parse("test2"))); renderer.newPageInstance = false; renderer.sessionTemporary = true; renderer.pageStateless = true; Assert.assertTrue(renderer.shouldRedirectToTargetUrl(requestCycle, Url.parse("test1"), Url.parse("test2"))); // just redirect } @Test public void shouldNOTRedirectToTargetUrlCondition() { TestPageRenderer renderer = new TestPageRenderer(handler); // NOT if // render policy is always-redirect // AND NOT // it's redirect-to-render // AND NOT // its ajax and the targetUrl matches current url // AND NOT // targetUrl DONT matches current url and // is new page instance // or // session is temporary and page is stateless renderer.ajax=false; renderer.redirectPolicy=RedirectPolicy.AUTO_REDIRECT; renderer.redirectToRender=false; renderer.newPageInstance=false; renderer.pageStateless=false; renderer.sessionTemporary=false; Assert.assertFalse(renderer.shouldRedirectToTargetUrl(requestCycle, Url.parse("test1"), Url.parse("test2"))); } private int countVariations(AbstractVariations variations) { int count = 0; while (variations.hasNextVariation()) { count++; variations.nextVariation(); } return count; } private void checkVariations(String match, AbstractVariations variations) { int idx=0; while (variations.hasNextVariation()) { variations.nextVariation(); Assert.assertEquals(variations.toString(), match.charAt(idx) == 'X', variations.getResult()); idx++; } } private void printVariations(AbstractVariations variations) { int idx=0; System.out.print("\""); while (variations.hasNextVariation()) { System.out.print(variations.getResult() ? 'X': ' '); variations.nextVariation(); idx++; if (idx>=16) { System.out.print("\"+\n\""); idx=0; } } System.out.println("\";"); } /** * Tests that when the page is stateful and the urls are the same then the response is written * directly */ @Test public void testRedirectToBufferStatefulPageAndSameUrls() { final AtomicBoolean stored = new AtomicBoolean(false); PageRenderer renderer = new TestPageRenderer(handler) { @Override protected boolean isRedirectToBuffer() { return true; } @Override protected void storeBufferedResponse(Url url, BufferedWebResponse response) { stored.set(true); } }; when(provider.isNewPageInstance()).thenReturn(true); Url sameUrl = Url.parse("same"); // needed for earlier checks when(urlRenderer.getBaseUrl()).thenReturn(sameUrl); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(sameUrl); renderer.respond(requestCycle); verify(response).write(any(byte[].class)); verify(response, never()).sendRedirect(anyString()); Assert.assertFalse(stored.get()); } /** * Tests that when all the conditions fail the redirect_to_buffer should be used as a fallback */ @Test public void testRedirectToBufferIsFallback() { final AtomicBoolean stored = new AtomicBoolean(false); PageRenderer renderer = new TestPageRenderer(handler) { @Override protected boolean isRedirectToBuffer() { return false; } @Override protected boolean isOnePassRender() { return false; } @Override protected boolean isRedirectToRender() { return false; } @Override protected boolean isSessionTemporary() { return false; } @Override protected void storeBufferedResponse(Url url, BufferedWebResponse response) { stored.set(true); } }; when(page.isPageStateless()).thenReturn(false); when(provider.isNewPageInstance()).thenReturn(false); // needed for earlier checks when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("url1")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("url2")); renderer.respond(requestCycle); verify(response, never()).write(any(byte[].class)); verify(response).sendRedirect(isNull()); Assert.assertTrue(stored.get()); } /** * Tests that when {@link WebRequest#shouldPreserveClientUrl()} returns {@code true} and the * current request is Ajax then a redirect should be issued */ @Test public void testShouldPreserveClientUrlAndAjaxRequest() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.ajax = true; renderer.newPageInstance = true; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("base")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("base/a")); when(request.shouldPreserveClientUrl()).thenReturn(true); renderer.respond(requestCycle); verify(response).sendRedirect(isNull()); verify(response, never()).write(any(byte[].class)); } /** * Tests that when {@link RedirectPolicy#NEVER_REDIRECT} is configured but the current request * is Ajax then a redirect should still be issued */ @Test public void testNeverRedirectButAjaxRequest() { TestPageRenderer renderer = new TestPageRenderer(handler); renderer.redirectPolicy = RedirectPolicy.NEVER_REDIRECT; renderer.ajax = true; renderer.newPageInstance = true; when(urlRenderer.getBaseUrl()).thenReturn(Url.parse("base")); when(requestCycle.mapUrlFor(eq(handler))).thenReturn(Url.parse("base/a")); renderer.respond(requestCycle); verify(response).sendRedirect(isNull()); verify(response, never()).write(any(byte[].class)); } }