001    // Copyright 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;
016    
017    import java.util.ArrayList;
018    import java.util.Collection;
019    import java.util.LinkedList;
020    import java.util.List;
021    import java.util.Map;
022    
023    import org.apache.hivemind.util.PropertyUtils;
024    import org.apache.tapestry.IActionListener;
025    import org.apache.tapestry.IBinding;
026    import org.apache.tapestry.IForm;
027    import org.apache.tapestry.IMarkupWriter;
028    import org.apache.tapestry.IRequestCycle;
029    import org.apache.tapestry.IScript;
030    import org.apache.tapestry.PageRenderSupport;
031    import org.apache.tapestry.engine.DirectServiceParameter;
032    import org.apache.tapestry.engine.IEngineService;
033    import org.apache.tapestry.engine.ILink;
034    import org.apache.tapestry.listener.ListenerInvokerTerminator;
035    import org.apache.tapestry.test.Creator;
036    import org.apache.tapestry.util.ScriptUtils;
037    import org.apache.tapestry.valid.IValidationDelegate;
038    import org.apache.tapestry.valid.ValidationConstants;
039    import static org.easymock.EasyMock.*;
040    import org.testng.annotations.Test;
041    
042    /**
043     * Tests for {@link org.apache.tapestry.form.Submit}.
044     * 
045     * @author Howard M. Lewis Ship
046     * @since 4.0
047     */
048    @Test
049    public class TestSubmit extends BaseFormComponentTestCase
050    {
051        public void test_Prerendered()
052        {
053            Creator creator = new Creator();
054            Submit submit = (Submit) creator.newInstance(Submit.class);
055    
056            IForm form = newMock(IForm.class);
057            IRequestCycle cycle = newCycle();
058            IMarkupWriter writer = newWriter();
059    
060            trainGetForm(cycle, form);
061    
062            trainWasPrerendered(form, writer, submit, true);
063    
064            replay();
065    
066            submit.renderComponent(writer, cycle);
067    
068            verify();
069        }
070    
071        public void test_Render()
072        {
073            Creator creator = new Creator();
074            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] {"submitType", "submit"});
075    
076            IValidationDelegate delegate = newDelegate();
077            IForm form = newForm();
078            IRequestCycle cycle = newCycle();
079            IMarkupWriter writer = newWriter();
080    
081            trainGetForm(cycle, form);
082    
083            trainWasPrerendered(form, writer, submit, false);
084    
085            trainGetDelegate(form, delegate);
086            
087            delegate.setFormComponent(submit);
088    
089            trainGetElementId(form, submit, "fred");
090    
091            trainIsRewinding(form, false);
092    
093            trainIsRewinding(cycle, false);
094            
095            form.setFormFieldUpdating(true);
096            
097            writer.beginEmpty("input");
098            writer.attribute("type", "submit");
099            writer.attribute("name", "fred");
100            writer.attribute("id", "fred");
101            writer.closeTag();
102    
103            trainIsInError(delegate, false);
104    
105            delegate.registerForFocus(submit, ValidationConstants.NORMAL_FIELD);
106    
107            replay();
108    
109            submit.renderComponent(writer, cycle);
110    
111            verify();
112        }
113    
114        public void test_Render_Function_Hash()
115        {
116            Creator creator = new Creator();
117            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[] {"submitType", "submit"});
118            
119            IValidationDelegate delegate = newDelegate();
120            IForm form = newForm();
121            IRequestCycle cycle = newCycle();
122            IMarkupWriter writer = newWriter();
123    
124            trainGetForm(cycle, form);
125    
126            trainWasPrerendered(form, writer, submit, false);
127    
128            trainGetDelegate(form, delegate);
129            
130            delegate.setFormComponent(submit);
131    
132            trainGetElementId(form, submit, "fred");
133    
134            trainIsRewinding(form, false);
135    
136            trainIsRewinding(cycle, false);
137            
138            form.setFormFieldUpdating(true);
139            
140            writer.beginEmpty("input");
141            writer.attribute("type", "submit");
142            writer.attribute("name", "fred");
143            writer.attribute("id", "fred");
144            writer.closeTag();
145    
146            trainIsInError(delegate, false);
147    
148            delegate.registerForFocus(submit, ValidationConstants.NORMAL_FIELD);
149    
150            replay();
151    
152            submit.renderComponent(writer, cycle);
153            
154            String hash = ScriptUtils.functionHash("onchange" + submit.hashCode());
155            
156            assertEquals(ScriptUtils.functionHash("onchange" + submit.hashCode()), hash);
157            
158            verify();
159        }
160        
161        public void test_Render_Disabled()
162        {
163            Creator creator = new Creator();
164            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
165            { "disabled", Boolean.TRUE, "submitType", "submit" });
166    
167            IValidationDelegate delegate = newDelegate();
168            IForm form = newForm();
169            IRequestCycle cycle = newCycle();
170            IMarkupWriter writer = newWriter();
171    
172            trainGetForm(cycle, form);
173    
174            trainWasPrerendered(form, writer, submit, false);
175    
176            trainGetDelegate(form, delegate);
177    
178            delegate.setFormComponent(submit);
179    
180            trainGetElementId(form, submit, "fred");
181    
182            trainIsRewinding(form, false);
183    
184            trainIsRewinding(cycle, false);
185    
186            form.setFormFieldUpdating(true);
187            
188            writer.beginEmpty("input");
189            writer.attribute("type", "submit");
190            writer.attribute("name", "fred");
191            writer.attribute("disabled", "disabled");
192            writer.attribute("id", "fred");
193            writer.closeTag();
194    
195            replay();
196    
197            submit.renderComponent(writer, cycle);
198    
199            verify();
200        }
201    
202        public void test_Render_With_Label()
203        {
204            Creator creator = new Creator();
205            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
206            { "label", "flintstone", "submitType", "submit" });
207    
208            IValidationDelegate delegate = newDelegate();
209            IForm form = newForm();
210            IRequestCycle cycle = newCycle();
211            IMarkupWriter writer = newWriter();
212    
213            trainGetForm(cycle, form);
214    
215            trainWasPrerendered(form, writer, submit, false);
216    
217            trainGetDelegate(form, delegate);
218    
219            delegate.setFormComponent(submit);
220            
221            trainGetElementId(form, submit, "fred");
222    
223            trainIsRewinding(form, false);
224            
225            trainIsRewinding(cycle, false);
226    
227            form.setFormFieldUpdating(true);
228            
229            writer.beginEmpty("input");
230            writer.attribute("type", "submit");
231            writer.attribute("name", "fred");
232            writer.attribute("value", "flintstone");
233            writer.attribute("id", "fred");
234            writer.closeTag();
235    
236            trainIsInError(delegate, false);
237    
238            delegate.registerForFocus(submit, ValidationConstants.NORMAL_FIELD);
239    
240            replay();
241    
242            submit.renderComponent(writer, cycle);
243    
244            verify();
245        }
246    
247        public void test_SubmitType_OnClick()
248        {
249            IScript script = newMock(IScript.class);
250            Submit submit = newInstance(Submit.class, 
251                    new Object[] {"submitType", "cancel", "submitScript", script});
252            
253            IValidationDelegate delegate = newDelegate();
254            IForm form = newForm();
255            IRequestCycle cycle = newCycle();
256            IMarkupWriter writer = newWriter();
257    
258            trainGetForm(cycle, form);
259    
260            trainWasPrerendered(form, writer, submit, false);
261    
262            trainGetDelegate(form, delegate);
263            
264            delegate.setFormComponent(submit);
265    
266            trainGetElementId(form, submit, "fred");
267    
268            trainIsRewinding(form, false);
269    
270            trainIsRewinding(cycle, false);
271    
272            form.setFormFieldUpdating(true);
273            
274            writer.beginEmpty("input");
275            writer.attribute("type", "submit");
276            writer.attribute("name", "fred");
277            writer.attribute("id", "fred");
278            
279            expect(form.getClientId()).andReturn("formtest");
280            
281            writer.attribute("onClick", "tapestry.form.cancel('formtest','fred')");
282            
283            writer.closeTag();
284    
285            trainIsInError(delegate, false);
286    
287            delegate.registerForFocus(submit, ValidationConstants.NORMAL_FIELD);
288    
289            replay();
290    
291            submit.renderComponent(writer, cycle);
292    
293            verify();
294        }
295        
296        public void test_SubmitType_OnClick_Disabled()
297        {
298            Submit submit = newInstance(Submit.class, new Object[] {
299                "disabled", Boolean.TRUE
300                });
301            
302            IValidationDelegate delegate = newDelegate();
303            IForm form = newForm();
304            IRequestCycle cycle = newCycle();
305            IMarkupWriter writer = newWriter();
306    
307            trainGetForm(cycle, form);
308    
309            trainWasPrerendered(form, writer, submit, false);
310    
311            trainGetDelegate(form, delegate);
312            
313            delegate.setFormComponent(submit);
314    
315            trainGetElementId(form, submit, "fred");
316    
317            trainIsRewinding(form, false);
318    
319            trainIsRewinding(cycle, false);
320    
321            form.setFormFieldUpdating(true);
322            
323            writer.beginEmpty("input");
324            writer.attribute("type", "submit");
325            writer.attribute("name", "fred");
326            writer.attribute("disabled", "disabled");
327            writer.attribute("id", "fred");
328            writer.closeTag();
329            
330            replay();
331            
332            submit.renderComponent(writer, cycle);
333    
334            verify();
335        }
336        
337        public void test_SubmitType_Script_OnClick()
338        {
339            IScript script = newMock(IScript.class);
340            IForm form = newForm();
341            IBinding binding = newMock(IBinding.class);
342            
343            Submit submit = newInstance(Submit.class, 
344                    new Object[] {"submitType", "cancel", 
345                "submitScript", script, "form", form});
346            
347            submit.setBinding("onClick", binding);
348            
349            IRequestCycle cycle = newCycle();
350            IMarkupWriter writer = newWriter();
351            
352            PageRenderSupport prs = newPageRenderSupport();
353            trainGetPageRenderSupport(cycle, prs);
354            
355            script.execute(eq(submit), eq(cycle), eq(prs), isA(Map.class));
356            
357            replay();
358            
359            submit.renderSubmitBindings(writer, cycle);
360    
361            verify();
362        }
363        
364        public void test_Submit_Async()
365        {
366            List updates = new ArrayList();
367            updates.add("bsComponent");
368            
369            IScript script = newMock(IScript.class);
370            IForm form = newForm();
371            IBinding binding = newMock(IBinding.class);
372            
373            IEngineService engine = newEngineService();
374            ILink link = newMock(ILink.class);
375            
376            Submit submit = newInstance(Submit.class,
377                                        "submitType", "cancel",
378                                        "submitScript", script, "form", form,
379                                        "async", true, "updateComponents", updates,
380                                        "directService", engine);
381            
382            submit.setBinding("onClick", binding);
383            
384            IRequestCycle cycle = newCycle();
385            IMarkupWriter writer = newWriter();
386            
387            expect(engine.getLink(eq(true), isA(DirectServiceParameter.class))).andReturn(link);
388            expect(link.getURL()).andReturn("/test/url");
389            
390            PageRenderSupport prs = newPageRenderSupport();
391            trainGetPageRenderSupport(cycle, prs);
392            
393            script.execute(eq(submit), eq(cycle), eq(prs), isA(Map.class));
394            
395            replay();
396            
397            submit.renderSubmitBindings(writer, cycle);
398    
399            verify();
400        }
401        
402        public void test_Rewinding_Disabled()
403        {
404            Creator creator = new Creator();
405            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
406            { "disabled", Boolean.TRUE });
407    
408            IValidationDelegate delegate = newDelegate();
409            IForm form = newForm();
410            IRequestCycle cycle = newCycle();
411            IMarkupWriter writer = newWriter();
412    
413            trainGetForm(cycle, form);
414    
415            trainWasPrerendered(form, writer, submit, false);
416    
417            expect(form.getDelegate()).andReturn(delegate);
418            
419            delegate.setFormComponent(submit);
420    
421            trainGetElementId(form, submit, "fred");
422    
423            trainIsRewinding(form, true);
424    
425            replay();
426    
427            submit.renderComponent(writer, cycle);
428    
429            verify();
430        }
431    
432        public void test_Rewind_Not_Form()
433        {
434            Creator creator = new Creator();
435            Submit submit = (Submit) creator.newInstance(Submit.class);
436    
437            IValidationDelegate delegate = newDelegate();
438            IForm form = newForm();
439            IRequestCycle cycle = newCycle();
440            IMarkupWriter writer = newWriter();
441    
442            trainGetForm(cycle, form);
443    
444            trainWasPrerendered(form, writer, submit, false);
445    
446            expect(form.getDelegate()).andReturn(delegate);
447            
448            delegate.setFormComponent(submit);
449    
450            trainGetElementId(form, submit, "fred");
451    
452            trainIsRewinding(form, false);
453            trainIsRewinding(cycle, true);
454    
455            replay();
456    
457            submit.renderComponent(writer, cycle);
458    
459            verify();
460        }
461    
462        public void test_Rewind_Not_Trigger()
463        {
464            Creator creator = new Creator();
465            Submit submit = (Submit) creator.newInstance(Submit.class);
466    
467            IValidationDelegate delegate = newDelegate();
468            IForm form = newForm();
469            IRequestCycle cycle = newCycle();
470            IMarkupWriter writer = newWriter();
471    
472            trainGetForm(cycle, form);
473    
474            trainWasPrerendered(form, writer, submit, false);
475    
476            expect(form.getDelegate()).andReturn(delegate);
477            
478            delegate.setFormComponent(submit);
479    
480            trainGetElementId(form, submit, "fred");
481    
482            trainIsRewinding(form, true);
483    
484            trainGetParameter(cycle, "fred", null);
485    
486            replay();
487    
488            submit.renderComponent(writer, cycle);
489    
490            verify();
491        }
492    
493        public void test_Rewind_Triggered()
494        {
495            Creator creator = new Creator();
496            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
497            { "tag", "clicked" });
498    
499            IBinding binding = newBinding();
500            submit.setBinding("selected", binding);
501    
502            IValidationDelegate delegate = newDelegate();
503            IForm form = newForm();
504            IRequestCycle cycle = newCycle();
505            IMarkupWriter writer = newWriter();
506    
507            trainGetForm(cycle, form);
508    
509            trainWasPrerendered(form, writer, submit, false);
510    
511            expect(form.getDelegate()).andReturn(delegate);
512    
513            delegate.setFormComponent(submit);
514    
515            trainGetElementId(form, submit, "fred");
516    
517            trainIsRewinding(form, true);
518    
519            trainGetParameter(cycle, "fred", "flintstone");
520    
521            replay();
522    
523            submit.renderComponent(writer, cycle);
524    
525            assertEquals("clicked", PropertyUtils.read(submit, "selected"));
526    
527            verify();
528        }
529    
530        public void test_Trigger_With_Listener()
531        {
532            IActionListener listener = newListener();
533            IForm form = newForm();
534            IRequestCycle cycle = newCycle();
535    
536            Creator creator = new Creator();
537            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
538            { "listener", listener, "listenerInvoker", new ListenerInvokerTerminator() });
539    
540            listener.actionTriggered(submit, cycle);
541    
542            replay();
543    
544            submit.handleClick(cycle, form);
545    
546            verify();
547        }
548    
549        public void test_Trigger_With_Action()
550        {
551            IActionListener action = newListener();
552            MockForm form = new MockForm();
553            IRequestCycle cycle = newCycle();
554    
555            Creator creator = new Creator();
556            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
557            { "action", action, "listenerInvoker",
558                    new ListenerInvokerTerminator() });
559    
560            replay();
561    
562            submit.handleClick(cycle, form);
563    
564            verify();
565    
566            action.actionTriggered(submit, cycle);
567    
568            replay();
569    
570            form.runDeferred();
571    
572            verify();
573        }
574    
575        public void test_Trigger_With_Action_And_Single_Parameter()
576        {
577            IActionListener action = newListener();
578            MockForm form = new MockForm();
579            IRequestCycle cycle = newCycle();
580            
581            Object parameter = new Object();
582            Creator creator = new Creator();
583            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
584            { "action", action, "parameters", parameter, "listenerInvoker",
585                    new ListenerInvokerTerminator() });
586            
587            cycle.setListenerParameters(aryEq(new Object[] { parameter }));
588    
589            replay();
590    
591            submit.handleClick(cycle, form);
592    
593            verify();
594    
595            action.actionTriggered(submit, cycle);
596    
597            replay();
598    
599            form.runDeferred();
600    
601            verify();
602        }
603    
604            public void test_Trigger_With_Action_And_Object_Array_Parameter()
605        {
606            IActionListener action = newListener();
607            MockForm form = new MockForm();
608            IRequestCycle cycle = newCycle();
609    
610            Object parameter = new Object[] {"p1", "p2"};
611            Creator creator = new Creator();
612            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
613            { "action", action, "parameters", parameter, "listenerInvoker",
614                    new ListenerInvokerTerminator() });
615    
616            cycle.setListenerParameters(aryEq(new Object[] { "p1", "p2" }));
617    
618            replay();
619    
620            submit.handleClick(cycle, form);
621    
622            verify();
623    
624            action.actionTriggered(submit, cycle);
625    
626            replay();
627    
628            form.runDeferred();
629    
630            verify();
631        }
632    
633        public void test_Trigger_With_Action_And_Collection_Parameter()
634        {
635            IActionListener action = newListener();
636            MockForm form = new MockForm();
637            IRequestCycle cycle = newCycle();
638    
639            Collection parameters = new LinkedList();
640            parameters.add("p1");
641            parameters.add("p2");
642    
643            Creator creator = new Creator();
644            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
645            { "action", action, "parameters", parameters, "listenerInvoker",
646                    new ListenerInvokerTerminator() });
647    
648            cycle.setListenerParameters(aryEq(new Object[]{ "p1", "p2" }));
649    
650            replay();
651    
652            submit.handleClick(cycle, form);
653    
654            verify();
655    
656            action.actionTriggered(submit, cycle);
657    
658            replay();
659    
660            form.runDeferred();
661    
662            verify();
663        }
664        
665        public void test_Trigger_With_Listener_And_Action()
666        {
667            IActionListener listener = newListener();
668            IActionListener action = newListener();
669            
670            MockForm form = new MockForm();
671            IRequestCycle cycle = newCycle();
672    
673            Creator creator = new Creator();
674            Submit submit = (Submit) creator.newInstance(Submit.class, new Object[]
675            { "listener", listener, "action", action, "listenerInvoker",
676                    new ListenerInvokerTerminator() });
677    
678            listener.actionTriggered(submit, cycle);
679            
680            replay();
681    
682            submit.handleClick(cycle, form);
683    
684            verify();
685    
686            action.actionTriggered(submit, cycle);
687    
688            replay();
689    
690            form.runDeferred();
691    
692            verify();
693        }
694       
695    }