Revision: 895 http://jwebunit.svn.sourceforge.net/jwebunit/?rev=895&view=rev Author: henryju Date: 2011-03-14 09:22:38 +0000 (Mon, 14 Mar 2011)
Log Message: ----------- [3190055] Fixed support of same named cookies/headers. Modified Paths: -------------- trunk/jwebunit-code-generator/src/main/javacc/JWebUnit.jj trunk/jwebunit-code-generator/src/main/javacc/WebTestCase.jj trunk/jwebunit-commons-tests/src/main/java/net/sourceforge/jwebunit/tests/WebCookieTest.java trunk/jwebunit-commons-tests/src/main/java/net/sourceforge/jwebunit/tests/util/CookiesServlet.java trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/api/ITestingEngine.java trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/junit/WebTester.java trunk/jwebunit-htmlunit-plugin/src/main/java/net/sourceforge/jwebunit/htmlunit/HtmlUnitTestingEngineImpl.java trunk/jwebunit-selenium-plugin/src/main/java/net/sourceforge/jwebunit/selenium/SeleniumTestingEngineImpl.java trunk/src/changes/changes.xml Added Paths: ----------- trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/api/HttpHeader.java Modified: trunk/jwebunit-code-generator/src/main/javacc/JWebUnit.jj =================================================================== --- trunk/jwebunit-code-generator/src/main/javacc/JWebUnit.jj 2011-01-27 13:42:12 UTC (rev 894) +++ trunk/jwebunit-code-generator/src/main/javacc/JWebUnit.jj 2011-03-14 09:22:38 UTC (rev 895) @@ -493,6 +493,7 @@ sb.append("import java.util.List;\n"); sb.append("import java.util.Map;\n"); sb.append("import java.net.URL;\n\n"); + sb.append("import net.sourceforge.jwebunit.api.HttpHeader;\n"); sb.append("import net.sourceforge.jwebunit.api.IElement;\n"); sb.append("import net.sourceforge.jwebunit.api.ITestingEngine;\n"); sb.append("import net.sourceforge.jwebunit.exception.TestingEngineResponseException;\n"); Modified: trunk/jwebunit-code-generator/src/main/javacc/WebTestCase.jj =================================================================== --- trunk/jwebunit-code-generator/src/main/javacc/WebTestCase.jj 2011-01-27 13:42:12 UTC (rev 894) +++ trunk/jwebunit-code-generator/src/main/javacc/WebTestCase.jj 2011-03-14 09:22:38 UTC (rev 895) @@ -493,6 +493,7 @@ sb.append("import java.util.List;\n"); sb.append("import java.util.Map;\n"); sb.append("import java.net.URL;\n\n"); + sb.append("import net.sourceforge.jwebunit.api.HttpHeader;\n"); sb.append("import net.sourceforge.jwebunit.api.IElement;\n"); sb.append("import net.sourceforge.jwebunit.api.ITestingEngine;\n"); sb.append("import net.sourceforge.jwebunit.exception.TestingEngineResponseException;\n"); Modified: trunk/jwebunit-commons-tests/src/main/java/net/sourceforge/jwebunit/tests/WebCookieTest.java =================================================================== --- trunk/jwebunit-commons-tests/src/main/java/net/sourceforge/jwebunit/tests/WebCookieTest.java 2011-01-27 13:42:12 UTC (rev 894) +++ trunk/jwebunit-commons-tests/src/main/java/net/sourceforge/jwebunit/tests/WebCookieTest.java 2011-03-14 09:22:38 UTC (rev 895) @@ -19,16 +19,21 @@ package net.sourceforge.jwebunit.tests; +import java.util.List; +import net.sourceforge.jwebunit.api.HttpHeader; +import org.junit.Test; + import static net.sourceforge.jwebunit.junit.JWebUnit.assertCookiePresent; import static net.sourceforge.jwebunit.junit.JWebUnit.assertCookieValueEquals; import static net.sourceforge.jwebunit.junit.JWebUnit.assertCookieValueMatch; import static net.sourceforge.jwebunit.junit.JWebUnit.assertTextPresent; import static net.sourceforge.jwebunit.junit.JWebUnit.beginAt; +import static net.sourceforge.jwebunit.junit.JWebUnit.getResponseHeaders; import static net.sourceforge.jwebunit.junit.JWebUnit.getTestContext; import static net.sourceforge.jwebunit.junit.JWebUnit.gotoPage; import static net.sourceforge.jwebunit.junit.JWebUnit.setBaseUrl; +import static org.junit.Assert.assertTrue; -import org.junit.Test; /** * Test the Cookies methods provided by WebTestCase. @@ -44,38 +49,56 @@ setBaseUrl(HOST_PATH); } - @Test public void testAddCookie() { + @Test + public void testAddCookie() { beginAt("/cookies.jsp"); assertTextPresent("cookie1=Cookievalue1"); } - @Test public void testAddAnotherCookie() { + @Test + public void testAddAnotherCookie() { getTestContext().addCookie("cookie2", "Cookievalue2", "localhost"); beginAt("/cookies.jsp"); assertTextPresent("cookie1=Cookievalue1"); assertTextPresent("cookie2=Cookievalue2"); } - @Test public void testAssertCookiePresent() throws Throwable { + @Test + public void testAssertCookiePresent() throws Throwable { beginAt("/cookies.jsp"); assertCookiePresent("serveurCookie"); } - @Test public void testAssertCookieValue() throws Throwable { + @Test + public void testAssertCookieValue() throws Throwable { beginAt("/cookies.jsp"); assertCookieValueEquals("serveurCookie", "foo"); } - @Test public void testAssertCookieMatch() throws Throwable { + @Test + public void testAssertCookieMatch() throws Throwable { beginAt("/cookies.jsp"); assertCookieValueMatch("serveurCookie", "fo*"); } /** + * When there are several cookies with the same name, it is the last one that should + * be taken. + * See <a href="http://tools.ietf.org/html/draft-ietf-httpstate-cookie-21#section-5.3">the spec</a> (ยง 11) + */ + @Test + public void testCookieMatchLastCookie() { + beginAt("/cookies.jsp?threesamecookies=true&dont_set=1"); + assertCookieValueMatch("JSESSIONID", "(.)*worker3"); + } + + + /** * Test that the cookie still exists across multiple requests, * even if the cookie is not explicitly set each time. */ - @Test public void testCookieWithoutExplicitSet() { + @Test + public void testCookieWithoutExplicitSet() { beginAt("/cookies.jsp"); // beginAt also resets cookies assertCookieValueEquals("serveurCookie", "foo"); gotoPage("/cookies.jsp?dont_set=1"); @@ -84,8 +107,34 @@ assertCookieValueEquals("serveurCookie", "foo"); // should still be there gotoPage("/cookies.jsp?dont_set=1"); assertCookieValueEquals("serveurCookie", "foo"); // should still be there - - } + /** + * Tests if all cookies are received when the server sets several cookies + * with same domain, path and name.<p> + * + * See http://tools.ietf.org/html/draft-ietf-httpstate-cookie-21#section-5.3, 11 + */ + @Test + public void testCookieSetInHeaders() { + beginAt("/cookies.jsp?threesamecookies=true&dont_set=1"); + List<HttpHeader> headers = getResponseHeaders(); + boolean foundCookie1 = false; + boolean foundCookie2 = false; + boolean foundCookie3 = false; + for (HttpHeader h : headers) { + if (h.getName().equals("Set-Cookie")) { + if (h.getValue().contains(".worker1")) { + foundCookie1 = true; + } + else if (h.getValue().contains(".worker2")) { + foundCookie2 = true; + } + else if (h.getValue().contains(".worker3")) { + foundCookie3 = true; + } + } + } + assertTrue("getResponseHeaders should return all headers even duplicates", foundCookie1 && foundCookie2 && foundCookie3); + } } \ No newline at end of file Modified: trunk/jwebunit-commons-tests/src/main/java/net/sourceforge/jwebunit/tests/util/CookiesServlet.java =================================================================== --- trunk/jwebunit-commons-tests/src/main/java/net/sourceforge/jwebunit/tests/util/CookiesServlet.java 2011-01-27 13:42:12 UTC (rev 894) +++ trunk/jwebunit-commons-tests/src/main/java/net/sourceforge/jwebunit/tests/util/CookiesServlet.java 2011-03-14 09:22:38 UTC (rev 895) @@ -72,6 +72,40 @@ Cookie cookie = new Cookie("serveurCookie","foo"); response.addCookie(cookie); } + + /* + * To test if serveral same cookies with same path, domain and name + * are passed through to the test API. This "should" not be done by a + * server but there are use cases where it has to be done. One example is + * the JSESSIONID cookie which is set by Tomcat but has to be modified in a + * mod_jk - clustered environment in order to let the client jump to another + * worker (-> Tomcat cluster member). However within the web application the + * JSESSIONID cookie has already been added to the response and cannot be + * removed from there via API. Solution is to set another cookie to overwrite this. + * + * See http://tools.ietf.org/html/draft-ietf-httpstate-cookie-21#section-5.3, 11 + */ + if(request.getParameter("threesamecookies") != null) { + // 1 + Cookie jsessionIDCookie = new Cookie("JSESSIONID", "07D486AC962DE67F176F70B7C9816AAE.worker1"); + jsessionIDCookie.setPath("/"); + // session cookie: + jsessionIDCookie.setMaxAge(-2); + jsessionIDCookie.setDomain("localhost"); + response.addCookie(jsessionIDCookie); + // 2 + jsessionIDCookie = new Cookie("JSESSIONID", "07D486AC962DE67F176F70B7C9816AAE.worker2"); + jsessionIDCookie.setMaxAge(-2); + jsessionIDCookie.setDomain("localhost"); + response.addCookie(jsessionIDCookie); + + // 3 + jsessionIDCookie = new Cookie("JSESSIONID", "07D486AC962DE67F176F70B7C9816AAE.worker3"); + jsessionIDCookie.setMaxAge(-2); + jsessionIDCookie.setDomain("localhost"); + jsessionIDCookie.setSecure(true); + response.addCookie(jsessionIDCookie); + } } } Added: trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/api/HttpHeader.java =================================================================== --- trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/api/HttpHeader.java (rev 0) +++ trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/api/HttpHeader.java 2011-03-14 09:22:38 UTC (rev 895) @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2010, JWebUnit team. + * + * This file is part of JWebUnit. + * + * JWebUnit is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * JWebUnit is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with JWebUnit. If not, see <http://www.gnu.org/licenses/>. + */ + +package net.sourceforge.jwebunit.api; + +/** + * A name/value pair to store HTTP headers. + * + * Inspired from HtmlUnit NameValuePair. + * @author Julien HENRY + */ +public class HttpHeader { + + /** The name. */ + private final String name_; + + /** The value. */ + private final String value_; + + /** + * Creates a new instance. + * @param name the name + * @param value the value + */ + public HttpHeader(final String name, final String value) { + name_ = name; + value_ = value; + } + + /** + * Returns the name. + * @return the name + */ + public String getName() { + return name_; + } + + /** + * Returns the value. + * @return the value + */ + public String getValue() { + return value_; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return name_ + "=" + value_; + } + +} Property changes on: trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/api/HttpHeader.java ___________________________________________________________________ Added: svn:mime-type + text/plain Modified: trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/api/ITestingEngine.java =================================================================== --- trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/api/ITestingEngine.java 2011-01-27 13:42:12 UTC (rev 894) +++ trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/api/ITestingEngine.java 2011-03-14 09:22:38 UTC (rev 895) @@ -19,6 +19,8 @@ package net.sourceforge.jwebunit.api; +import java.util.Map; + import java.io.InputStream; import java.net.URL; import java.util.List; @@ -907,22 +909,30 @@ */ String getHeader(String name); - /** - * Get all headers. - * - * @return The header values stored in a map. - */ - java.util.Map<String,String> getAllHeaders(); - - /** - * Should the tester ignore failing status codes (300+)? Otherwise, - * failing status codes will throw an exception. - * - * @param ignore - */ - public void setIgnoreFailingStatusCodes(boolean ignore); - /** + * Get all distinct response headers. In case there are duplicate headers with same name, the last one will be returned. + * + * @return The header values stored in a map. + * @deprecated Use {@link #getResponseHeaders()} + */ + @Deprecated + Map<String, String> getAllHeaders(); + + /** + * Get all response headers. + * @return the response headers as a list of {@link HttpHeader}s + */ + List<HttpHeader> getResponseHeaders(); + + /** + * Should the tester ignore failing status codes (300+)? Otherwise, + * failing status codes will throw an exception. + * + * @param ignore + */ + public void setIgnoreFailingStatusCodes(boolean ignore); + + /** * Get all the comments in a document, as a list of strings. */ public List<String> getComments(); Modified: trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/junit/WebTester.java =================================================================== --- trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/junit/WebTester.java 2011-01-27 13:42:12 UTC (rev 894) +++ trunk/jwebunit-core/src/main/java/net/sourceforge/jwebunit/junit/WebTester.java 2011-03-14 09:22:38 UTC (rev 895) @@ -37,10 +37,9 @@ import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; - import javax.imageio.ImageIO; import javax.servlet.http.Cookie; - +import net.sourceforge.jwebunit.api.HttpHeader; import net.sourceforge.jwebunit.api.IElement; import net.sourceforge.jwebunit.api.ITestingEngine; import net.sourceforge.jwebunit.exception.ExpectedJavascriptAlertException; @@ -54,7 +53,6 @@ import net.sourceforge.jwebunit.javascript.JavascriptPrompt; import net.sourceforge.jwebunit.util.TestContext; import net.sourceforge.jwebunit.util.TestingEngineRegistry; - import org.apache.regexp.RE; import org.apache.regexp.RESyntaxException; @@ -399,10 +397,21 @@ * Get all response headers. * * @return A map of response headers + * @deprecated This method do not deal with several headers with same name. Use {@link #getResponseHeaders()} instead. */ + @Deprecated public Map<String, String> getAllHeaders() { - return getTestingEngine().getAllHeaders(); + return getTestingEngine().getAllHeaders(); } + + /** + * Return all HTTP headers that are in last response. It is possible to have several headers with same name. + * + * @return A list of {@link HttpHeader} elements. + */ + public List<HttpHeader> getResponseHeaders() { + return getTestingEngine().getResponseHeaders(); + } /** * Assert title of current html page in conversation matches an expected @@ -2269,12 +2278,11 @@ List<?> cookies = getTestingEngine().getCookies(); for (Iterator<?> i = cookies.iterator(); i.hasNext();) { Cookie c = (Cookie) i.next(); - if (c.getName().equals(cookieName)) { - assertEquals(expectedValue, c.getValue()); + if (c.getName().equals(cookieName) && c.getValue().equals(expectedValue)) { return; } } - fail("Should not be reached"); + fail("Could not find cookie with name [" + cookieName + "] and value [" + expectedValue + "]"); } /** @@ -2289,19 +2297,17 @@ try { re = new RE(regexp, RE.MATCH_SINGLELINE); } catch (RESyntaxException e) { - fail(e.toString()); + fail(e.getMessage()); } List<?> cookies = getTestingEngine().getCookies(); for (Iterator<?> i = cookies.iterator(); i.hasNext();) { Cookie c = (Cookie) i.next(); - if (c.getName().equals(cookieName)) { - assertTrue("Unable to match [" + regexp - + "] in cookie \"" + cookieName + "\"", re.match(c - .getValue())); + if (c.getName().equals(cookieName) && + re.match(c.getValue())) { return; } } - fail("Should not be reached"); + fail("Could not find cookie with name [" + cookieName + "] with value matching [" + regexp + "]"); } // Form interaction methods Modified: trunk/jwebunit-htmlunit-plugin/src/main/java/net/sourceforge/jwebunit/htmlunit/HtmlUnitTestingEngineImpl.java =================================================================== --- trunk/jwebunit-htmlunit-plugin/src/main/java/net/sourceforge/jwebunit/htmlunit/HtmlUnitTestingEngineImpl.java 2011-01-27 13:42:12 UTC (rev 894) +++ trunk/jwebunit-htmlunit-plugin/src/main/java/net/sourceforge/jwebunit/htmlunit/HtmlUnitTestingEngineImpl.java 2011-03-14 09:22:38 UTC (rev 895) @@ -19,6 +19,8 @@ package net.sourceforge.jwebunit.htmlunit; +import net.sourceforge.jwebunit.api.HttpHeader; + import org.apache.http.auth.AuthScope; import java.io.IOException; @@ -2331,6 +2333,7 @@ /* (non-Javadoc) * @see net.sourceforge.jwebunit.api.ITestingEngine#getAllHeaders() */ + @Deprecated public Map<String, String> getAllHeaders() { Map<String, String> map = new java.util.HashMap<String, String>(); for (NameValuePair header : getWebResponse().getResponseHeaders()) { @@ -2338,6 +2341,14 @@ } return map; } + + public List<HttpHeader> getResponseHeaders() { + List<HttpHeader> result = new LinkedList<HttpHeader>(); + for (NameValuePair header : getWebResponse().getResponseHeaders()) { + result.add(new HttpHeader(header.getName(), header.getValue())); + } + return result; + } /** * An alternative to setting the {@link TestContext#setUserAgent(String) user agent string manually} Modified: trunk/jwebunit-selenium-plugin/src/main/java/net/sourceforge/jwebunit/selenium/SeleniumTestingEngineImpl.java =================================================================== --- trunk/jwebunit-selenium-plugin/src/main/java/net/sourceforge/jwebunit/selenium/SeleniumTestingEngineImpl.java 2011-01-27 13:42:12 UTC (rev 894) +++ trunk/jwebunit-selenium-plugin/src/main/java/net/sourceforge/jwebunit/selenium/SeleniumTestingEngineImpl.java 2011-03-14 09:22:38 UTC (rev 895) @@ -20,6 +20,8 @@ package net.sourceforge.jwebunit.selenium; +import net.sourceforge.jwebunit.api.HttpHeader; + import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; @@ -720,10 +722,16 @@ /* (non-Javadoc) * @see net.sourceforge.jwebunit.api.ITestingEngine#getAllHeaders() */ + @Deprecated public Map<String, String> getAllHeaders() { // TODO implement method throw new UnsupportedOperationException("getAllHeaders"); } + + public List<HttpHeader> getResponseHeaders() { + // TODO implement method + throw new UnsupportedOperationException("getResponseHeaders"); + } /* (non-Javadoc) * @see net.sourceforge.jwebunit.api.ITestingEngine#getHeader(java.lang.String) Modified: trunk/src/changes/changes.xml =================================================================== --- trunk/src/changes/changes.xml 2011-01-27 13:42:12 UTC (rev 894) +++ trunk/src/changes/changes.xml 2011-03-14 09:22:38 UTC (rev 895) @@ -32,6 +32,12 @@ </properties> <body> <release version="3.0" date="UNKNOW" description="Updated all internals to JUnit 4"> + <action type="fix" dev="henryju" issue="3190055" due-to="Achim Westermann"> + Fixed handling of several cookies/headers with same name. getAllHeaders() was wrongly returning only the latest header + header with the same name so this method was deprecated and a new one was added with a different return type. + See getResponseHeaders(). + AssertCookiePresent/Match was also updated to take the last set cookie of the given name instead of the first one. + </action> <action type="add" dev="henryju" issue="3166502" due-to="Harri"> Added indexed alternatives of methods clickLinkWithImage, assertLinkPresentWithImage and assertLinkNotPresentWithImage. </action> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Colocation vs. Managed Hosting A question and answer guide to determining the best fit for your organization - today and in the future. http://p.sf.net/sfu/internap-sfd2d _______________________________________________ JWebUnit-development mailing list JWebUnit-development@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jwebunit-development