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