001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.wicket.markup.html.form.persistence;
018:
019: import java.util.List;
020:
021: import javax.servlet.http.Cookie;
022:
023: import junit.framework.TestCase;
024:
025: import org.apache.wicket.Page;
026: import org.apache.wicket.RequestCycle;
027: import org.apache.wicket.markup.html.form.TextField;
028: import org.apache.wicket.markup.html.form.persistence.CookieValuePersisterTestPage.TestForm;
029: import org.apache.wicket.protocol.http.MockHttpServletRequest;
030: import org.apache.wicket.protocol.http.MockHttpServletResponse;
031: import org.apache.wicket.protocol.http.WebRequest;
032: import org.apache.wicket.protocol.http.WebRequestCycle;
033: import org.apache.wicket.protocol.http.WebResponse;
034: import org.apache.wicket.util.tester.WicketTester;
035:
036: /**
037: * How to test CookieValuePersister. Problem: CookieValuePersister relies on
038: * RequestCycle.get().getApplication() to access application settings.
039: * RequestCycle.get() however is valid only during the render process. It get's
040: * automatically attached and detached. Thus RequestCycle.get() will be NULL
041: * before and after render. Thus CookieValuePersister can not be tested outside
042: * the render process. You may think you can subclass CookieValuePersister and
043: * provide your own getSettings(). Unfortunately you can't as it is private. One
044: * more note: Though CookieValuePersister could probably be re-arranged in a way
045: * that RequestCycle.get() is no longer a problem, the next (testing-) problem
046: * can not be solved. Cookies are added to the response and based on the servlet
047: * api, the response has no means to validate (read) the already added cookies.
048: * But the MockResponse does !?!?. The only solution I came up with so far is
049: * indirect testing. Create a page with a form and a form component. Enable the
050: * component to be persistent. The first run should give you a null value, as no
051: * values are currently stored. Than set a new value and submit the form. The
052: * component's values will (hopefully) be saved. Refresh the same page and voala
053: * the saved values should be automatically loaded.
054: *
055: * @author Juergen Donnerstag
056: */
057: public class CookieValuePersisterTest extends TestCase {
058: private WicketTester application;
059:
060: protected void setUp() throws Exception {
061: application = new WicketTester();
062: application.startPage(CookieValuePersisterTestPage.class);
063: }
064:
065: protected void tearDown() throws Exception {
066: application.destroy();
067: }
068:
069: /**
070: *
071: * @throws Exception
072: */
073: public void test1() throws Exception {
074: // How does the test work: Make sure you have a page, form and form
075: // component properly set up (getRelativePath() etc.). See setUp().
076: final Page page = application.getLastRenderedPage();
077:
078: // Get the form and form component created
079: final TestForm form = (TestForm) page.get("form");
080: final TextField textField = (TextField) form.get("input");
081:
082: // Make sure a valid cycle is available through RequestCycle.get().
083: // The RequestCycle's constructor will attach the new cycle to
084: // the threadLocal retrieved by RequestCycle.get().
085: // Attached to this cycle must be a valid request and response
086: final WebRequestCycle cycle = application.createRequestCycle();
087:
088: // Just after init, the requests and responses cookie lists must be
089: // empty
090: assertNull(getRequestCookies(cycle));
091: assertEquals(0, getResponseCookies(cycle).size());
092:
093: // The persister to be used for the tests
094: final CookieValuePersister persister = new CookieValuePersister();
095:
096: // See comment on CookieValuePersister on how clearing a value with
097: // Cookies works. As no cookies in the request, no "delete" cookie
098: // will be added to the response.
099: persister.clear(textField);
100: assertNull(getRequestCookies(cycle));
101: assertEquals(0, getResponseCookies(cycle).size());
102:
103: // Save the input field's value (add it to the response's cookie list)
104: persister.save(textField);
105: assertNull(getRequestCookies(cycle));
106: assertEquals(1, getResponseCookies(cycle).size());
107: assertEquals("test",
108: ((Cookie) getResponseCookies(cycle).get(0)).getValue());
109: assertEquals("form:input", ((Cookie) getResponseCookies(cycle)
110: .get(0)).getName());
111: assertEquals("/", ((Cookie) getResponseCookies(cycle).get(0))
112: .getPath());
113:
114: // To clear in the context of cookies means to add a special cookie
115: // (maxAge=0) to the response, provided a cookie with
116: // the same name has been provided in the request. Thus, no changes in
117: // our test case
118: persister.clear(textField);
119: assertNull(getRequestCookies(cycle));
120: assertEquals(1, getResponseCookies(cycle).size());
121: assertEquals("test",
122: ((Cookie) getResponseCookies(cycle).get(0)).getValue());
123: assertEquals("form:input", ((Cookie) getResponseCookies(cycle)
124: .get(0)).getName());
125: assertEquals("/", ((Cookie) getResponseCookies(cycle).get(0))
126: .getPath());
127:
128: // Try to load it. Because there is no Cookie matching the textfield's name
129: // it remains unchanged
130: persister.load(textField);
131: assertEquals("test", textField.getModelObjectAsString());
132:
133: // Simulate loading a textfield. Initialize textfield with a new
134: // (default) value, copy the cookie from respone to request (simulating
135: // a browser), than load the textfield from cookie and voala the
136: // textfields value should change.
137: // save means: add it to the respone
138: // load means: take it from request
139: assertEquals("test", textField.getModelObjectAsString());
140: textField.setModelObject("new text");
141: assertEquals("new text", textField.getModelObjectAsString());
142: copyCookieFromResponseToRequest(cycle);
143: assertEquals(1, getRequestCookies(cycle).length);
144: assertEquals(1, getResponseCookies(cycle).size());
145:
146: persister.load(textField);
147: assertEquals("test", textField.getModelObjectAsString());
148: assertEquals(1, getRequestCookies(cycle).length);
149: assertEquals(1, getResponseCookies(cycle).size());
150:
151: // remove all cookies from mock response
152: // Because I'll find the cookie to be removed in the request, the
153: // persister will create
154: // a "delete" cookie to remove the cookie on the client and add it to
155: // the response.
156: persister.clear(textField);
157: assertEquals(1, getRequestCookies(cycle).length);
158: assertEquals(2, getResponseCookies(cycle).size());
159: assertEquals("form:input", ((Cookie) getResponseCookies(cycle)
160: .get(1)).getName());
161: assertEquals(0, ((Cookie) getResponseCookies(cycle).get(1))
162: .getMaxAge());
163: }
164:
165: private void copyCookieFromResponseToRequest(
166: final RequestCycle cycle) {
167: ((MockHttpServletRequest) ((WebRequest) cycle.getRequest())
168: .getHttpServletRequest())
169: .addCookie((Cookie) getResponseCookies(cycle).get(0));
170: }
171:
172: private Cookie[] getRequestCookies(final RequestCycle cycle) {
173: return ((WebRequest) cycle.getRequest())
174: .getHttpServletRequest().getCookies();
175: }
176:
177: private List getResponseCookies(final RequestCycle cycle) {
178: return (List) ((MockHttpServletResponse) ((WebResponse) cycle
179: .getResponse()).getHttpServletResponse()).getCookies();
180: }
181: }
|