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.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 }