1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.renderkit.html.util;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Enumeration;
24 import java.util.HashMap;
25 import java.util.LinkedHashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import javax.servlet.ServletContext;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32
33 import org.apache.myfaces.test.AbstractTomahawkViewControllerTestCase;
34 import org.apache.myfaces.webapp.filter.servlet.AbstractAttributeMap;
35 import org.apache.myfaces.webapp.filter.servlet.RequestHeaderMap;
36 import org.apache.myfaces.webapp.filter.servlet.RequestHeaderValuesMap;
37 import org.apache.shale.test.mock.MockExternalContext;
38 import org.apache.shale.test.mock.MockPrintWriter;
39 import org.apache.shale.test.mock.MockResponseWriter;
40
41 /**
42 * Unit test for the AddResource class which can output script, style and inline
43 * javascript into the header or body of an HTML response page.
44 */
45 public class AddResourceTest extends AbstractTomahawkViewControllerTestCase
46 {
47 public AddResourceTest(String name)
48 {
49 super(name);
50 }
51
52 public void testGetInstance()
53 {
54
55 Map cacheMap = new LinkedHashMap();
56
57 AddResource instance1 = AddResourceFactory.getInstance(null,cacheMap, "/test1", null);
58 assertNotNull(instance1);
59
60 /* no longer true
61 AddResource instance2 = AddResourceFactory.getInstance(null, "/test2", null);
62 assertNotSame(instance1, instance2);
63 */
64
65 AddResourceFactory.getInstance(null,cacheMap, "/test1", null);
66 }
67
68 /*
69 public void setUp()
70 {
71 // Make sure a FacesContext configured from some previous test case
72 // doesn't interfere with the test case we are about to run...
73 FacesContextHelper.setCurrentInstance(null);
74 }
75
76 public void tearDown()
77 {
78 // Make sure a FacesContext we may have configured in the test case
79 // just completed doesn't interfere with test cases run later.
80 FacesContextHelper.setCurrentInstance(null);
81 }
82 */
83
84 /**
85 * Simple test helper class to allow unit tests to configure
86 * mock FacesContext objects as the "current instance".
87 * <p>
88 * The method FacesContext.setCurrentInstance is protected, and
89 * hence cannot be accessed by unit tests wanting to configure
90 * a mock object as the value seen by code calling method
91 * FacesContext.getCurrentInstance().
92 */
93 /*
94 private static abstract class FacesContextHelper extends FacesContext
95 {
96 public static void setCurrentInstance(FacesContext other)
97 {
98 FacesContext.setCurrentInstance(other);
99 }
100 }*/
101
102 /**
103 * Configure a fake JSF environment for a test, consisting of a
104 * FacesContext and dependent objects.
105 * <p>
106 * EasyMock control objects are used to emulate the necessary bits.
107 */
108 /*
109 private static class MockState
110 {
111 Writer _writer;
112 ResponseWriter _htmlResponseWriter;
113 MockControl _servletRequestControl;
114 HttpServletRequest _servletRequest;
115 MockControl _servletResponseControl;
116 HttpServletResponse _servletResponse;
117 FacesContext _facesContext;
118
119 public void setup() throws IOException
120 {
121 // set up a writer object to be the "response" output stream.
122 _writer = new StringWriter();
123 String contentType = "text/html";
124 String charEncoding = "UTF-8";
125 _htmlResponseWriter = new HtmlResponseWriterImpl(_writer, contentType, charEncoding);
126
127 // Mock ServletRequest object that:
128 // * returns "/test" for context path
129 // * returns "/test/foo.jsp" for servlet path
130 // * returns "null" for getPathInfo
131 // * returns "null" for getHeader
132 // * returns "null" for getAttribute
133 // * returns null for getSession
134 _servletRequestControl = MockControl.createControl(HttpServletRequest.class);
135 _servletRequest = (HttpServletRequest) _servletRequestControl.getMock();
136 _servletRequest.getContextPath();
137 _servletRequestControl.setReturnValue("/test", MockControl.ZERO_OR_MORE);
138 _servletRequest.getServletPath();
139 _servletRequestControl.setReturnValue("/test/foo.jsp", MockControl.ZERO_OR_MORE);
140 _servletRequest.getPathInfo();
141 _servletRequestControl.setReturnValue("", MockControl.ZERO_OR_MORE);
142 _servletRequest.getHeader("");
143 _servletRequestControl.setMatcher(MockControl.ALWAYS_MATCHER);
144 _servletRequestControl.setReturnValue(null, MockControl.ZERO_OR_MORE);
145 _servletRequest.getAttribute("");
146 _servletRequestControl.setMatcher(MockControl.ALWAYS_MATCHER);
147 _servletRequestControl.setReturnValue(null, MockControl.ZERO_OR_MORE);
148 _servletRequest.setAttribute("", "");
149 _servletRequestControl.setMatcher(MockControl.ALWAYS_MATCHER);
150 _servletRequestControl.setVoidCallable(MockControl.ZERO_OR_MORE);
151 _servletRequest.getSession(false);
152 _servletRequestControl.setReturnValue(null, MockControl.ZERO_OR_MORE);
153 _servletRequestControl.replay();
154
155 // Mock ServletResponse object that:
156 // * returns appropriate encoded URLs
157 // * returns a PrintWriter wrapping this object's writer member for
158 // calls to getWriter
159 _servletResponseControl = MockControl.createControl(HttpServletResponse.class);
160 _servletResponse = (HttpServletResponse) _servletResponseControl.getMock();
161 _servletResponse.encodeURL("/test/scripts/script1");
162 _servletResponseControl.setReturnValue("encoded(/test/scripts/script1)", MockControl.ZERO_OR_MORE);
163 _servletResponse.getWriter();
164 _servletResponseControl.setReturnValue(new PrintWriter(_writer), MockControl.ZERO_OR_MORE);
165 _servletResponse.getCharacterEncoding();
166 _servletResponseControl.setReturnValue("UTF-8", MockControl.ZERO_OR_MORE);
167 _servletResponseControl.replay();
168
169 // The FacesContext needs FactoryFinder configured.
170 FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, ApplicationFactoryImpl.class.getName());
171 FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, RenderKitFactoryImpl.class.getName());
172
173 // Now create a FacesContext....
174 _facesContext = new ServletFacesContextImpl(null,
175 _servletRequest, _servletResponse);
176 _facesContext.setResponseWriter(_htmlResponseWriter);
177 }
178
179 public void verifyControls()
180 {
181 _servletRequestControl.verify();
182 _servletResponseControl.verify();
183 }
184 }*/
185
186 public void testAddJavaScriptHere() throws IOException
187 {
188 //MockState mockState = new MockState();
189 //mockState.setup();
190
191 request.setPathElements("/test", "", "", "");
192 // now start the test
193 AddResource instance1 = AddResourceFactory.getInstance(null,null,"/test", null);
194 instance1.addJavaScriptHere(facesContext, "/scripts/script1");
195
196 // verify that our mock objects got the expected callbacks
197 //mockState.verifyControls();
198
199 // verify that:
200 // *script tag is output
201 // * type attribute is right,
202 // * URL has context path prepended to it
203 // * URL has been encoded
204 // * HTML comments have been used to hide script from non-script-aware
205 // browsers.
206 //
207 // NOTE: are comments required to hide this script from browsers when
208 // there isn't any script body content (just a src attr)?
209 String scriptValue = ((MockResponseWriter)facesContext.getResponseWriter()).getWriter().toString();
210
211 assertEquals(scriptValue, "<script type=\"text/javascript\" src=\"/test/scripts/script1\"/>");
212 }
213
214 public static class CustomMockExternalContext extends MockExternalContext
215 {
216 private Map _requestHeaderMap;
217 private Map _requestHeaderValuesMap;
218
219 public CustomMockExternalContext(ServletContext context,
220 HttpServletRequest request, HttpServletResponse response)
221 {
222 super(context, request, response);
223 }
224
225 @Override
226 public Map getRequestHeaderMap()
227 {
228 if (_requestHeaderMap == null)
229 {
230 _requestHeaderMap = new RequestHeaderMap((HttpServletRequest)request);
231 }
232 return _requestHeaderMap;
233 }
234
235 @Override
236 public Map getRequestHeaderValuesMap()
237 {
238 if (_requestHeaderValuesMap == null)
239 {
240 _requestHeaderValuesMap = new RequestHeaderValuesMap((HttpServletRequest)request);
241 }
242 return _requestHeaderValuesMap;
243 }
244 }
245
246 public static class RequestHeaderMap extends AbstractAttributeMap
247 {
248 private final HttpServletRequest _httpServletRequest;
249
250 RequestHeaderMap(HttpServletRequest httpServletRequest)
251 {
252 _httpServletRequest = httpServletRequest;
253 }
254
255 protected Object getAttribute(String key)
256 {
257 return _httpServletRequest.getHeader(key);
258 }
259
260 protected void setAttribute(String key, Object value)
261 {
262 throw new UnsupportedOperationException(
263 "Cannot set HttpServletRequest Header");
264 }
265
266 protected void removeAttribute(String key)
267 {
268 throw new UnsupportedOperationException(
269 "Cannot remove HttpServletRequest Header");
270 }
271
272 protected Enumeration getAttributeNames()
273 {
274 return _httpServletRequest.getHeaderNames();
275 }
276
277 public void putAll(Map t)
278 {
279 throw new UnsupportedOperationException();
280 }
281
282
283 public void clear()
284 {
285 throw new UnsupportedOperationException();
286 }
287 }
288
289 public static class RequestHeaderValuesMap extends AbstractAttributeMap
290 {
291 private final HttpServletRequest _httpServletRequest;
292 private final Map _valueCache = new HashMap();
293
294 RequestHeaderValuesMap(HttpServletRequest httpServletRequest)
295 {
296 _httpServletRequest = httpServletRequest;
297 }
298
299 protected Object getAttribute(String key)
300 {
301 Object ret = _valueCache.get(key);
302 if (ret == null)
303 {
304 _valueCache.put(key, ret = toArray(_httpServletRequest
305 .getHeaders(key)));
306 }
307
308 return ret;
309 }
310
311 protected void setAttribute(String key, Object value)
312 {
313 throw new UnsupportedOperationException(
314 "Cannot set HttpServletRequest HeaderValues");
315 }
316
317 protected void removeAttribute(String key)
318 {
319 throw new UnsupportedOperationException(
320 "Cannot remove HttpServletRequest HeaderValues");
321 }
322
323 protected Enumeration getAttributeNames()
324 {
325 return _httpServletRequest.getHeaderNames();
326 }
327
328 private String[] toArray(Enumeration e)
329 {
330 List ret = new ArrayList();
331
332 while (e.hasMoreElements())
333 {
334 ret.add(e.nextElement());
335 }
336
337 return (String[]) ret.toArray(new String[ret.size()]);
338 }
339 }
340
341 public void testWriteWithFullHeader() throws IOException
342 {
343 //MockState mockState = new MockState();
344 //mockState.setup();
345 externalContext = new CustomMockExternalContext(servletContext, request, response);
346 facesContext.setExternalContext(externalContext);
347
348 request.setPathElements("/test", "", "", "");
349 String originalResponse =
350 "<html><head></head><body></body></html>";
351
352 AddResource ar = AddResourceFactory.getInstance(null,null,"/test", null);
353 ar.parseResponse(request,originalResponse,response);
354 ar.writeWithFullHeader(request,response);
355 ar.writeResponse(request,response);
356
357 //mockState.verifyControls();
358
359 String returnedResponse = new String(((MockPrintWriter)response.getWriter()).content());
360
361 //System.out.println(facesContext.getResponseWriter().toString());
362 assertEquals(originalResponse, returnedResponse);
363 }
364 }