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.valid;
016    
017    import static org.easymock.EasyMock.checkOrder;
018    import static org.easymock.EasyMock.expect;
019    
020    import java.util.List;
021    
022    import org.apache.tapestry.IRender;
023    import org.apache.tapestry.form.IFormComponent;
024    import org.testng.annotations.Configuration;
025    import org.testng.annotations.Test;
026    
027    /**
028     * Test the class {@link ValidationDelegate}.
029     * 
030     * @author Howard Lewis Ship
031     * @since 1.0.8
032     */
033    @Test(sequential=true)
034    public class ValidationDelegateTest extends BaseValidatorTestCase
035    {
036        protected IFormComponent newField(String name, int count)
037        {
038            IFormComponent fc = newMock(IFormComponent.class);
039            checkOrder(fc, false);
040            
041            expect(fc.getName()).andReturn(name).anyTimes();
042    
043            return fc;
044        }
045    
046        private ValidationDelegate d = new ValidationDelegate();
047        
048        @Configuration(afterTestMethod = true)
049        public void resetDelegate()
050        {
051            d.clear();
052        }
053        
054        public void testHasErrorsEmpty()
055        {
056            assertEquals(false, d.getHasErrors());
057        }
058    
059        public void testFirstErrorEmpty()
060        {
061            assertNull(d.getFirstError());
062        }
063    
064        public void testInvalidInput()
065        {
066            IFormComponent field = newField("testAdd", 3);
067    
068            replay();
069    
070            String errorMessage = "Need a bigger one.";
071    
072            d.setFormComponent(field);
073            d.recordFieldInputValue("Bad Stuff");
074            d.record(new ValidatorException(errorMessage, ValidationConstraint.TOO_LARGE));
075    
076            List fieldTracking = d.getFieldTracking();
077    
078            assertEquals(1, fieldTracking.size());
079    
080            IFieldTracking t = (IFieldTracking) fieldTracking.get(0);
081    
082            assertSame(field, t.getComponent());
083            checkRender(errorMessage, t);
084            assertEquals("testAdd", t.getFieldName());
085            assertEquals("Bad Stuff", t.getInput());
086            assertEquals(ValidationConstraint.TOO_LARGE, t.getConstraint());
087    
088            assertTrue(d.getHasErrors());
089            assertEquals(errorMessage, ((RenderString) (d.getFirstError())).getString());
090    
091            verify();
092        }
093    
094        public void testValidatorErrorRenderer()
095        {
096            IFormComponent field = newField("testValidatorErrorRenderer", 3);
097    
098            replay();
099    
100            IRender errorRenderer = new RenderString("Just don't like it.");
101    
102            d.setFormComponent(field);
103            d.recordFieldInputValue("Bad Stuff");
104            d.record(new ValidatorException("Just don't like it.", errorRenderer,
105                    ValidationConstraint.CONSISTENCY));
106    
107            List fieldTracking = d.getFieldTracking();
108    
109            assertEquals(1, fieldTracking.size());
110    
111            IFieldTracking t = (IFieldTracking) fieldTracking.get(0);
112    
113            assertSame(field, t.getComponent());
114            assertSame(errorRenderer, t.getErrorRenderer());
115            assertEquals("testValidatorErrorRenderer", t.getFieldName());
116            assertEquals("Bad Stuff", t.getInput());
117            assertEquals(ValidationConstraint.CONSISTENCY, t.getConstraint());
118    
119            assertTrue(d.getHasErrors());
120            assertSame(errorRenderer, d.getFirstError());
121    
122            verify();
123        }
124    
125        public void testNoError()
126        {
127            IFormComponent field = newField("input", 2);
128    
129            replay();
130    
131            d.setFormComponent(field);
132            d.recordFieldInputValue("Futurama");
133    
134            List fieldTracking = d.getFieldTracking();
135            assertEquals(1, fieldTracking.size());
136    
137            IFieldTracking t = (IFieldTracking) fieldTracking.get(0);
138    
139            assertSame(field, t.getComponent());
140            assertNull(t.getErrorRenderer());
141            assertEquals(false, t.isInError());
142            assertEquals("Futurama", t.getInput());
143            assertNull(t.getConstraint());
144    
145            assertEquals(false, d.getHasErrors());
146            assertNull(d.getFirstError());
147    
148            verify();
149        }
150    
151        public void testUnassociatedErrors()
152        {
153            IFormComponent field = newField("input", 2);
154    
155            replay();
156    
157            d.setFormComponent(field);
158            d.recordFieldInputValue("Bender");
159    
160            d.setFormComponent(null);
161            d.record("Overload!", ValidationConstraint.CONSISTENCY);
162    
163            assertEquals(true, d.getHasErrors());
164    
165            List fieldTracking = d.getFieldTracking();
166            assertEquals(2, fieldTracking.size());
167    
168            IFieldTracking t0 = (IFieldTracking) fieldTracking.get(0);
169            assertEquals(false, t0.isInError());
170            assertSame(field, t0.getComponent());
171    
172            IFieldTracking t1 = (IFieldTracking) fieldTracking.get(1);
173            assertNull(t1.getComponent());
174            assertEquals(true, t1.isInError());
175            checkRender("Overload!", t1);
176    
177            checkRender("Overload!", d.getFirstError());
178    
179            List trackings = d.getUnassociatedTrackings();
180            assertEquals(1, trackings.size());
181            assertEquals(t1, trackings.get(0));
182    
183            trackings = d.getAssociatedTrackings();
184            assertEquals(1, trackings.size());
185            assertEquals(t0, trackings.get(0));
186    
187            verify();
188        }
189    
190        private void checkRender(String errorMessage, IFieldTracking tracking)
191        {
192            IRender render = tracking.getErrorRenderer();
193    
194            checkRender(errorMessage, render);
195        }
196    
197        private void checkRender(String errorMessage, IRender render)
198        {
199            assertEquals(errorMessage, ((RenderString) render).getString());
200        }
201    
202        public void testMultipleInvalidInput()
203        {
204            IFormComponent f1 = newField("monty", 3);
205            IFormComponent f2 = newField("python", 3);
206    
207            replay();
208    
209            String e1 = "And now for something completely different.";
210            String e2 = "A man with three buttocks.";
211    
212            d.setFormComponent(f1);
213            d.recordFieldInputValue("Monty");
214            d.record(new ValidatorException(e1, null));
215    
216            d.setFormComponent(f2);
217            d.recordFieldInputValue("Python");
218            d.record(new ValidatorException(e2, null));
219    
220            List fieldTracking = d.getFieldTracking();
221            assertEquals(2, fieldTracking.size());
222    
223            IFieldTracking t = (IFieldTracking) fieldTracking.get(0);
224    
225            assertSame(f1, t.getComponent());
226            checkRender(e1, t);
227    
228            t = (IFieldTracking) fieldTracking.get(1);
229            assertEquals("Python", t.getInput());
230            checkRender(e2, t);
231            assertSame(f2, t.getComponent());
232    
233            verify();
234        }
235    
236        public void testReset()
237        {
238            IFormComponent f1 = newField("monty", 4);
239            IFormComponent f2 = newField("python", 3);
240    
241            replay();
242    
243            String e1 = "And now for something completely different.";
244            String e2 = "A man with three buttocks.";
245    
246            d.setFormComponent(f1);
247            d.recordFieldInputValue("Monty");
248            d.record(new ValidatorException(e1, null));
249    
250            d.setFormComponent(f2);
251            d.recordFieldInputValue("Python");
252            d.record(new ValidatorException(e2, null));
253    
254            // Now, wipe out info on f1
255    
256            d.setFormComponent(f1);
257            d.reset();
258    
259            List fieldTracking = d.getFieldTracking();
260            assertEquals(1, fieldTracking.size());
261    
262            IFieldTracking t = (IFieldTracking) fieldTracking.get(0);
263            assertEquals("Python", t.getInput());
264            checkRender(e2, t);
265            assertEquals(f2, t.getComponent());
266    
267            verify();
268        }
269    
270        public void testResetAll()
271        {
272            IFormComponent f1 = newField("monty", 3);
273            IFormComponent f2 = newField("python", 3);
274    
275            replay();
276    
277            String e1 = "And now for something completely different.";
278            String e2 = "A man with three buttocks.";
279    
280            d.setFormComponent(f1);
281            d.record(new ValidatorException(e1, null));
282    
283            d.setFormComponent(f2);
284            d.record(new ValidatorException(e2, null));
285    
286            d.setFormComponent(f1);
287            d.reset();
288    
289            d.setFormComponent(f2);
290            d.reset();
291    
292            assertNull(d.getFieldTracking());
293    
294            assertEquals(false, d.getHasErrors());
295            assertNull(d.getFirstError());
296    
297            verify();
298        }
299    
300        /** @since 4.0 */
301    
302        public void testGetErrorRenderers()
303        {
304            List l = d.getErrorRenderers();
305    
306            assertEquals(true, l.isEmpty());
307    
308            IFormComponent f1 = newField("monty", 2);
309            IFormComponent f2 = newField("python", 3);
310    
311            IRender f2ErrorRenderer = newMock(IRender.class);
312    
313            replay();
314    
315            d.setFormComponent(f1);
316            d.recordFieldInputValue("f1 input");
317    
318            d.setFormComponent(f2);
319            d.recordFieldInputValue("f2 input");
320            d.record(f2ErrorRenderer, null);
321    
322            l = d.getErrorRenderers();
323            assertEquals(1, l.size());
324            assertSame(f2ErrorRenderer, l.get(0));
325    
326            verify();
327        }
328    
329        public void testClearErrors()
330        {
331            IFormComponent f = newField("input", 4);
332    
333            replay();
334    
335            d.setFormComponent(f);
336            d.recordFieldInputValue("hello");
337            d.record("An error in the input field.", null);
338    
339            assertEquals(true, d.getHasErrors());
340    
341            assertNotNull(d.getFirstError());
342    
343            d.clearErrors();
344    
345            assertEquals(false, d.getHasErrors());
346    
347            d.setFormComponent(f);
348    
349            assertEquals("hello", d.getFieldInputValue());
350    
351            verify();
352        }
353    
354        public void testRegisterForFocus()
355        {
356            IFormComponent fred = newFieldWithClientId("fred");
357            IFormComponent barney = newFieldWithClientId("barney");
358            IFormComponent wilma = newField();
359    
360            ValidationDelegate vd = new ValidationDelegate();
361    
362            replay();
363    
364            vd.registerForFocus(fred, ValidationConstants.NORMAL_FIELD);
365            vd.registerForFocus(barney, ValidationConstants.REQUIRED_FIELD);
366            vd.registerForFocus(wilma, ValidationConstants.NORMAL_FIELD);
367    
368            assertEquals("barney", vd.getFocusField());
369    
370            verify();
371        }
372    
373        private IFormComponent newFieldWithClientId(String clientId)
374        {
375            IFormComponent field = newMock(IFormComponent.class);
376    
377            expect(field.getClientId()).andReturn(clientId);
378    
379            return field;
380        }
381    
382        /**
383         * Test {@link ValidationDelegate#record(IFormComponent, String)}.
384         * 
385         * @since 4.0
386         */
387        public void testSimpleRecord()
388        {
389            IFormComponent field = newField();
390    
391            trainGetName(field, "myField");
392            trainGetName(field, "myField");
393    
394            replay();
395    
396            ValidationDelegate delegate = new ValidationDelegate();
397    
398            delegate.record(field, "My Error Message");
399    
400            List list = delegate.getFieldTracking();
401    
402            assertEquals(1, list.size());
403    
404            IFieldTracking ft = (IFieldTracking) list.get(0);
405    
406            assertEquals(true, ft.isInError());
407            assertSame(field, ft.getComponent());
408            assertNull(ft.getConstraint());
409            assertEquals("My Error Message", ft.getErrorRenderer().toString());
410    
411            verify();
412        }
413    
414        public void testSimpleRecordUnassociated()
415        {
416            ValidationDelegate delegate = new ValidationDelegate();
417    
418            delegate.record(null, "My Error Message");
419    
420            List list = delegate.getUnassociatedTrackings();
421    
422            assertEquals(1, list.size());
423    
424            IFieldTracking ft = (IFieldTracking) list.get(0);
425    
426            assertEquals(true, ft.isInError());
427            assertNull(ft.getComponent());
428            assertNull(ft.getConstraint());
429            assertEquals("My Error Message", ft.getErrorRenderer().toString());
430    
431        }
432    
433        protected void trainGetName(IFormComponent field, String name)
434        {
435            expect(field.getName()).andReturn(name);
436        }
437    }