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