001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.form.translator;
016    
017    import static org.easymock.EasyMock.expect;
018    
019    import java.util.Calendar;
020    import java.util.Date;
021    import java.util.Locale;
022    
023    import org.apache.tapestry.IMarkupWriter;
024    import org.apache.tapestry.IRequestCycle;
025    import org.apache.tapestry.form.FormComponentContributorContext;
026    import org.apache.tapestry.form.FormComponentContributorTestCase;
027    import org.apache.tapestry.form.IFormComponent;
028    import org.apache.tapestry.form.ValidationMessages;
029    import org.apache.tapestry.json.JSONObject;
030    import org.apache.tapestry.valid.ValidationConstraint;
031    import org.apache.tapestry.valid.ValidationStrings;
032    import org.apache.tapestry.valid.ValidatorException;
033    import org.testng.annotations.AfterMethod;
034    import org.testng.annotations.Test;
035    
036    /**
037     * Test case for {@link DateTranslator}.
038     * 
039     * @author Paul Ferraro
040     * @since 4.0
041     */
042    @Test(sequential=true)
043    public class TestDateTranslator extends FormComponentContributorTestCase
044    {
045        private Calendar _calendar = Calendar.getInstance();
046        
047        @AfterMethod
048        protected void cleanup()
049        {
050            _calendar.clear();
051        }
052        
053        private Date buildDate(int year, int month, int day)
054        {
055            _calendar.set(Calendar.YEAR, year);
056            _calendar.set(Calendar.MONTH, month);
057            _calendar.set(Calendar.DATE, day);
058    
059            return _calendar.getTime();
060        }
061    
062        public void testDefaultFormat()
063        {
064            DateTranslator translator = new DateTranslator();
065            trainFormat(translator, buildDate(1976, Calendar.OCTOBER, 29), "10/29/1976");
066        }
067    
068        public void testCustomFormat()
069        {
070            DateTranslator translator = new DateTranslator();
071    
072            translator.setPattern("yyyy-MM-dd");
073    
074            trainFormat(translator, buildDate(1976, Calendar.OCTOBER, 29), "1976-10-29");
075        }
076    
077        public void testInitializerFormat()
078        {
079            DateTranslator translator = new DateTranslator("pattern=yyyy-MM-dd");
080    
081            trainFormat(translator, buildDate(1976, Calendar.OCTOBER, 29), "1976-10-29");
082        }
083    
084        private void trainFormat(DateTranslator translator, Date date, String expected)
085        {
086            IFormComponent field = newField();
087    
088            replay();
089    
090            String result = translator.format(field, Locale.ENGLISH, date);
091    
092            assertEquals(expected, result);
093    
094            verify();
095        }
096    
097        public void testNullFormat()
098        {
099            DateTranslator translator = new DateTranslator();
100    
101            replay();
102    
103            String result = translator.format(_component, null, null);
104    
105            assertEquals("", result);
106    
107            verify();
108        }
109    
110        public void testDefaultParse() throws Exception
111        {
112            DateTranslator translator = new DateTranslator();
113    
114            testParse(translator, "10/29/1976", buildDate(1976, Calendar.OCTOBER, 29));
115        }
116        
117        public void test_Time_Parse() throws Exception
118        {
119            DateTranslator translator = new DateTranslator();
120            
121            String input = "6:50 pm";
122            
123            translator.setPattern("hh:mm a");
124            
125            IFormComponent field = newField();
126            
127            ValidationMessages messages = newValidationMessages(Locale.ENGLISH);
128            
129            replay();
130            
131            Date result = (Date) translator.parse(field, messages, input);
132            
133            assertEquals(18, result.getHours());
134            assertEquals(50, result.getMinutes());
135            
136            verify();
137        }
138        
139        public void testCustomParse() throws Exception
140        {
141            DateTranslator translator = new DateTranslator();
142    
143            translator.setPattern("yyyy-MM-dd");
144    
145            testParse(translator, "1976-10-29", buildDate(1976, Calendar.OCTOBER, 29));
146        }
147    
148        public void testTrimmedParse() throws Exception
149        {
150            DateTranslator translator = new DateTranslator();
151    
152            translator.setTrim(true);
153    
154            testParse(translator, " 10/29/1976 ", buildDate(1976, Calendar.OCTOBER, 29));
155        }
156    
157        public void testEmptyParse()
158        {
159            DateTranslator translator = new DateTranslator();
160    
161            replay();
162    
163            try
164            {
165                Date result = (Date) translator.parse(_component, null, "");
166    
167                assertEquals(null, result);
168            }
169            catch (ValidatorException e)
170            {
171                unreachable();
172            }
173            finally
174            {
175                verify();
176            }
177        }
178    
179        private void testParse(DateTranslator translator, String date, Date expected) throws Exception
180        {
181            IFormComponent field = newField();
182    
183            ValidationMessages messages = newValidationMessages(Locale.ENGLISH);
184    
185            replay();
186    
187            Date result = (Date) translator.parse(field, messages, date);
188    
189            assertEquals(expected, result);
190    
191            verify();
192        }
193    
194        public void testFailedParseDefaultMessage() throws Exception
195        {
196            DateTranslator translator = new DateTranslator();
197    
198            failedParse(translator, null);
199        }
200    
201        public void testFailedParseCustomMessage() throws Exception
202        {
203            DateTranslator translator = new DateTranslator();
204            String message = "Field Name is an invalid date.";
205    
206            translator.setMessage(message);
207    
208            failedParse(translator, message);
209        }
210    
211        private void failedParse(DateTranslator translator, String overrideMessage)
212                throws Exception
213        {   
214            IFormComponent field = newField("My Field");
215            
216            ValidationMessages messages = newValidationMessages(Locale.ENGLISH);
217            
218            trainBuildMessage(
219                    messages,
220                    overrideMessage,
221                    ValidationStrings.INVALID_DATE,
222                    new Object[]
223                    { "My Field", "MM/DD/YYYY" },
224                    "final message");
225            
226            replay();
227    
228            try
229            {
230                System.out.println(translator.parse(field, messages, "Bad-Date"));
231    
232                unreachable();
233            }
234            catch (ValidatorException e)
235            {
236                assertEquals("final message", e.getMessage());
237                assertEquals(ValidationConstraint.DATE_FORMAT, e.getConstraint());
238            }
239    
240            verify();
241        }
242    
243        public void test_Render_Contribution()
244        {
245            DateTranslator translator = new DateTranslator();
246            IFormComponent field = newField("Date Field", "dateField", 1);
247            
248            JSONObject json = new JSONObject();
249            
250            IMarkupWriter writer = newWriter();
251            IRequestCycle cycle = newCycle();
252            
253            FormComponentContributorContext context = newMock(FormComponentContributorContext.class);
254            
255            expect(context.getProfile()).andReturn(json);
256            
257            trainGetLocale(context, Locale.ENGLISH);
258            
259            trainBuildMessage(context, null, ValidationStrings.INVALID_DATE, 
260                    new Object[] { "Date Field", 
261                    translator.getDateFormat(Locale.ENGLISH)
262                    .toLocalizedPattern().toUpperCase(Locale.ENGLISH)}, "invalid date");
263            
264            context.addInitializationScript(field, "dojo.require(\"tapestry.form.datetime\");");
265            
266            replay();
267            
268            translator.renderContribution(writer, cycle, context, field);
269            
270            verify();
271            
272            assertEquals(json.toString(),
273                    "{\"constraints\":{\"dateField\":" +
274                    "[[tapestry.form.datetime.isValidDate," +
275                    "{datePattern:\"MM/dd/yyyy\"}]]},\"dateField\":" +
276                    "{\"constraints\":[\"invalid date\"]}}");
277        }
278    
279        public void test_Trim_Render_Contribution()
280        {
281            DateTranslator dt = new DateTranslator("!lenient,trim");
282            assertFalse(dt.isLenient());
283            assertTrue(dt.isTrim());
284            
285            IMarkupWriter writer = newWriter();
286            IRequestCycle cycle = newCycle();
287            IFormComponent field = newField("Date Field", "dateField", 1);
288            
289            JSONObject json = new JSONObject();
290            
291            FormComponentContributorContext context = newMock(FormComponentContributorContext.class);
292            
293            expect(context.getProfile()).andReturn(json).anyTimes();
294            
295            trainGetLocale(context, Locale.ENGLISH);
296            
297            trainBuildMessage(context, null, ValidationStrings.INVALID_DATE, 
298                    new Object[] { "Date Field", 
299                    dt.getDateFormat(Locale.ENGLISH)
300                    .toLocalizedPattern().toUpperCase(Locale.ENGLISH)}, "invalid date");
301            
302            context.addInitializationScript(field, "dojo.require(\"tapestry.form.datetime\");");
303            
304            replay();
305    
306            dt.renderContribution(writer, cycle, context, field);
307    
308            verify();
309            
310            assertEquals(json.toString(),
311                    "{\"trim\":[\"dateField\"],\"constraints\":{\"dateField\":" +
312                    "[[tapestry.form.datetime.isValidDate,{datePattern:\"MM/dd/yyyy\",strict:true}]]}," +
313                    "\"dateField\":{\"constraints\":[\"invalid date\"]}}");
314        }
315    }