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.dojo.form;
016    
017    import org.apache.tapestry.*;
018    import org.apache.tapestry.engine.DirectServiceParameter;
019    import org.apache.tapestry.engine.IEngineService;
020    import org.apache.tapestry.engine.ILink;
021    import org.apache.tapestry.form.BaseFormComponentTestCase;
022    import org.apache.tapestry.form.MockDelegate;
023    import org.apache.tapestry.form.ValidatableFieldSupport;
024    import org.apache.tapestry.json.IJSONWriter;
025    import org.apache.tapestry.json.JSONObject;
026    import org.apache.tapestry.services.DataSqueezer;
027    import org.apache.tapestry.services.ResponseBuilder;
028    import org.apache.tapestry.valid.IValidationDelegate;
029    import org.apache.tapestry.valid.ValidatorException;
030    import static org.easymock.EasyMock.*;
031    import org.testng.annotations.DataProvider;
032    import org.testng.annotations.Test;
033    
034    import java.util.ArrayList;
035    import java.util.List;
036    import java.util.Map;
037    
038    /**
039     * Tests for {@link org.apache.tapestry.form.TextField}.
040     *
041     * @author Howard M. Lewis Ship
042     * @since 4.0
043     */
044    @Test(sequential=true)
045    public class TestAutocompleter extends BaseFormComponentTestCase
046    {
047        private IAutocompleteModel createModel()
048        {
049            List values = new ArrayList();
050    
051            SimpleBean s1 = new SimpleBean(new Integer(1), "Simple 1", 100);
052            SimpleBean s2 = new SimpleBean(new Integer(2), "Simple 2", 200);
053            SimpleBean s3 = new SimpleBean(new Integer(3), "Simple 3", 300);
054    
055            values.add(s1);
056            values.add(s2);
057            values.add(s3);
058    
059            return new DefaultAutocompleteModel(values, "id", "label");
060        }
061    
062        public void test_Rewind()
063        {
064            IAutocompleteModel model = createModel();
065            ValidatableFieldSupport vfs = newMock(ValidatableFieldSupport.class);
066            DataSqueezer ds = newMock(DataSqueezer.class);
067    
068            Autocompleter component = newInstance(Autocompleter.class,
069                                                  new Object[] { "model", model, "validatableFieldSupport", vfs,
070                                                                 "dataSqueezer", ds});
071    
072            IRequestCycle cycle = newMock(IRequestCycle.class);
073            IForm form = newMock(IForm.class);
074    
075            IMarkupWriter writer = newWriter();
076    
077            IValidationDelegate delegate = newDelegate();
078    
079            expect(cycle.renderStackPush(component)).andReturn(component);
080    
081            trainGetForm(cycle, form);
082            trainWasPrerendered(form, writer, component, false);
083            trainGetDelegate(form, delegate);
084    
085            delegate.setFormComponent(component);
086    
087            trainGetElementId(form, component, "barney");
088            trainIsRewinding(form, true);
089    
090            trainGetParameter(cycle, "barney", "1");
091    
092            expect(ds.unsqueeze("1")).andReturn(new Integer(1));
093    
094            SimpleBean match = new SimpleBean(new Integer(1), null, -1);
095    
096            try
097            {
098                vfs.validate(component, writer, cycle, match);
099            }
100            catch (ValidatorException e)
101            {
102                unreachable();
103            }
104    
105            expect(cycle.renderStackPop()).andReturn(component);
106    
107            replay();
108    
109            component.render(writer, cycle);
110    
111            verify();
112    
113            assertEquals(match, component.getValue());
114        }
115    
116        public void test_Rewind_NotForm()
117        {
118            Autocompleter component = (Autocompleter) newInstance(Autocompleter.class);
119    
120            IRequestCycle cycle = newMock(IRequestCycle.class);
121            IForm form = newMock(IForm.class);
122    
123            IMarkupWriter writer = newWriter();
124    
125            IValidationDelegate delegate = newDelegate();
126    
127            expect(cycle.renderStackPush(component)).andReturn(component);
128    
129            trainGetForm(cycle, form);
130            trainWasPrerendered(form, writer, component, false);
131            trainGetDelegate(form, delegate);
132    
133            delegate.setFormComponent(component);
134    
135            trainGetElementId(form, component, "barney");
136            trainIsRewinding(form, false);
137            trainIsRewinding(cycle, true);
138    
139            expect(cycle.renderStackPop()).andReturn(component);
140    
141            replay();
142    
143            component.render(writer, cycle);
144    
145            verify();
146        }
147    
148        @DataProvider(name="renderings")
149        public Object[][] createRenderings() {
150            return new Object[][] {
151              {"<span class=\"prefix\"><select name=\"fred\" autocomplete=\"off\" id=\"fred\" class=\"validation-delegate\"> </select></span>",
152               Boolean.FALSE},
153              {"<span class=\"prefix\"><select name=\"fred\" autocomplete=\"off\" id=\"fred\" class=\"validation-delegate\"> <option " +
154               "value=\"1p\">Simple 1</option><option value=\"2p\" selected=\"selected\">Simple 2</option><option value=\"3p\">Simple 3</option></select></span>",
155               Boolean.TRUE}
156            };
157        }
158    
159        @Test(dataProvider = "renderings")
160        public void test_Render(String outcome, Boolean local)
161        {
162            IAutocompleteModel model = createModel();
163            ValidatableFieldSupport vfs = newMock(ValidatableFieldSupport.class);
164            DataSqueezer ds = newMock(DataSqueezer.class);
165            ResponseBuilder resp = newMock(ResponseBuilder.class);
166    
167            IRequestCycle cycle = newMock(IRequestCycle.class);
168            IForm form = newMock(IForm.class);
169            checkOrder(form, false);
170    
171            MockDelegate delegate = new MockDelegate();
172    
173            IEngineService engine = newEngineService();
174            ILink link = newLink();
175    
176            IScript script = newMock(IScript.class);
177    
178            SimpleBean match = new SimpleBean(new Integer(2), "Simple 2", 200);
179    
180            Autocompleter component = newInstance(Autocompleter.class,
181                                                  new Object[] {
182                                                    "name", "fred", "model", model,
183                                                    "directService", engine,
184                                                    "script", script,
185                                                    "validatableFieldSupport", vfs,
186                                                    "value", match,
187                                                    "dataSqueezer", ds, "local", local
188                                                  });
189    
190            expect(cycle.renderStackPush(component)).andReturn(component);
191    
192            expect(form.getName()).andReturn("testform").anyTimes();
193    
194            form.setFormFieldUpdating(true);
195    
196            IMarkupWriter writer = newBufferWriter();
197    
198            DirectServiceParameter dsp =
199              new DirectServiceParameter(component);
200    
201            trainGetForm(cycle, form);
202            trainWasPrerendered(form, writer, component, false);
203    
204            trainGetDelegate(form, delegate);
205    
206            delegate.setFormComponent(component);
207    
208            trainGetElementId(form, component, "fred");
209            trainIsRewinding(form, false);
210            expect(cycle.isRewinding()).andReturn(false).anyTimes();
211    
212            delegate.setFormComponent(component);
213    
214            expect(cycle.getResponseBuilder()).andReturn(resp).anyTimes();
215            expect(resp.isDynamic()).andReturn(false).anyTimes();
216    
217            vfs.renderContributions(component, writer, cycle);
218            if (!local.booleanValue())
219            {
220                trainGetLinkCheckIgnoreParameter(engine, cycle, true, dsp, link);
221                trainGetURL(link, "urlstring");
222            }
223            else
224            {
225                expect(ds.squeeze(1)).andReturn("1p");
226                expect(ds.squeeze(2)).andReturn("2p");
227                expect(ds.squeeze(3)).andReturn("3p");
228            }
229            // for the default value
230            expect(ds.squeeze(2)).andReturn("2p");
231    
232            PageRenderSupport prs = newPageRenderSupport();
233            trainGetPageRenderSupport(cycle, prs);
234    
235            script.execute(eq(component), eq(cycle), eq(prs), isA(Map.class));
236    
237            expect(cycle.renderStackPop()).andReturn(component);
238    
239            replay();
240    
241            component.render(writer, cycle);
242    
243            verify();
244    
245            assertBuffer(outcome);
246        }
247    
248        public void test_Render_JSON()
249        {
250            IAutocompleteModel model = createModel();
251            IRequestCycle cycle = newMock(IRequestCycle.class);
252            DataSqueezer ds = newMock(DataSqueezer.class);
253            checkOrder(ds, false);
254    
255            IJSONWriter writer = newBufferJSONWriter();
256    
257            Autocompleter component = newInstance(Autocompleter.class, new Object[]
258              { "name", "fred", "model", model,
259                "filter", "l", "dataSqueezer", ds });
260    
261            expect(ds.squeeze(1)).andReturn("1");
262            expect(ds.squeeze(2)).andReturn("2");
263            expect(ds.squeeze(3)).andReturn("3");
264    
265            replay();
266    
267            component.renderComponent(writer, cycle);
268    
269            verify();
270    
271            JSONObject json = writer.object();
272    
273            assertEquals(json.length(), 3);
274            assertEquals(json.get("1"), "Simple 1");
275            assertEquals(json.get("2"), "Simple 2");
276            assertEquals(json.get("3"), "Simple 3");
277        }
278    
279        public void test_Is_Required()
280        {
281            ValidatableFieldSupport support = newMock(ValidatableFieldSupport.class);
282    
283            Autocompleter field = newInstance(Autocompleter.class,
284                                              new Object[] { "validatableFieldSupport", support, });
285    
286            expect(support.isRequired(field)).andReturn(true);
287    
288            replay();
289    
290            assert field.isRequired();
291    
292            verify();
293        }
294    }