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.binding;
016    
017    import org.apache.hivemind.ApplicationRuntimeException;
018    import org.apache.hivemind.Location;
019    import org.apache.tapestry.*;
020    import org.apache.tapestry.coerce.ValueConverter;
021    import org.apache.tapestry.listener.ListenerMap;
022    import static org.easymock.EasyMock.expect;
023    import static org.easymock.EasyMock.expectLastCall;
024    import org.testng.annotations.Test;
025    
026    /**
027     * Test for {@link org.apache.tapestry.binding.ListenerMethodBinding}.
028     * 
029     * @author Howard M. Lewis Ship
030     * @since 4.0
031     */
032    @Test
033    public class TestListenerMethodBinding extends BindingTestCase
034    {
035        public void test_Invoke_Listener()
036        {
037            IComponent component = newComponent();
038            ListenerMap map = newListenerMap();
039            IActionListener listener = newListener();
040            Location l = newLocation();
041            IComponent sourceComponent = newComponent();
042            IRequestCycle cycle = newCycle();
043            ValueConverter vc = newValueConverter();
044    
045            trainGetListener(component, map, listener);
046    
047            listener.actionTriggered(sourceComponent, cycle);
048    
049            replay();
050    
051            ListenerMethodBinding b = new ListenerMethodBinding("param", vc, l, component, "foo");
052    
053            assertSame(b, b.getObject());
054            assertSame(component, b.getComponent());
055    
056            b.actionTriggered(sourceComponent, cycle);
057    
058            verify();
059        }
060    
061        public void test_To_String()
062        {
063            IComponent component = newComponent();
064            Location l = newLocation();
065            ValueConverter vc = newValueConverter();
066    
067            trainGetExtendedId(component, "Fred/barney");
068            
069            replay();
070            
071            ListenerMethodBinding b = new ListenerMethodBinding("param", vc, l, component, "foo");
072    
073            String toString = b.toString();
074            String description = toString.substring(toString.indexOf('[') + 1, toString.length() - 1);
075            
076            assertTrue(description.indexOf("param, component=Fred/barney, methodName=foo, location=") > -1);
077            
078            verify();
079        }
080    
081        public void test_Invoke_And_Page_Redirect()
082        {
083            IComponent component = newComponent();
084            ListenerMap map = newListenerMap();
085            IActionListener listener = newListener();
086            Location l = newLocation();
087            ValueConverter vc = newValueConverter();
088            IComponent sourceComponent = newComponent();
089            IRequestCycle cycle = newCycle();
090    
091            trainGetListener(component, map, listener);
092    
093            listener.actionTriggered(sourceComponent, cycle);
094            
095            Throwable t = new PageRedirectException("TargetPage");
096            expectLastCall().andThrow(t);
097            
098            replay();
099    
100            ListenerMethodBinding b = new ListenerMethodBinding("param", vc, l, component, "foo");
101    
102            try
103            {
104                b.actionTriggered(sourceComponent, cycle);
105                unreachable();
106            }
107            catch (PageRedirectException ex)
108            {
109                assertSame(t, ex);
110            }
111    
112            verify();
113        }
114    
115        public void test_Invoke_And_Redirect()
116        {
117            IComponent component = newComponent();
118            ListenerMap map = newListenerMap();
119            IActionListener listener = newListener();
120            Location l = newLocation();
121            ValueConverter vc = newValueConverter();
122            IComponent sourceComponent = newComponent();
123            IRequestCycle cycle = newCycle();
124    
125            trainGetListener(component, map, listener);
126    
127            listener.actionTriggered(sourceComponent, cycle);
128            
129            Throwable t = new RedirectException("http://foo.bar");
130            expectLastCall().andThrow(t);
131    
132            replay();
133    
134            ListenerMethodBinding b = new ListenerMethodBinding("param", vc, l, component, "foo");
135    
136            try
137            {
138                b.actionTriggered(sourceComponent, cycle);
139                unreachable();
140            }
141            catch (RedirectException ex)
142            {
143                assertSame(t, ex);
144            }
145    
146            verify();
147        }
148    
149        @Test(expectedExceptions = RenderRewoundException.class)
150        public void test_Invoke_Render_Rewound()
151        {        
152            IComponent component = newMock(IComponent.class);
153            ListenerMap map = newListenerMap();
154            IActionListener listener = newMock(IActionListener.class);
155            ValueConverter vc = newMock(ValueConverter.class);
156            IComponent sourceComponent = newMock(IComponent.class);
157            Location l = newMock(Location.class);
158            IRequestCycle cycle = newMock(IRequestCycle.class);
159    
160            trainGetListener(component, map, listener);
161    
162            listener.actionTriggered(sourceComponent, cycle);
163    
164            ApplicationRuntimeException t = new RenderRewoundException(null);
165            expectLastCall().andThrow(t);
166    
167            replay();
168    
169            ListenerMethodBinding b = new ListenerMethodBinding("param", vc, l, component, "foo");
170    
171            b.actionTriggered(sourceComponent, cycle);
172    
173            verify();
174        }
175    
176        public void test_Invoke_Listener_Failure()
177        {
178            IComponent component = newComponent();
179            ListenerMap map = newListenerMap();
180            IActionListener listener = newListener();
181            Location l = newLocation();
182            ValueConverter vc = newValueConverter();
183            IComponent sourceComponent = newComponent();
184            IRequestCycle cycle = newCycle();
185    
186            trainGetListener(component, map, listener);
187    
188            listener.actionTriggered(sourceComponent, cycle);
189    
190            Throwable t = new RuntimeException("Failure.");
191            expectLastCall().andThrow(t);
192    
193            trainGetExtendedId(component, "Fred/barney");
194    
195            replay();
196    
197            ListenerMethodBinding b = new ListenerMethodBinding("param", vc, l, component, "foo");
198    
199            try
200            {
201                b.actionTriggered(sourceComponent, cycle);
202                unreachable();
203            }
204            catch (BindingException ex)
205            {
206                assertEquals(
207                        "Exception invoking listener method foo of component Fred/barney: Failure.",
208                        ex.getMessage());
209                assertSame(component, ex.getComponent());
210                assertSame(l, ex.getLocation());
211                assertSame(b, ex.getBinding());
212            }
213    
214            verify();
215        }
216    
217        public void test_Get_Method_Name()
218        {
219            IComponent component = newComponent();
220            Location l = newLocation();
221            ValueConverter vc = newValueConverter();
222            
223            replay();
224    
225            ListenerMethodBinding b = new ListenerMethodBinding("param", vc, l, component, "foo");
226    
227            assertEquals(b.getMethodName(), "foo");
228    
229            verify();
230        }
231    
232        private void trainGetListener(IComponent component, ListenerMap lm, IActionListener listener)
233        {
234            trainGetListeners(component, lm);
235            trainGetListener(lm, "foo", listener);
236        }
237    
238        private void trainGetListener(ListenerMap map, String methodName, IActionListener listener)
239        {
240            expect(map.getListener(methodName)).andReturn(listener);
241        }
242    
243        private void trainGetListeners(IComponent component, ListenerMap lm)
244        {
245            expect(component.getListeners()).andReturn(lm);
246        }
247    
248        private ListenerMap newListenerMap()
249        {
250            return newMock(ListenerMap.class);
251        }
252    
253        private IActionListener newListener()
254        {
255            return newMock(IActionListener.class);
256        }
257    }