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.application;
20  
21  import java.beans.BeanInfo;
22  import java.io.File;
23  import java.net.MalformedURLException;
24  import java.net.URL;
25  
26  import javax.el.ExpressionFactory;
27  import javax.el.VariableMapper;
28  import javax.faces.FactoryFinder;
29  import javax.faces.application.Application;
30  import javax.faces.application.ApplicationWrapper;
31  import javax.faces.application.Resource;
32  import javax.faces.component.UIComponent;
33  import javax.faces.component.UINamingContainer;
34  import javax.faces.component.UIOutput;
35  import javax.faces.component.UIViewRoot;
36  import javax.faces.context.FacesContext;
37  import javax.faces.view.facelets.FaceletContext;
38  
39  import org.apache.myfaces.config.RuntimeConfig;
40  import org.apache.myfaces.test.base.AbstractJsfTestCase;
41  import org.apache.myfaces.test.el.MockExpressionFactory;
42  import org.apache.myfaces.test.el.MockVariableMapper;
43  import org.apache.myfaces.test.mock.MockServletContext;
44  import org.apache.myfaces.test.mock.resource.MockSimpleResource;
45  import org.apache.myfaces.view.facelets.MockFaceletViewDeclarationLanguage;
46  import org.apache.myfaces.view.facelets.impl.FaceletCacheFactoryImpl;
47  import org.apache.myfaces.view.facelets.mock.MockViewDeclarationLanguageFactory;
48  import org.easymock.classextension.EasyMock;
49  import org.easymock.classextension.IMocksControl;
50  
51  /**
52   * Test class for ApplicationImpl that extends AbstractJsfTestCase
53   * 
54   * @author Jakob Korherr (latest modification by $Author: struberg $)
55   * @version $Revisio$ $Date: 2011-10-25 10:07:44 -0500 (Tue, 25 Oct 2011) $
56   */
57  public class ApplicationImplJsfTest extends AbstractJsfTestCase
58  {
59      
60      private static final String RESOURCE_MSG = "The Resource must be stored in the component's attribute " +
61                                                 "map under the key " + Resource.COMPONENT_RESOURCE_KEY;
62      
63      private static final String BEANINFO_MSG = "The BeanInfo metadata has to be store in the component's " + 
64                                                 "attribute map under the key " + UIComponent.BEANINFO_KEY;
65      
66      private static final String COMPOSITE_RENDERER_MSG = "The rendererType has to be javax.faces.Composite";
67      
68      private static final String TEST_COMPONENT_TYPE = "org.apache.myfaces.MyCustomComponentType";
69      
70      /**
71       * Application wrapper to test all the methods from ApplicationImpl,
72       * but to be able to override getExpressionFactory() to get the 
73       * MockExpressionFactory.
74       * 
75       * @author Jakob Korherr
76       */
77      private class TestApplicationWrapper extends ApplicationWrapper
78      {
79          
80          private ApplicationImpl _applicationImpl;
81          private MockExpressionFactory _expressionFactory;
82          
83          public TestApplicationWrapper(ApplicationImpl applicationImpl)
84          {
85              _applicationImpl = applicationImpl;
86              _expressionFactory = new MockExpressionFactory();
87          }
88  
89          @Override
90          public Application getWrapped()
91          {
92              return _applicationImpl;
93          }
94          
95          @Override
96          public ExpressionFactory getExpressionFactory() 
97          {
98              return _expressionFactory;
99          }
100         
101     }
102     
103     /**
104      * Helper method to assert the RendererType, the Resource and the BeanInfo.
105      * @param component
106      * @param resource
107      * @param metadata
108      */
109     private static void assertRendererTypeResourceBeanInfo(UIComponent component, Resource resource, BeanInfo metadata)
110     {
111         assertEquals(COMPOSITE_RENDERER_MSG, "javax.faces.Composite", component.getRendererType());
112         assertEquals(RESOURCE_MSG, resource, component.getAttributes().get(Resource.COMPONENT_RESOURCE_KEY));
113         assertEquals(BEANINFO_MSG, metadata, component.getAttributes().get(UIComponent.BEANINFO_KEY));
114     }
115 
116     private TestApplicationWrapper _testApplication;
117     private IMocksControl _mocksControl;
118     private FaceletContext _faceletContext;
119     
120     public ApplicationImplJsfTest(String name)
121     {
122         super(name);
123     }
124     
125     @Override
126     protected void setUp() throws Exception
127     {
128         super.setUp();
129         
130         _mocksControl = EasyMock.createControl();
131         
132         // create a FaceletContext Mock and put it in the FacesContext
133         _faceletContext = _mocksControl.createMock(FaceletContext.class);
134         facesContext.getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, _faceletContext);
135         
136         // create and configure our ApplicationImpl instance
137         FactoryFinder.setFactory(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY,
138                 MockViewDeclarationLanguageFactory.class.getName());
139         FactoryFinder.setFactory(FactoryFinder.FACELET_CACHE_FACTORY,
140                 FaceletCacheFactoryImpl.class.getName());
141         RuntimeConfig runtimeConfig = new RuntimeConfig();
142         _testApplication = new TestApplicationWrapper(new ApplicationImpl(runtimeConfig));
143         facesContext.setApplication(_testApplication);
144     }
145 
146     @Override
147     protected void tearDown() throws Exception
148     {
149         _mocksControl = null;
150         _faceletContext = null;
151         _testApplication = null;
152         
153         super.tearDown();
154     }
155 
156     /**
157      * Tests the creation of a composite component via 
158      * Application.createComponent(FacesContext context, Resource componentResource)
159      */
160     public void testCreateComponentFromResource()
161     {
162         // we need a UINamingContainer for this test
163         application.addComponent(UINamingContainer.COMPONENT_TYPE, UINamingContainer.class.getName());
164         _testApplication.addComponent(UINamingContainer.COMPONENT_TYPE, UINamingContainer.class.getName());
165         
166         // configure FaceletContext mock
167         MockVariableMapper variableMapper = new MockVariableMapper();
168         EasyMock.expect(_faceletContext.getVariableMapper()).andReturn(variableMapper).anyTimes();
169         _faceletContext.setVariableMapper((VariableMapper) EasyMock.anyObject());
170         EasyMock.expectLastCall().anyTimes();
171         _mocksControl.replay();
172 
173         // get the VDL
174         UIViewRoot view = facesContext.getViewRoot();
175         MockFaceletViewDeclarationLanguage vdl 
176                 = (MockFaceletViewDeclarationLanguage) _testApplication.getViewHandler()
177                     .getViewDeclarationLanguage(facesContext, view.getViewId());
178         
179         // ---- first component test - without any special settings ----------------------------
180         
181         // configure the Resource needed for this test
182         MockSimpleResource resource = new MockSimpleResource(null, "testlib", null, "composite.xhtml", 
183                 null, new File("src/test/resources/org/apache/myfaces/application"));
184         
185         // get the BeanInfo metadata
186         BeanInfo metadata = vdl.getComponentMetadata(facesContext, resource);
187         
188         // create the component
189         UIComponent component = _testApplication.createComponent(facesContext, resource);
190         
191         // asserts for the first component
192         assertTrue("The component has to be an UINamingContainer", component instanceof UINamingContainer);
193         assertRendererTypeResourceBeanInfo(component, resource, metadata);
194         
195         // ---- second component test - from a script ------------------------------------------
196         
197         MockSimpleResource scriptResource = new MockSimpleResource(null, "testlib", null, 
198                 "org.apache.myfaces.application.MockResourceComponent.groovy", 
199                 null, new File("src/test/resources/org/apache/myfaces/application"));
200         
201         // install the script resource to the VDL-mock
202         vdl.setScriptComponentResource(resource, scriptResource);
203         
204         // create the component
205         component = _testApplication.createComponent(facesContext, resource);
206         
207         // asserts for the second component
208         assertTrue("The component has to be a MockResourceComponent", component instanceof MockResourceComponent);
209         assertRendererTypeResourceBeanInfo(component, resource, metadata);
210         
211         // remove the script resource again
212         vdl.setScriptComponentResource(resource, null);
213         
214         // ---- third component test - from libaryName.resourceName.class -----------------------
215         
216         MockSimpleResource componentResource = new MockSimpleResource(null, "org.apache.myfaces.application",
217                 null, "MockResourceComponent.xhtml", null,
218                 new File("src/test/resources/org/apache/myfaces/application"))
219         {
220 
221             /* (non-javadoc)
222              * We have to overwrite getURL() here, because it has to deliver a valid URL and
223              * we can't get that out of the library and the resource name we set on this resource.
224              */
225             @Override
226             public URL getURL()
227             {
228                 MockServletContext servletContext 
229                         = (MockServletContext) FacesContext.getCurrentInstance()
230                                 .getExternalContext().getContext();
231                 servletContext.setDocumentRoot(new File("src/test/resources/org/apache/myfaces/application"));
232     
233                 try 
234                 {
235                     return servletContext.getResource("/testlib/composite.xhtml");
236                 } 
237                 catch (MalformedURLException e) 
238                 {
239                     return null;
240                 }
241             }
242             
243         };
244         
245         // get the BeanInfo metadata
246         BeanInfo metadataComponentResource = vdl.getComponentMetadata(facesContext, componentResource);
247         
248         // create the component
249         component = _testApplication.createComponent(facesContext, componentResource);
250         
251         // asserts for the third component
252         assertTrue("The component has to be a MockResourceComponent", component instanceof MockResourceComponent);
253         assertRendererTypeResourceBeanInfo(component, componentResource, metadataComponentResource);
254         
255         // ---- fourth component test - with a custom componentType ------------------------------
256         
257         // change the resource
258         resource = new MockSimpleResource(null, "testlib", null, "compositeWithComponentType.xhtml", 
259                 null, new File("src/test/resources/org/apache/myfaces/application"));
260         // FIXME resource.setResourceName(resourceName) did not work
261         // this can be changed in the next release of MyFaces test (1.0.0-beta.NEXT)
262         
263         // register the new component type
264         _testApplication.addComponent(TEST_COMPONENT_TYPE, UIOutput.class.getName());
265         
266         // get the BeanInfo metadata
267         metadata = vdl.getComponentMetadata(facesContext, resource);
268         
269         // create the component
270         component = _testApplication.createComponent(facesContext, resource);
271         
272         // asserts for the fourth component
273         assertTrue("The component has to be an instance of UIOutput", component instanceof UIOutput);
274         assertRendererTypeResourceBeanInfo(component, resource, metadata);
275     }
276     
277 }