View Javadoc

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 }