/* * 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.util.tester; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.servlet.http.Cookie; import org.apache.wicket.protocol.http.mock.Cookies; import org.apache.wicket.util.tester.apps_1.CreateBook; import org.apache.wicket.util.tester.cookies.CollectAllRequestCookiesPage; import org.apache.wicket.util.tester.cookies.EndPage; import org.apache.wicket.util.tester.cookies.SetCookiePage; import org.junit.Assert; import org.junit.Test; /** * test code for wicket tester cookie handling * * @author mosmann */ public class WicketTesterCookieTest extends WicketTestCase { /** * */ @Test public void cookieIsFoundWhenAddedToRequest() { tester.getRequest().addCookie(new Cookie("name", "value")); assertEquals("value", tester.getRequest().getCookie("name").getValue()); } /** * */ @Test public void cookieIsFoundWhenAddedToResponse() { tester.startPage(CreateBook.class); tester.getLastResponse().addCookie(new Cookie("name", "value")); Collection<Cookie> cookies = tester.getLastResponse().getCookies(); assertEquals(cookies.iterator().next().getValue(), "value"); } /** * Tests that setting a cookie with age > 0 before creating the page will survive after the * rendering of the page and it will be used for the next request cycle. */ @Test public void transferCookies() { String cookieName = "wicket4289Name"; String cookieValue = "wicket4289Value"; int cookieAge = 1; // age > 0 => the cookie will be preserved for the the next request cycle Cookie cookie = new Cookie(cookieName, cookieValue); cookie.setMaxAge(cookieAge); tester.getRequest().addCookie(cookie); CookiePage page = new CookiePage(cookieName, cookieValue); tester.startPage(page); // assert that the cookie was in the response List<Cookie> cookies = tester.getLastResponse().getCookies(); assertEquals(1, cookies.size()); Cookie cookie2 = cookies.get(0); assertEquals(cookieName, cookie2.getName()); assertEquals(cookieValue, cookie2.getValue()); assertEquals(cookieAge, cookie2.getMaxAge()); // assert that the cookie will be preserved for the next request assertEquals(cookieValue, tester.getRequest().getCookie(cookieName).getValue()); } /** * Tests that setting a cookie with age == 0 will not be stored after the request cycle. */ @Test public void dontTransferCookiesWithNegativeAge() { String cookieName = "wicket4289Name"; String cookieValue = "wicket4289Value"; int cookieAge = 0; // age = 0 => do not store it Cookie cookie = new Cookie(cookieName, cookieValue); cookie.setMaxAge(cookieAge); tester.getRequest().addCookie(cookie); CookiePage page = new CookiePage(cookieName, cookieValue); tester.startPage(page); // assert that the cookie is not preserved for the next request cycle assertNull(tester.getRequest().getCookies()); } /** * Tests that setting a cookie with age < 0 will not be stored after the request cycle. */ @Test public void dontTransferCookiesWithZeroAge() { String cookieName = "wicket4289Name"; String cookieValue = "wicket4289Value"; int cookieAge = 0; // age == 0 => delete the cookie Cookie cookie = new Cookie(cookieName, cookieValue); cookie.setMaxAge(cookieAge); tester.getRequest().addCookie(cookie); CookiePage page = new CookiePage(cookieName, cookieValue); tester.startPage(page); // assert that the cookie is not preserved for the next request cycle assertNull(tester.getRequest().getCookies()); } /** * A cookie set in the request headers should not be * expected in the response headers unless the page * sets it explicitly. * * https://issues.apache.org/jira/browse/WICKET-4989 */ @Test public void cookieSetInRequestShouldNotBeInResponse() { //start and render the test page tester.getRequest().addCookie(new Cookie("dummy", "sample")); tester.startPage(tester.getApplication().getHomePage()); //assert rendered page class tester.assertRenderedPage(tester.getApplication().getHomePage()); Assert.assertEquals("The cookie should not be in the response unless explicitly set", 0, tester.getLastResponse().getCookies().size()); // The cookie should be in each following request unless the server code // schedules it for removal it with cookie.setMaxAge(0) Assert.assertEquals("The cookie should be in each following request", 1, tester.getRequest().getCookies().length); } /** * The response cookie should not be the same instance as the request * cookie. * * https://issues.apache.org/jira/browse/WICKET-4989 */ @Test public void doNotReuseTheSameInstanceOfTheCookieForRequestAndResponse() { //start and render the test page String cookieName = "cookieName"; String cookieValue = "cookieValue"; Cookie requestCookie = new Cookie(cookieName, cookieValue); tester.getRequest().addCookie(requestCookie); tester.startPage(new CookiePage(cookieName, cookieValue)); //assert rendered page class tester.assertRenderedPage(CookiePage.class); Cookie responseCookie = tester.getLastResponse().getCookies().get(0); requestCookie.setValue("valueChanged"); Assert.assertEquals(cookieValue, responseCookie.getValue()); } /** * @see WicketTester * * TODO add a cookie to request, which should override cookie from last response and last request * https://issues.apache.org/jira/browse/WICKET-5147 */ @Test public void wicketTesterCookieHandlingWithoutRedirect() { // no cookies set CollectAllRequestCookiesPage collectingPage = collectAllRequestCookiesOnThisPage(); Assert.assertTrue("no cookie in first request",collectingPage.getCookies().isEmpty()); lastResponseDoesNotHaveAnyCookies(); responseDoesNotHaveAnyCookies(); requestDoesNotHaveAnyCookies(); // set cookie on request Cookie firstCookie = newCookie("a","firstValue",1); tester.getRequest().addCookie(firstCookie); collectingPage = collectAllRequestCookiesOnThisPage(); requestOnPageShouldHaveTheseCookies(collectingPage, firstCookie); lastResponseDoesNotHaveAnyCookies(); requestShouldHaveTheseCookies(firstCookie); responseDoesNotHaveAnyCookies(); // cookies from last request should appear on following requests collectingPage = collectAllRequestCookiesOnThisPage(); requestOnPageShouldHaveTheseCookies(collectingPage, firstCookie); lastResponseDoesNotHaveAnyCookies(); requestShouldHaveTheseCookies(firstCookie); responseDoesNotHaveAnyCookies(); // cookie will be overwritten if response will do so Cookie cookieSetInResponse = newCookie("a","overwriteWithNewValue",1); setCookieInResponse(cookieSetInResponse); lastResponseShouldHaveTheseCookies(cookieSetInResponse); requestShouldHaveTheseCookies(cookieSetInResponse); // cookies from last response then should appear on following requests collectingPage = collectAllRequestCookiesOnThisPage(); requestOnPageShouldHaveTheseCookies(collectingPage, cookieSetInResponse); lastResponseDoesNotHaveAnyCookies(); requestShouldHaveTheseCookies(cookieSetInResponse); // cookies from requests will be deleted if the response will do so Cookie expiredCookieSetInResponse = newCookie("a","removeMe",0); setCookieInResponse(expiredCookieSetInResponse); lastResponseShouldHaveTheseCookies(expiredCookieSetInResponse); responseDoesNotHaveAnyCookies(); requestDoesNotHaveAnyCookies(); // no cookies in next request while last cookie was deleted collectingPage = collectAllRequestCookiesOnThisPage(); requestOnPageShouldHaveTheseCookies(collectingPage); lastResponseDoesNotHaveAnyCookies(); requestDoesNotHaveAnyCookies(); responseDoesNotHaveAnyCookies(); } /** * @see WicketTesterCookieTest#wicketTesterCookieHandlingWithoutRedirect() * * https://issues.apache.org/jira/browse/WICKET-5147 */ @Test public void wicketTesterCookieHandlingWithRedirect() { // set cookie in response then redirect to other page Cookie firstCookie = newCookie("a","firstValue",1); setCookieInResponseAndRedirect(firstCookie); lastResponseShouldHaveTheseCookies(firstCookie); requestShouldHaveTheseCookies(firstCookie); // cookie in response after redirect should appear in next request CollectAllRequestCookiesPage collectingPage = collectAllRequestCookiesOnThisPage(); requestOnPageShouldHaveTheseCookies(collectingPage,firstCookie); lastResponseDoesNotHaveAnyCookies(); requestShouldHaveTheseCookies(firstCookie); responseDoesNotHaveAnyCookies(); // set cookie on request and overwrite in response then redirect to other page Cookie cookieSetInRequest = newCookie("a","valueFromRequest",1); Cookie cookieSetInResponse = newCookie("a","overwriteInResponse",1); tester.getRequest().addCookie(cookieSetInRequest); setCookieInResponseAndRedirect(cookieSetInResponse); lastResponseShouldHaveTheseCookies(cookieSetInResponse); requestShouldHaveTheseCookies(cookieSetInResponse); // cookie in response after redirect should appear in next request collectingPage = collectAllRequestCookiesOnThisPage(); requestOnPageShouldHaveTheseCookies(collectingPage,cookieSetInResponse); lastResponseDoesNotHaveAnyCookies(); requestShouldHaveTheseCookies(cookieSetInResponse); responseDoesNotHaveAnyCookies(); // set cookie on request and remove it in response then redirect to other page Cookie nextCookieSetInRequest = newCookie("a","nextValueFromRequest",1); Cookie nextCookieSetInResponse = newCookie("a","newValue",0); tester.getRequest().addCookie(nextCookieSetInRequest); setCookieInResponseAndRedirect(nextCookieSetInResponse); lastResponseShouldHaveTheseCookies(nextCookieSetInResponse); requestDoesNotHaveAnyCookies(); responseDoesNotHaveAnyCookies(); // no cookies left collectingPage = collectAllRequestCookiesOnThisPage(); requestOnPageShouldHaveTheseCookies(collectingPage); lastResponseDoesNotHaveAnyCookies(); requestDoesNotHaveAnyCookies(); responseDoesNotHaveAnyCookies(); } /** * creates a new cookie with maxAge set * @param name name * @param value value * @param maxAge maxAge * @return a cookie */ private static Cookie newCookie(String name,String value, int maxAge) { Cookie cookie = new Cookie(name,value); cookie.setMaxAge(maxAge); return cookie; } /** * start a page which collects all cookies from request * @return the page */ private CollectAllRequestCookiesPage collectAllRequestCookiesOnThisPage() { return tester.startPage(CollectAllRequestCookiesPage.class); } /** * start a page which set a cookie in response * @param cookie cookie */ private void setCookieInResponse(Cookie cookie) { tester.startPage(new SetCookiePage(cookie)); } /** * start a page which set a cookie in response and then redirect to different page * @param cookie cookie */ private void setCookieInResponseAndRedirect(Cookie cookie) { tester.startPage(new SetCookiePage(cookie,EndPage.class)); } /** * check cookies collected by page * @param page page * @param cookies cookies */ private void requestOnPageShouldHaveTheseCookies(CollectAllRequestCookiesPage page, Cookie...cookies) { listShouldMatchAll(page.getCookies(), cookies); } /** * check cookies in current request * @param cookies cookies */ private void requestShouldHaveTheseCookies(Cookie...cookies) { Cookie[] cookieFromRequest = tester.getRequest().getCookies(); listShouldMatchAll(cookieFromRequest!=null ? Arrays.asList(cookieFromRequest) : new ArrayList<Cookie>(), cookies); } /** * check if every cookie is found in the list and no cookie is left * @param cookieList cookie list * @param cookies cookies to check */ private void listShouldMatchAll(List<Cookie> cookieList, Cookie... cookies) { Map<String, Cookie> cookieMap = cookiesFromList(cookieList); for (Cookie cookie : cookies) { Cookie removed = cookieMap.remove(cookie.getName()); Assert.assertNotNull("Cookie "+cookie.getName(),removed); Assert.assertTrue("Cookie "+cookie.getName()+" matches",Cookies.isEqual(cookie, removed)); } Assert.assertTrue("no cookies left "+asString(cookieMap),cookieMap.isEmpty()); } /** * make cookie map more readable * @param cookieMap cookie map * @return string */ private static String asString(Map<String, Cookie> cookieMap) { StringBuilder sb=new StringBuilder(); sb.append('{'); for (Map.Entry<String, Cookie> e : cookieMap.entrySet()) { sb.append(e.getKey()).append('=').append(asString(e.getValue())); sb.append(","); } sb.append('}'); return sb.toString(); } /** * make cookie more readable * @param c cookie * @return string */ private static String asString(Cookie c) { StringBuilder sb=new StringBuilder(); sb.append('['); sb.append("name=").append(c.getName()).append(','); sb.append("value=").append(c.getValue()).append(','); sb.append("maxAge=").append(c.getMaxAge()); sb.append(']'); return sb.toString(); } /** * check last response cookies * @param cookies cookies */ private void lastResponseShouldHaveTheseCookies(Cookie...cookies) { listShouldMatchAll(tester.getLastResponse().getCookies(), cookies); } /** * response should not have any cookies */ private void lastResponseDoesNotHaveAnyCookies() { listShouldMatchAll(tester.getLastResponse().getCookies()); } /** * response should not have any cookies */ private void responseDoesNotHaveAnyCookies() { listShouldMatchAll(tester.getResponse().getCookies()); } /** * request should not have any cookies */ private void requestDoesNotHaveAnyCookies() { requestShouldHaveTheseCookies(); } /** * create a cookie map based on cookie name * @param cookies cookie list * @return as map * @throws RuntimeException if more than one cookie with the same name */ private static Map<String,Cookie> cookiesFromList(List<Cookie> cookies) { Map<String, Cookie> ret = new LinkedHashMap<String, Cookie>(); for (Cookie cookie : cookies) { Cookie oldValue = ret.put(cookie.getName(), cookie); if (oldValue != null) { throw new RuntimeException(String.format("Cookie with name '%s' ('%s') already in map %s", cookie.getName(), asString(oldValue), asString(ret))); } } return ret; } }