001package org.apache.turbine.modules;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import static org.junit.Assert.assertEquals;
023import static org.junit.Assert.assertFalse;
024import static org.junit.Assert.assertTrue;
025import static org.junit.Assert.fail;
026
027import java.util.HashMap;
028import java.util.Map;
029import java.util.Vector;
030
031import javax.servlet.http.HttpServletResponse;
032
033import org.apache.turbine.Turbine;
034import org.apache.turbine.modules.actions.VelocityActionDoesNothing;
035import org.apache.turbine.om.security.User;
036import org.apache.turbine.pipeline.DefaultPipelineData;
037import org.apache.turbine.pipeline.PipelineData;
038import org.apache.turbine.test.BaseTestCase;
039import org.apache.turbine.test.EnhancedMockHttpServletRequest;
040import org.apache.turbine.test.EnhancedMockHttpSession;
041import org.apache.turbine.util.RunData;
042import org.apache.turbine.util.TurbineConfig;
043import org.junit.AfterClass;
044import org.junit.Before;
045import org.junit.BeforeClass;
046import org.junit.Test;
047
048import com.mockobjects.servlet.MockHttpServletResponse;
049import com.mockobjects.servlet.MockServletConfig;
050
051/**
052 * This test case is to verify whether exceptions in Velocity actions are
053 * properly bubbled up when action.event.bubbleexception=true. Or, if
054 * action.event.bubbleexception=false, then the exceptions should be logged and
055 * sunk.
056 *
057 * Changes 2014/Jun/26 (gk): removed Constructor with String parameter as no Test VelocityErrorScreenTest is found and JUnit does not allow it.
058 *
059 * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
060 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
061 */
062public class ActionLoaderTest extends BaseTestCase
063{
064    private static TurbineConfig tc = null;
065    private MockServletConfig config = null;
066    private EnhancedMockHttpServletRequest request = null;
067    private EnhancedMockHttpSession session = null;
068    private HttpServletResponse response = null;
069
070    /*
071     * @see TestCase#setUp()
072     */
073
074    @BeforeClass
075    public static void init() {
076        tc = new TurbineConfig(".", "/conf/test/CompleteTurbineResources.properties");
077        tc.initialize();
078    }
079
080    @Before
081    public void setUpBefore() throws Exception
082    {
083        config = new MockServletConfig();
084        config.setupNoParameters();
085        request = new EnhancedMockHttpServletRequest();
086        request.setupServerName("bob");
087        request.setupGetProtocol("http");
088        request.setupScheme("scheme");
089        request.setupPathInfo("damn");
090        request.setupGetServletPath("damn2");
091        request.setupGetContextPath("wow");
092        request.setupGetContentType("html/text");
093        request.setupAddHeader("Content-type", "html/text");
094        request.setupAddHeader("Accept-Language", "en-US");
095        Vector<String> v = new Vector<String>();
096        request.setupGetParameterNames(v.elements());
097        session = new EnhancedMockHttpSession();
098        response = new MockHttpServletResponse();
099        session.setupGetAttribute(User.SESSION_KEY, null);
100        request.setSession(session);
101    }
102
103    /*
104     * @see TestCase#tearDown()
105     */
106    @AfterClass
107    public static void tearDown() throws Exception
108    {
109        if (tc != null)
110        {
111            tc.dispose();
112        }
113    }
114
115    /**
116     * This unit test verifies that if your standard doPerform is called, and it
117     * throws an Exception, the exception is bubbled up out of the
118     * ActionLoader...
119     *
120     * @throws Exception
121     *             If something goes wrong with the unit test
122     */
123    @Test
124    public void testDoPerformBubblesException() throws Exception
125    {
126        System.out.println("tcturbine:"+ tc.getTurbine());
127
128    }
129
130    /**
131     * This unit test verifies that if an Action Event doEventSubmit_ is called,
132     * and it throws an Exception, the exception is bubbled up out of the
133     * ActionLoader...
134     *
135     * @throws Exception
136     *             If something goes wrong with the unit test
137     */
138    @Test
139    public void testActionEventBubblesException() throws Exception
140    {
141        // can't seem to figure out how to setup the Mock Request with the right
142        // parameters...
143        request.setupAddParameter("eventSubmit_doCauseexception", "foo");
144        RunData data = getRunData(request, response, config);
145        PipelineData pipelineData = new DefaultPipelineData();
146        Map<Class<?>, Object> runDataMap = new HashMap<Class<?>, Object>();
147        runDataMap.put(RunData.class, data);
148        pipelineData.put(RunData.class, runDataMap);
149        data.setAction("VelocityActionThrowsException");
150        data.getParameters().add("eventSubmit_doCauseexception", "foo");
151        assertTrue(data.getParameters().containsKey("eventSubmit_doCauseexception"));
152        try
153        {
154            ActionLoader.getInstance().exec(data, data.getAction());
155            fail("Should have bubbled out an exception thrown by the action.");
156        }
157        catch (Exception e)
158        {
159            // good
160        }
161        try
162        {
163            ActionLoader.getInstance().exec(pipelineData, data.getAction());
164            fail("Should have bubbled out an exception thrown by the action.");
165        }
166        catch (Exception e)
167        {
168            // good
169        }
170    }
171
172    /**
173     * This unit test verifies that if your standard doPerform is called, and it
174     * throws an Exception, if the action.event.bubbleexception property is set
175     * to false then the exception is NOT bubbled up
176     *
177     * @throws Exception
178     *             If something goes wrong with the unit test
179     */
180    @Test
181    public void testDoPerformDoesntBubbleException() throws Exception
182    {
183        Turbine.getConfiguration().setProperty("action.event.bubbleexception", Boolean.FALSE);
184        assertFalse(Turbine.getConfiguration().getBoolean("action.event.bubbleexception"));
185        RunData data = getRunData(request, response, config);
186        PipelineData pipelineData = new DefaultPipelineData();
187        Map<Class<?>, Object> runDataMap = new HashMap<Class<?>, Object>();
188        runDataMap.put(RunData.class, data);
189        pipelineData.put(RunData.class, runDataMap);
190        data.setAction("VelocityActionThrowsException");
191        try
192        {
193            ActionLoader.getInstance().exec(data, data.getAction());
194        }
195        catch (Exception e)
196        {
197            fail("Should NOT have thrown an exception:" + e.getMessage());
198        }
199        try
200        {
201            ActionLoader.getInstance().exec(pipelineData, data.getAction());
202        }
203        catch (Exception e)
204        {
205            fail("Should NOT have thrown an exception:" + e.getMessage());
206        }
207    }
208
209    /**
210     * This unit test verifies that if an Action Event doEventSubmit_ is called,
211     * and it throws an Exception, if the action.event.bubbleexception property
212     * is set to false then the exception is NOT bubbled up
213     *
214     * @throws Exception
215     *             If something goes wrong with the unit test
216     */
217    @Test
218    public void testActionEventDoesntBubbleException() throws Exception
219    {
220        // can't seem to figure out how to setup the Mock Request with the right
221        // parameters...
222        Turbine.getConfiguration().setProperty("action.event.bubbleexception", Boolean.FALSE);
223        request.setupAddParameter("eventSubmit_doCauseexception", "foo");
224        RunData data = getRunData(request, response, config);
225        PipelineData pipelineData = new DefaultPipelineData();
226        Map<Class<?>, Object> runDataMap = new HashMap<Class<?>, Object>();
227        runDataMap.put(RunData.class, data);
228        pipelineData.put(RunData.class, runDataMap);
229        data.setAction("VelocityActionThrowsException");
230        data.getParameters().add("eventSubmit_doCauseexception", "foo");
231        assertTrue(data.getParameters().containsKey("eventSubmit_doCauseexception"));
232
233        try
234        {
235            ActionLoader.getInstance().exec(data, data.getAction());
236        }
237        catch (Exception e)
238        {
239            fail("Should NOT have thrown an exception:" + e.getMessage());
240        }
241        try
242        {
243            ActionLoader.getInstance().exec(pipelineData, data.getAction());
244        }
245        catch (Exception e)
246        {
247            fail("Should NOT have thrown an exception:" + e.getMessage());
248        }
249    }
250
251    /**
252     * This unit test verifies that if an Action Event doEventSubmit_ is called,
253     * a properly annotated method is being called
254     *
255     * @throws Exception
256     *             If something goes wrong with the unit test
257     */
258    @Test
259    public void testActionEventAnnotation() throws Exception
260    {
261        // can't seem to figure out how to setup the Mock Request with the right
262        // parameters...
263        request.setupAddParameter("eventSubmit_annotatedEvent", "foo");
264        RunData data = getRunData(request, response, config);
265        PipelineData pipelineData = data;
266        data.setAction("VelocityActionDoesNothing");
267        data.getParameters().add("eventSubmit_annotatedEvent", "foo");
268
269        int numberOfCalls = VelocityActionDoesNothing.numberOfCalls;
270        int pipelineDataCalls = VelocityActionDoesNothing.pipelineDataCalls;
271        int actionEventCalls = VelocityActionDoesNothing.actionEventCalls;
272        try
273        {
274            ActionLoader.getInstance().exec(pipelineData, data.getAction());
275        }
276        catch (Exception e)
277        {
278            e.printStackTrace();
279            fail("Should not have thrown an exception.");
280        }
281        assertEquals(numberOfCalls + 1, VelocityActionDoesNothing.numberOfCalls);
282        assertEquals(pipelineDataCalls, VelocityActionDoesNothing.pipelineDataCalls);
283        assertEquals(actionEventCalls + 1, VelocityActionDoesNothing.actionEventCalls);
284    }
285
286    @Test
287    public void testNonexistentActionCausesError() throws Exception
288    {
289        RunData data = getRunData(request, response, config);
290        PipelineData pipelineData = new DefaultPipelineData();
291        Map<Class<?>, Object> runDataMap = new HashMap<Class<?>, Object>();
292        runDataMap.put(RunData.class, data);
293        pipelineData.put(RunData.class, runDataMap);
294        data.setAction("ImaginaryAction");
295        try
296        {
297            ActionLoader.getInstance().exec(data, "boo");
298            fail("Should have thrown an exception");
299        }
300        catch (Exception e)
301        {
302            // good
303        }
304        try
305        {
306            ActionLoader.getInstance().exec(pipelineData, "boo");
307            fail("Should have thrown an exception");
308        }
309        catch (Exception e)
310        {
311            // good
312        }
313    }
314
315    @Test
316    public void testDoPerformWithPipelineData() throws Exception
317    {
318        RunData data = getRunData(request, response, config);
319        PipelineData pipelineData = data;
320        data.setAction("VelocityActionDoesNothing");
321        int numberOfCalls = VelocityActionDoesNothing.numberOfCalls;
322        int pipelineDataCalls = VelocityActionDoesNothing.pipelineDataCalls;
323        try
324        {
325            ActionLoader.getInstance().exec(pipelineData, data.getAction());
326        }
327        catch (Exception e)
328        {
329            e.printStackTrace();
330            fail("Should not have thrown an exception.");
331        }
332        assertEquals(numberOfCalls + 1, VelocityActionDoesNothing.numberOfCalls);
333        assertEquals(pipelineDataCalls + 1, VelocityActionDoesNothing.pipelineDataCalls);
334    }
335
336    @Test
337    public void testDoPerformWithServiceInjection() throws Exception
338    {
339        RunData data = getRunData(request, response, config);
340        PipelineData pipelineData = data;
341        data.setAction("VelocityActionWithServiceInjection");
342
343        try
344        {
345            ActionLoader.getInstance().exec(pipelineData, data.getAction());
346        }
347        catch (Exception e)
348        {
349            e.printStackTrace();
350            fail("Should not have thrown an exception.");
351        }
352    }
353}