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

Reply via email to