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  
20  package org.apache.myfaces.custom.date;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.IOException;
24  import java.text.ParseException;
25  import java.util.Calendar;
26  import java.util.Date;
27  import java.util.GregorianCalendar;
28  import java.util.HashMap;
29  import java.util.Locale;
30  import java.util.Map;
31  import java.util.Properties;
32  
33  import javax.faces.FactoryFinder;
34  import javax.faces.component.UIComponent;
35  import javax.faces.component.UIViewRoot;
36  import javax.faces.context.ExternalContext;
37  import javax.faces.context.FacesContext;
38  import javax.faces.convert.Converter;
39  import javax.faces.convert.ConverterException;
40  import javax.faces.render.RenderKitFactory;
41  
42  import junit.framework.Test;
43  import junit.framework.TestSuite;
44  
45  import org.apache.myfaces.application.ApplicationFactoryImpl;
46  import org.apache.myfaces.custom.date.AbstractHtmlInputDate.UserData;
47  import org.apache.myfaces.test.AbstractTomahawkViewControllerTestCase;
48  import org.apache.myfaces.test.mock.MockResponseWriter;
49  import org.apache.myfaces.test.utils.HtmlCheckAttributesUtil;
50  import org.apache.myfaces.test.utils.HtmlRenderedAttr;
51  import org.easymock.MockControl;
52  import org.easymock.classextension.MockClassControl;
53  
54  public class HtmlDateRendererTest extends AbstractTomahawkViewControllerTestCase {
55  //  public static void main(String[] args) {
56  //    junit.textui.TestRunner.run(HtmlDateRendererTest.class);
57  //  }
58     
59    public HtmlDateRendererTest(String name) {
60      super(name);
61    }
62    
63    public static Test suite() {
64        return new TestSuite(HtmlDateRendererTest.class);
65    }
66  
67    protected void setUp() throws Exception {
68      super.setUp();
69      FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
70          MockHtmlDateRendererTestRenderKitFactory.class.getName());
71      FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
72          ApplicationFactoryImpl.class.getName());
73    }
74  
75    protected void tearDown() throws Exception {
76      super.tearDown();
77    }
78  
79    /*
80     * Test method for
81     * 'org.apache.myfaces.custom.date.HtmlDateRenderer.decode(FacesContext,
82     * UIComponent)'
83     */
84    public void testDecodeDate() throws Exception {
85      HtmlInputDate inputDate = new HtmlInputDate();
86      inputDate.setId("test");
87      inputDate.setType("date");
88      HtmlDateRenderer subject = new HtmlDateRenderer();
89      // setup the request map
90      Map map = new HashMap();
91      map.put("test.day", "14");
92      map.put("test.month", "1");
93      map.put("test.year", "2005");
94      FacesContext facesContext = mockupForDecodeCall(map);
95      // decode
96      subject.decode(facesContext, inputDate);
97      UserData data = inputDate.getUserData(Locale.ENGLISH);
98      assertEquals("14", data.getDay());
99      assertEquals("1", data.getMonth());
100     assertEquals("2005", data.getYear());
101   }
102 
103   public void testDecodeWithSubmittedValue() throws Exception {
104     HtmlInputDate inputDate = new HtmlInputDate();
105     inputDate.setId("test");
106     inputDate.setType("date");
107     Date today = new Date();
108     inputDate.setSubmittedValue(new UserData(today, Locale.ENGLISH, null, true, "date"));
109     HtmlDateRenderer subject = new HtmlDateRenderer();
110     // setup the request map
111     Map map = new HashMap();
112     map.put("test.day", "14");
113     map.put("test.month", "1");
114     map.put("test.year", "2005");
115     FacesContext facesContext = mockupForDecodeCall(map);
116     // decode
117     subject.decode(facesContext, inputDate);
118     UserData data = inputDate.getUserData(Locale.ENGLISH);
119     assertEquals("14", data.getDay());
120     assertEquals("1", data.getMonth());
121     assertEquals("2005", data.getYear());
122   }
123 
124   public void testDecodeTime() throws Exception {
125     HtmlInputDate inputDate = new HtmlInputDate();
126     inputDate.setId("test");
127     inputDate.setType("time");
128     HtmlDateRenderer subject = new HtmlDateRenderer();
129     // setup the request map
130     Map map = new HashMap();
131     map.put("test.hours", "12");
132     map.put("test.minutes", "15");
133     map.put("test.seconds", "35");
134     FacesContext facesContext = mockupForDecodeCall(map);
135     // decode
136     subject.decode(facesContext, inputDate);
137     UserData data = inputDate.getUserData(Locale.ENGLISH);
138     assertEquals("12", data.getHours());
139     assertEquals("15", data.getMinutes());
140     assertEquals("35", data.getSeconds());
141   }
142 
143   public void testDecodeFull() throws Exception {
144     HtmlInputDate inputDate = new HtmlInputDate();
145     inputDate.setId("test");
146     inputDate.setType("full");
147     HtmlDateRenderer subject = new HtmlDateRenderer();
148     // setup the request map
149     Map map = new HashMap();
150     map.put("test.day", "14");
151     map.put("test.month", "1");
152     map.put("test.year", "2005");
153     map.put("test.hours", "12");
154     map.put("test.minutes", "15");
155     map.put("test.seconds", "3");
156     FacesContext facesContext = mockupForDecodeCall(map);
157     // decode
158     subject.decode(facesContext, inputDate);
159     UserData data = inputDate.getUserData(Locale.ENGLISH);
160     assertEquals("14", data.getDay());
161     assertEquals("1", data.getMonth());
162     assertEquals("2005", data.getYear());
163     assertEquals("12", data.getHours());
164     assertEquals("15", data.getMinutes());
165     assertEquals("03", data.getSeconds());
166   }
167 
168   public void testDecodeFlorp() throws Exception {
169     HtmlInputDate inputDate = new HtmlInputDate();
170     inputDate.setId("test");
171     // is this correct? Should it parse correctly if the type is not valid?
172     inputDate.setType("florp");
173     HtmlDateRenderer subject = new HtmlDateRenderer();
174     // setup the request map
175     Map map = new HashMap();
176     map.put("test.day", "14");
177     map.put("test.month", "1");
178     map.put("test.year", "2005");
179     map.put("test.hours", "12");
180     map.put("test.minutes", "15");
181     FacesContext facesContext = mockupForDecodeCall(map);
182     // decode
183     subject.decode(facesContext, inputDate);
184     UserData data = inputDate.getUserData(Locale.ENGLISH);
185     assertEquals("14", data.getDay());
186     assertEquals("1", data.getMonth());
187     assertEquals("2005", data.getYear());
188     assertEquals("12", data.getHours());
189     assertEquals("15", data.getMinutes());
190   }
191 
192   public void testDecodeDisabled() throws Exception {
193     HtmlInputDate inputDate = new HtmlInputDate();
194     inputDate.setId("test");
195     inputDate.setType("date");
196     inputDate.setDisabled(true);
197     HtmlDateRenderer subject = new HtmlDateRenderer();
198     // setup the request map
199     Map map = new HashMap();
200     map.put("test.day", "14");
201     map.put("test.month", "1");
202     map.put("test.year", "2005");
203     FacesContext facesContext = mockupForDecodeCall(map);
204     // decode - when disabled currently defaults to today
205     // JIRA Issue #233 requests that the default be null
206     // and the control handle data that is not required
207     subject.decode(facesContext, inputDate);
208     UserData data = inputDate.getUserData(Locale.ENGLISH);
209     Calendar cal = GregorianCalendar.getInstance();
210     assertEquals(cal.get(Calendar.DATE) + "", data.getDay());
211     // different bases - cal starts at 0 in January, UserData starts at 1 in
212     // January
213     assertEquals((cal.get(Calendar.MONTH) + 1) + "", data.getMonth());
214     assertEquals(cal.get(Calendar.YEAR) + "", data.getYear());
215   }
216 
217   public static class DateTestConverter implements Converter
218   {
219 
220     public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String submittedValue)
221             throws ConverterException
222     {
223         HtmlInputDate inputDate = (HtmlInputDate) uiComponent;
224         String type = inputDate.getType();
225         Properties props = new Properties();
226         try
227         {
228             props.load(new ByteArrayInputStream(submittedValue.getBytes()));
229         }catch(IOException e)
230         {
231         }
232         UserData userData = inputDate.getUserData(facesContext.getViewRoot().getLocale());
233         if( ! (type.equals( "time" ) || type.equals( "short_time" )) )
234         {
235             userData.setYear(props.getProperty("year"));
236             userData.setMonth(props.getProperty("month"));
237             userData.setDay(props.getProperty("day"));
238         }
239         
240         if( ! type.equals( "date" ) ){
241             userData.setHours(props.getProperty("hours"));
242             userData.setMinutes(props.getProperty("minutes"));
243             if (type.equals("full") || type.equals("time"))
244             {
245                 userData.setSeconds(props.getProperty("seconds"));
246             }
247             if (inputDate.isAmpm()) {
248                 userData.setAmpm(props.getProperty("ampm"));
249             }
250         }
251         try {
252             return userData.parse();
253         } catch (ParseException e) {
254             Object[] args = {uiComponent.getId()};
255             throw new ConverterException("Error Parsing");
256         }  
257     }
258 
259     public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object submitValue)
260             throws ConverterException
261     {
262         HtmlInputDate inputDate = (HtmlInputDate) uiComponent;
263         String type = inputDate.getType();
264         UserData value = new UserData((Date) submitValue, 
265                 facesContext.getViewRoot().getLocale(), 
266                 inputDate.getTimeZone(), inputDate.isAmpm(), inputDate.getType());        
267         
268         StringBuffer submittedValue = new StringBuffer();
269         if( ! (type.equals( "time" ) || type.equals( "short_time" )) )
270         {
271             submittedValue.append("year=");
272             submittedValue.append((String) value.getYear() );
273             submittedValue.append("\n");
274 
275             submittedValue.append("month=");
276             submittedValue.append((String) value.getMonth());
277             submittedValue.append("\n");
278             
279             submittedValue.append("day=");
280             submittedValue.append((String) value.getDay() );
281             submittedValue.append("\n");                
282         }
283         
284         if( ! type.equals( "date" ) )
285         {
286             submittedValue.append("hours=");
287             submittedValue.append((String) value.getHours() );
288             submittedValue.append("\n");
289             
290             submittedValue.append("minutes=");
291             submittedValue.append((String) value.getMinutes() );
292             submittedValue.append("\n");
293 
294             if (type.equals("full") || type.equals("time"))
295             {
296                 submittedValue.append("seconds=");
297                 submittedValue.append((String) value.getSeconds() );
298                 submittedValue.append("\n");                    
299             }
300             
301             if (inputDate.isAmpm())
302             {
303                 submittedValue.append("ampm=");
304                 submittedValue.append((String) value.getAmpm() );
305                 submittedValue.append("\n");
306             }
307         }
308         if (submittedValue.charAt(submittedValue.length()-1) == '\n' )
309         {
310             submittedValue.deleteCharAt(submittedValue.length()-1);
311         }
312         
313         return submittedValue.toString();
314     }
315       
316   }
317   
318   public void testDecodeConverterDate() throws Exception {
319       HtmlInputDate inputDate = new HtmlInputDate();
320       inputDate.setId("test");
321       inputDate.setType("date");
322       inputDate.setConverter(new DateTestConverter());
323       HtmlDateRenderer subject = new HtmlDateRenderer();
324       // setup the request map
325       Map map = new HashMap();
326       map.put("test.day", "14");
327       map.put("test.month", "1");
328       map.put("test.year", "2005");
329       FacesContext facesContext = mockupForDecodeCall(map);
330       // decode
331       subject.decode(facesContext, inputDate);
332       //With converter, the submitted value is a String
333       assertTrue(inputDate.getSubmittedValue() instanceof String);
334       // converter
335       inputDate.validate(facesContext);
336       
337       UserData data = inputDate.getUserData(Locale.ENGLISH);
338       assertEquals("14", data.getDay());
339       assertEquals("1", data.getMonth());
340       assertEquals("2005", data.getYear());
341     }
342   
343   public void testDecodeConverterWithSubmittedValue() throws Exception {
344       HtmlInputDate inputDate = new HtmlInputDate();
345       inputDate.setId("test");
346       inputDate.setType("date");
347       inputDate.setConverter(new DateTestConverter());
348       Date today = new Date();
349       inputDate.setSubmittedValue(new UserData(today, Locale.ENGLISH, null, true, "date"));
350       HtmlDateRenderer subject = new HtmlDateRenderer();
351       // setup the request map
352       Map map = new HashMap();
353       map.put("test.day", "14");
354       map.put("test.month", "1");
355       map.put("test.year", "2005");
356       FacesContext facesContext = mockupForDecodeCall(map);
357       // decode
358       subject.decode(facesContext, inputDate);
359       //With converter, the submitted value is a String
360       assertTrue(inputDate.getSubmittedValue() instanceof String);
361       // converter
362       inputDate.validate(facesContext);
363       
364       UserData data = inputDate.getUserData(Locale.ENGLISH);
365       assertEquals("14", data.getDay());
366       assertEquals("1", data.getMonth());
367       assertEquals("2005", data.getYear());
368     }
369   
370   public void testDecodeConverterTime() throws Exception {
371       HtmlInputDate inputDate = new HtmlInputDate();
372       inputDate.setId("test");
373       inputDate.setType("time");
374       HtmlDateRenderer subject = new HtmlDateRenderer();
375       // setup the request map
376       Map map = new HashMap();
377       map.put("test.hours", "12");
378       map.put("test.minutes", "15");
379       map.put("test.seconds", "35");
380       FacesContext facesContext = mockupForDecodeCall(map);
381       // decode
382       subject.decode(facesContext, inputDate);
383       //With converter, the submitted value is a String
384       assertTrue(inputDate.getSubmittedValue() instanceof String);
385       // converter
386       inputDate.validate(facesContext);
387       
388       UserData data = inputDate.getUserData(Locale.ENGLISH);
389       assertEquals("12", data.getHours());
390       assertEquals("15", data.getMinutes());
391       assertEquals("35", data.getSeconds());
392     }
393 
394   public void testDecodeConverterFull() throws Exception {
395       HtmlInputDate inputDate = new HtmlInputDate();
396       inputDate.setId("test");
397       inputDate.setType("full");
398       HtmlDateRenderer subject = new HtmlDateRenderer();
399       // setup the request map
400       Map map = new HashMap();
401       map.put("test.day", "14");
402       map.put("test.month", "1");
403       map.put("test.year", "2005");
404       map.put("test.hours", "12");
405       map.put("test.minutes", "15");
406       map.put("test.seconds", "3");
407       FacesContext facesContext = mockupForDecodeCall(map);
408       // decode
409       subject.decode(facesContext, inputDate);
410       //With converter, the submitted value is a String
411       assertTrue(inputDate.getSubmittedValue() instanceof String);
412       // converter
413       inputDate.validate(facesContext);
414       UserData data = inputDate.getUserData(Locale.ENGLISH);
415       assertEquals("14", data.getDay());
416       assertEquals("1", data.getMonth());
417       assertEquals("2005", data.getYear());
418       assertEquals("12", data.getHours());
419       assertEquals("15", data.getMinutes());
420       assertEquals("03", data.getSeconds());
421     }
422 
423     public void testDecodeConverterFlorp() throws Exception {
424       HtmlInputDate inputDate = new HtmlInputDate();
425       inputDate.setId("test");
426       // is this correct? Should it parse correctly if the type is not valid?
427       inputDate.setType("florp");
428       HtmlDateRenderer subject = new HtmlDateRenderer();
429       // setup the request map
430       Map map = new HashMap();
431       map.put("test.day", "14");
432       map.put("test.month", "1");
433       map.put("test.year", "2005");
434       map.put("test.hours", "12");
435       map.put("test.minutes", "15");
436       FacesContext facesContext = mockupForDecodeCall(map);
437       // decode
438       subject.decode(facesContext, inputDate);
439       //With converter, the submitted value is a String
440       assertTrue(inputDate.getSubmittedValue() instanceof String);
441       // converter
442       inputDate.validate(facesContext);
443       UserData data = inputDate.getUserData(Locale.ENGLISH);
444       assertEquals("14", data.getDay());
445       assertEquals("1", data.getMonth());
446       assertEquals("2005", data.getYear());
447       assertEquals("12", data.getHours());
448       assertEquals("15", data.getMinutes());
449     }
450 
451   /*
452    * Test method for
453    * 'org.apache.myfaces.custom.date.HtmlDateRenderer.encodeEnd(FacesContext,
454    * UIComponent)'
455    */
456   public void testEncodeEnd() throws Exception {
457     
458   }
459 
460   /*
461    * Test method for
462    * 'org.apache.myfaces.custom.date.HtmlDateRenderer.getConvertedValue(FacesContext,
463    * UIComponent, Object)'
464    */
465   public void testGetConvertedValue() throws Exception {
466   }
467 
468   private FacesContext mockupForDecodeCall(Map requestParameterMap) {
469     // mock FacesContext
470     MockControl contextControl = MockClassControl
471         .createControl(FacesContext.class);
472     FacesContext facesContext = (FacesContext) contextControl.getMock();
473     // mock UIViewRoot
474     MockControl viewControl = MockClassControl.createControl(UIViewRoot.class);
475     UIViewRoot viewRoot = (UIViewRoot) viewControl.getMock();
476     // mock ExternalContext
477     MockControl externalContextControl = MockClassControl
478         .createControl(ExternalContext.class);
479     ExternalContext externalContext = (ExternalContext) externalContextControl
480         .getMock();
481     // set the view root
482     facesContext.getViewRoot();
483     contextControl.setReturnValue(viewRoot);
484     // called twice
485     facesContext.getViewRoot();
486     contextControl.setReturnValue(viewRoot);
487     // set the external context
488     facesContext.getExternalContext();
489     contextControl.setReturnValue(externalContext);
490     // set the locale
491     viewRoot.getLocale();
492     viewControl.setReturnValue(Locale.ENGLISH);
493     // set the render kit id
494     viewRoot.getRenderKitId();
495     viewControl.setReturnValue(RenderKitFactory.HTML_BASIC_RENDER_KIT);
496     externalContext.getRequestParameterMap();
497     externalContextControl.setReturnValue(requestParameterMap);
498     // prepare
499     contextControl.replay();
500     viewControl.replay();
501     externalContextControl.replay();
502     return facesContext;
503   }
504 
505   public void testHtmlPropertyPassTru() throws Exception
506   {
507       HtmlInputDate inputDate = new HtmlInputDate();
508       
509       HtmlRenderedAttr[] attrs = {
510           //_UniversalProperties
511           new HtmlRenderedAttr("dir", 3), 
512           new HtmlRenderedAttr("lang", 3), 
513           new HtmlRenderedAttr("title", 3),
514           //_EventProperties 
515           new HtmlRenderedAttr("ondblclick", 3), 
516           new HtmlRenderedAttr("onkeydown", 3), 
517           new HtmlRenderedAttr("onkeypress", 3),
518           new HtmlRenderedAttr("onkeyup", 3), 
519           new HtmlRenderedAttr("onmousedown", 3), 
520           new HtmlRenderedAttr("onmousemove", 3), 
521           new HtmlRenderedAttr("onmouseout", 3),
522           new HtmlRenderedAttr("onmouseover", 3), 
523           new HtmlRenderedAttr("onmouseup", 3),
524           //_StyleProperties
525           new HtmlRenderedAttr("style", 3), 
526           new HtmlRenderedAttr("styleClass", "styleClass", "class=\"styleClass\"", 3),
527       };
528       
529       
530       MockResponseWriter writer = (MockResponseWriter)facesContext.getResponseWriter();
531       HtmlCheckAttributesUtil.checkRenderedAttributes(
532               inputDate, facesContext, writer, attrs);
533       if(HtmlCheckAttributesUtil.hasFailedAttrRender(attrs)) {
534           fail(HtmlCheckAttributesUtil.constructErrorMessage(attrs, writer.getWriter().toString()));
535       }
536   }
537 }