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.shared.renderkit;
20  
21  import java.io.IOException;
22  import java.io.StringWriter;
23  
24  import javax.el.ELContext;
25  import javax.faces.application.Application;
26  import javax.faces.application.ProjectStage;
27  import javax.faces.application.Resource;
28  import javax.faces.application.ResourceHandler;
29  import javax.faces.component.UIComponent;
30  import javax.faces.component.UIInput;
31  import javax.faces.component.UIOutput;
32  import javax.faces.component.UIPanel;
33  import javax.faces.component.html.HtmlGraphicImage;
34  import javax.faces.context.FacesContext;
35  
36  import junit.framework.Assert;
37  
38  import org.apache.myfaces.shared.renderkit.html.HTML;
39  import org.apache.myfaces.test.base.AbstractJsfTestCase;
40  import org.apache.myfaces.test.mock.MockResponseWriter;
41  import org.easymock.classextension.EasyMock;
42  import org.junit.Test;
43  
44  /**
45   * 
46   * @author markoc
47   */
48  public class RendererUtilsTest extends AbstractJsfTestCase {
49  
50  	private MockResponseWriter writer;
51  
52  	/**
53  	 * ResourceHandler nice easy mock
54  	 */
55  	ResourceHandler resourceHandlerMock;
56  
57  	/**
58  	 * {@link Application} nice easy mock
59  	 */
60  	Application applicationMock;
61  
62  	/**
63  	 * A {@link Resource} nice easy mock
64  	 */
65  	private Resource resourceMock;
66  
67  	String libraryName = "images";
68  
69  	String resourceName = "picture.gif";
70  
71  	String requestPath = "/somePrefix/faces/javax.faces.resource/picture.gif?ln=\"images\"";
72  
73  	// a Component instance:
74  	HtmlGraphicImage graphicImage = new HtmlGraphicImage();
75  
76      private UIPanel parent;
77  
78  	public RendererUtilsTest(String name) {
79  		super(name);
80  	}
81  
82  	protected void setUp() throws Exception {
83  		super.setUp();
84  
85  		writer = new MockResponseWriter(new StringWriter(), null, null);
86  		facesContext.setResponseWriter(writer);
87  
88  		applicationMock = EasyMock.createNiceMock(Application.class);
89  		facesContext.setApplication(applicationMock);
90  
91  		resourceHandlerMock = EasyMock.createNiceMock(ResourceHandler.class);
92  		applicationMock.getResourceHandler();
93  		EasyMock.expectLastCall().andReturn(resourceHandlerMock);
94  		
95  		applicationMock.getProjectStage();
96  		EasyMock.expectLastCall().andReturn(ProjectStage.Development);
97  
98  		resourceMock = EasyMock.createNiceMock(Resource.class);
99  
100 		EasyMock.replay(applicationMock);
101 
102 		graphicImage.getAttributes().put(JSFAttr.LIBRARY_ATTR, libraryName);
103 		graphicImage.getAttributes().put(JSFAttr.NAME_ATTR, resourceName);
104 		graphicImage.setId("graphicImageId");
105 		
106 		parent = new UIPanel();
107 	}
108 
109 	protected void tearDown() throws Exception {
110 		super.tearDown();
111 	}
112 
113 	/**
114 	 * 
115 	 */
116 	public void testGetIconSrc() {
117 
118 		// Training a mock:
119 		resourceHandlerMock.createResource(resourceName, libraryName);
120 		EasyMock.expectLastCall().andReturn(resourceMock);
121 		resourceMock.getRequestPath();
122 		EasyMock.expectLastCall().andReturn(requestPath);
123 		EasyMock.replay(resourceHandlerMock);
124 		EasyMock.replay(resourceMock);
125 
126 		// Tested method :
127 		String iconSrc = RendererUtils.getIconSrc(facesContext, graphicImage,
128 				HTML.IMG_ELEM);
129 
130 		assertEquals(
131 				"If name or name/library present, source must be obtained from ResourceHandler",
132 				requestPath, iconSrc);
133 
134 	}
135 
136 	public void testGetIconSrcResourceNotFound() throws Exception {
137 		// Training a mock:
138 		EasyMock.reset(resourceHandlerMock);
139 		resourceHandlerMock.createResource(resourceName, libraryName);
140 		EasyMock.expectLastCall().andReturn(null);
141 		EasyMock.replay(resourceHandlerMock);
142 
143 		// Tested method :
144 		String iconSrc = RendererUtils.getIconSrc(facesContext, graphicImage,
145 				HTML.IMG_ELEM);
146 
147 		assertEquals("RES_NOT_FOUND", iconSrc);
148 		assertTrue("If resource is not found, a Message must be added",
149 				facesContext.getMessages(graphicImage.getClientId(facesContext)).hasNext());
150 
151 	}
152 
153     public void testGetStringValue()
154     {
155         // Test for situation where submittedValue IS NOT String: 
156         UIInput uiInput = new UIInput();
157         Object submittedValue = new Object();
158         uiInput.setSubmittedValue(submittedValue);
159         
160         String stringValue = RendererUtils.getStringValue(facesContext, uiInput);
161         assertNotNull(stringValue);
162         assertEquals("If submittedvalue is not String, toString() must be used", submittedValue.toString(), stringValue);
163     }
164 
165     public void testGetConvertedUIOutputValue()
166     {
167         UIInput uiInput = new UIInput();
168         StringBuilder submittedValue = new StringBuilder("submittedValue");
169         uiInput.setSubmittedValue(submittedValue);
170         
171         
172         Object convertedUIOutputValue = RendererUtils.getConvertedUIOutputValue(facesContext, uiInput, submittedValue);
173         assertEquals("If submittedvalue is not String, toString() must be used", submittedValue.toString(), convertedUIOutputValue);
174     }
175 
176     /**
177      * test for MYFACES-3126
178      */
179     @Test
180     public void testRenderChild() throws IOException
181     {
182         
183        UIInput uiInput = _setUpComponentStack();
184        
185        RendererUtils.renderChild(facesContext, uiInput);
186        
187        assertEquals("Invocation must not change the current component", parent, UIComponent.getCurrentComponent(facesContext));
188     }
189 
190     
191     /**
192      * Test that no method encode* are called if component is not rendered 
193      */
194     @Test
195     public void testRenderChild2() throws IOException {
196 
197         MockComponent component = new MockComponent();
198         
199         RendererUtils.renderChild(facesContext, component);
200     }
201     
202     @Test
203     public void testIsRendered()
204     {
205         UIComponent uiComponent = new UIOutput();
206         boolean rendered = RendererUtils.isRendered(facesContext, uiComponent);
207         assertTrue(rendered);
208         
209         uiComponent.setRendered(false);
210         rendered = RendererUtils.isRendered(facesContext, uiComponent);
211         assertFalse(rendered);
212         
213         uiComponent = _setUpComponentStack();
214         rendered = RendererUtils.isRendered(facesContext, uiComponent);
215         assertFalse(rendered);
216         assertEquals("isRendered must not change current component", parent, UIComponent.getCurrentComponent(facesContext));
217     }
218     
219     /**
220      * Verifies the current component on stack
221      */
222     private class MockRenderedValueExpression extends org.apache.myfaces.test.el.MockValueExpression {
223 
224         private final UIComponent toVerify;
225 
226         public MockRenderedValueExpression(String expression, Class<?> expectedType, UIComponent toVerify) {
227             super(expression, expectedType);
228             this.toVerify = toVerify;
229         }
230         
231         @Override
232         public Object getValue(ELContext elContext) {
233           UIComponent currentComponent = UIComponent.getCurrentComponent(facesContext);
234           Assert.assertEquals("If this VE is called, component on stack must be actual" , currentComponent , toVerify);
235           return false;
236         }
237     }
238     
239     /** Verifies no call to encode* methods */
240     private class MockComponent extends UIOutput
241     {
242         @Override
243         public boolean isRendered() {
244             return false;
245         }
246         @Override
247         public void encodeBegin(FacesContext context) throws IOException {
248             fail();
249         }
250         @Override
251         public void encodeChildren(FacesContext context) throws IOException {
252             fail();
253         }
254         @Override
255         public void encodeEnd(FacesContext context) throws IOException {
256             fail();
257         }
258     }
259     
260     private UIInput _setUpComponentStack() {
261         UIInput uiInput = new UIInput();
262         parent.getChildren().add(uiInput);
263         uiInput.setId("testId");
264         
265         
266         MockRenderedValueExpression ve = new MockRenderedValueExpression("#{component.id eq 'testId'}", Boolean.class, uiInput);
267         uiInput.setValueExpression("rendered", ve);
268         
269        // simlulate that parent panel encodes children and is on the stack:
270        parent.pushComponentToEL(facesContext, null);
271         return uiInput;
272     }
273 
274 }