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 static org.easymock.EasyMock.eq;
018    import static org.easymock.EasyMock.expect;
019    import static org.easymock.EasyMock.isA;
020    
021    import org.apache.tapestry.BaseComponentTestCase;
022    import org.apache.tapestry.IActionListener;
023    import org.apache.tapestry.IForm;
024    import org.apache.tapestry.IMarkupWriter;
025    import org.apache.tapestry.IRender;
026    import org.apache.tapestry.IRequestCycle;
027    import org.apache.tapestry.RenderRewoundException;
028    import org.apache.tapestry.TapestryUtils;
029    import org.apache.tapestry.engine.DirectServiceParameter;
030    import org.apache.tapestry.engine.IEngineService;
031    import org.apache.tapestry.engine.ILink;
032    import org.apache.tapestry.listener.ListenerInvoker;
033    import org.apache.tapestry.valid.IValidationDelegate;
034    import org.apache.tapestry.web.WebResponse;
035    import org.testng.annotations.Test;
036    
037    /**
038     * Tests for {@link org.apache.tapestry.form.Form}. Most of the testing is, still alas, done with
039     * mock objects.
040     * 
041     * @author Howard Lewis Ship
042     * @since 4.0
043     */
044    @Test
045    public class FormTest extends BaseComponentTestCase
046    {
047        private IActionListener newListener()
048        {
049            return newMock(IActionListener.class);
050        }
051    
052        private FormSupport newFormSupport()
053        {
054            return newMock(FormSupport.class);
055        }
056    
057        protected void trainGetUniqueId(IRequestCycle cycle, String baseId, String uniqueId)
058        {
059            expect(cycle.getUniqueId(baseId)).andReturn(uniqueId);
060        }
061    
062        protected WebResponse newResponse()
063        {
064            return newMock(WebResponse.class);
065        }
066    
067        protected void trainGetNamespace(WebResponse response, String namespace)
068        {
069            expect(response.getNamespace()).andReturn(namespace);
070        }
071    
072        protected IValidationDelegate newDelegate()
073        {
074            return newMock(IValidationDelegate.class);
075        }
076    
077        public void testRewind()
078        {
079            IMarkupWriter writer = newWriter();
080            IRequestCycle cycle = newCycle();
081            FormSupport support = newFormSupport();
082            IValidationDelegate delegate = newDelegate();
083            IActionListener listener = newListener();
084            ListenerInvoker invoker = newListenerInvoker();
085    
086            Form form = newInstance(FormFixture.class, new Object[]
087            { "id", "myform", "expectedWriter", writer, "expectedRequestCycle", cycle,
088                    "formSupport", support, "listener", listener, "listenerInvoker", invoker,
089                    "delegate", delegate });
090    
091            expect(cycle.renderStackPush(form)).andReturn(form);
092            
093            trainStoreForm(cycle, form);
094            
095            trainIsRewinding(support, true);
096            
097            expect(support.rewind()).andReturn(FormConstants.SUBMIT_NORMAL);
098            
099            expect(delegate.getHasErrors()).andReturn(false);
100    
101            invoker.invokeListener(listener, form, cycle);
102            
103            TapestryUtils.removeForm(cycle);
104            
105            delegate.setFormComponent(null);
106            
107            expect(cycle.renderStackPop()).andReturn(form);
108            
109            replay();
110    
111            try
112            {
113                form.render(writer, cycle);
114            }
115            catch (RenderRewoundException ex)
116            {
117                assertSame(form, ex.getComponent());
118            }
119    
120            verify();
121        }
122    
123        private ListenerInvoker newListenerInvoker()
124        {
125            return newMock(ListenerInvoker.class);
126        }
127    
128        public void testBasicRender()
129        {
130            IMarkupWriter writer = newWriter();
131            IRequestCycle cycle = newCycle();
132            FormSupport support = newFormSupport();
133            WebResponse response = newResponse();
134            IEngineService direct = newEngineService();
135            ILink link = newLink();
136            IRender render = newRender();
137            IValidationDelegate delegate = newDelegate();
138    
139            Form form = newInstance(FormFixture.class, new Object[]
140            { "id", "myform", "expectedWriter", writer, "expectedRequestCycle", cycle,
141                    "formSupport", support, "response", response, "directService", direct, "method",
142                    "post", "delegate", delegate });
143            
144            expect(cycle.renderStackPush(form)).andReturn(form);
145            
146            trainStoreForm(cycle, form);
147            
148            trainIsRewinding(support, false);
149    
150            trainGetNamespace(response, "$ns");
151            
152            trainGetLinkCheckIgnoreParameter(
153                    direct,
154                    cycle,
155                    true,
156                    new DirectServiceParameter(form),
157                    link);
158    
159            trainRender(support, link, render, null, null);
160    
161            TapestryUtils.removeForm(cycle);
162    
163            delegate.setFormComponent(null);
164                
165            expect(cycle.renderStackPop()).andReturn(form);
166            
167            replay();
168    
169            form.render(writer, cycle);
170    
171            verify();
172        }
173    
174        public void testRenderWithScheme()
175        {
176            IMarkupWriter writer = newWriter();
177            IRequestCycle cycle = newCycle();
178            FormSupport support = newFormSupport();
179            WebResponse response = newResponse();
180            IEngineService direct = newEngineService();
181            
182            ILink link = newLink();
183            IRender render = newRender();
184            IValidationDelegate delegate = newDelegate();
185            
186            Form form = newInstance(FormFixture.class, new Object[]
187            { "id", "myform", "expectedWriter", writer, "expectedRequestCycle", cycle,
188                    "formSupport", support, "response", response, "directService", direct, "method",
189                    "post", "delegate", delegate, "scheme", "https", "port", new Integer(443) });
190            
191            expect(cycle.renderStackPush(form)).andReturn(form);
192            
193            trainStoreForm(cycle, form);
194            
195            trainIsRewinding(support, false);
196            
197            trainGetNamespace(response, "$ns");
198    
199            trainGetLinkCheckIgnoreParameter(
200                    direct,
201                    cycle,
202                    true,
203                    new DirectServiceParameter(form),
204                    link);
205            
206            trainRender(support, link, render, "https", new Integer(443));
207            
208            TapestryUtils.removeForm(cycle);
209            
210            delegate.setFormComponent(null);
211            
212            expect(cycle.renderStackPop()).andReturn(form);
213            
214            replay();
215    
216            form.render(writer, cycle);
217    
218            verify();
219        }
220    
221        protected void trainStoreForm(IRequestCycle cycle, IForm form)
222        {
223            trainGetAttribute(cycle, TapestryUtils.FORM_ATTRIBUTE, null);
224    
225            cycle.setAttribute(TapestryUtils.FORM_ATTRIBUTE, form);
226        }
227    
228        private void trainRender(FormSupport support, ILink link, IRender render, String scheme, Integer port)
229        {
230            support.render(eq("post"), isA(IRender.class), eq(link), eq(scheme), eq(port));
231        }
232    
233        protected void trainIsRewinding(FormSupport support, boolean isRewinding)
234        {
235            expect(support.isRewinding()).andReturn(isRewinding);
236        }
237    
238        public void testFindCancelListener()
239        {
240            IActionListener cancel = newListener();
241            IActionListener listener = newListener();
242    
243            replay();
244    
245            Form form = newInstance(Form.class, new Object[]
246            { "listener", listener, "cancel", cancel });
247    
248            assertSame(cancel, form.findListener(FormConstants.SUBMIT_CANCEL));
249    
250            verify();
251        }
252    
253        public void testFindCancelDefaultListener()
254        {
255            IActionListener listener = newListener();
256    
257            replay();
258    
259            Form form = (Form) newInstance(Form.class, "listener", listener);
260    
261            assertSame(listener, form.findListener(FormConstants.SUBMIT_CANCEL));
262    
263            verify();
264        }
265    
266        public void testFindRefreshListener()
267        {
268            IActionListener refresh = newListener();
269            IActionListener listener = newListener();
270    
271            replay();
272    
273            Form form = newInstance(Form.class, new Object[]
274            { "listener", listener, "refresh", refresh });
275    
276            assertSame(refresh, form.findListener(FormConstants.SUBMIT_REFRESH));
277    
278            verify();
279        }
280    
281        public void testFindRefreshListenerDefault()
282        {
283            IActionListener listener = newListener();
284    
285            replay();
286    
287            Form form = newInstance(Form.class, new Object[]
288            { "listener", listener });
289    
290            assertSame(listener, form.findListener(FormConstants.SUBMIT_REFRESH));
291    
292            verify();
293        }
294    
295        public void testFindListenerSuccess()
296        {
297            IActionListener cancel = newListener();
298            IActionListener refresh = newListener();
299            IActionListener success = newListener();
300            IActionListener listener = newListener();
301    
302            IValidationDelegate delegate = newDelegate(false);
303    
304            replay();
305    
306            Form form = newInstance(Form.class, new Object[]
307            { "delegate", delegate, "success", success, "cancel", cancel, "refresh", refresh,
308                    "listener", listener });
309    
310            assertSame(success, form.findListener(FormConstants.SUBMIT_NORMAL));
311    
312            verify();
313        }
314    
315        public void testFindListenerValidationErrors()
316        {
317            IActionListener cancel = newListener();
318            IActionListener refresh = newListener();
319            IActionListener success = newListener();
320            IActionListener listener = newListener();
321    
322            IValidationDelegate delegate = newDelegate(true);
323    
324            replay();
325            
326            Form form = newInstance(Form.class, new Object[]
327            { "delegate", delegate, "success", success, "cancel", cancel, "refresh", refresh,
328                    "listener", listener });
329    
330            assertSame(listener, form.findListener(FormConstants.SUBMIT_NORMAL));
331    
332            verify();
333        }
334    
335        public void test_Focus_Disabled()
336        {
337            IMarkupWriter writer = newWriter();
338            IRequestCycle cycle = newCycle();
339            FormSupport support = newFormSupport();
340            WebResponse response = newResponse();
341            IEngineService direct = newEngineService();
342            ILink link = newLink();
343            IRender render = newRender();
344            IValidationDelegate delegate = newDelegate();
345            
346            Form form = newInstance(FormFixture.class, new Object[]
347            { "id", "myform", "expectedWriter", writer, "expectedRequestCycle", cycle,
348                    "formSupport", support, "response", response, "directService", direct, "method",
349                    "post", "delegate", delegate, "focus", false });
350    
351            expect(cycle.renderStackPush(form)).andReturn(form);
352            
353            trainStoreForm(cycle, form);
354            
355            trainIsRewinding(support, false);
356            
357            trainGetNamespace(response, "$ns");
358            
359            trainGetLinkCheckIgnoreParameter(
360                    direct,
361                    cycle,
362                    true,
363                    new DirectServiceParameter(form),
364                    link);
365            
366            trainRender(support, link, render, null, null);
367            
368            TapestryUtils.removeForm(cycle);
369    
370            delegate.setFormComponent(null);
371            
372            expect(cycle.renderStackPop()).andReturn(form);
373            
374            replay();
375    
376            form.render(writer, cycle);
377    
378            verify();
379        }
380        
381        private IValidationDelegate newDelegate(boolean hasErrors)
382        {
383            IValidationDelegate delegate = newMock(IValidationDelegate.class);
384            
385            expect(delegate.getHasErrors()).andReturn(hasErrors);
386            
387            return delegate;
388        }
389    }