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;
026import static org.mockito.Mockito.mock;
027import static org.mockito.Mockito.when;
028
029import java.util.HashMap;
030import java.util.Map;
031
032import javax.servlet.ServletConfig;
033import javax.servlet.http.HttpServletRequest;
034import javax.servlet.http.HttpServletResponse;
035
036import org.apache.turbine.Turbine;
037import org.apache.turbine.modules.actions.VelocityActionDoesNothing;
038import org.apache.turbine.pipeline.DefaultPipelineData;
039import org.apache.turbine.pipeline.PipelineData;
040import org.apache.turbine.test.BaseTestCase;
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
048/**
049 * This test case is to verify whether exceptions in Velocity actions are
050 * properly bubbled up when action.event.bubbleexception=true. Or, if
051 * action.event.bubbleexception=false, then the exceptions should be logged and
052 * sunk.
053 *
054 * Changes 2014/Jun/26 (gk): removed Constructor with String parameter as no Test VelocityErrorScreenTest is found and JUnit does not allow it.
055 *
056 * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
057 * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a>
058 */
059public class ActionLoaderTest extends BaseTestCase
060{
061    private static TurbineConfig tc = null;
062    private ServletConfig config = null;
063    private HttpServletRequest request = null;
064    private HttpServletResponse response = null;
065
066    /*
067     * @see TestCase#setUp()
068     */
069
070    @BeforeClass
071    public static void init()
072    {
073        tc = new TurbineConfig(".", "/conf/test/CompleteTurbineResources.properties");
074        tc.initialize();
075    }
076
077    @Before
078    public void setUpBefore() throws Exception
079    {
080        config = mock(ServletConfig.class);
081        request = getMockRequest();
082        response = mock(HttpServletResponse.class);
083    }
084
085    /*
086     * @see TestCase#tearDown()
087     */
088    @AfterClass
089    public static void tearDown() throws Exception
090    {
091        if (tc != null)
092        {
093            tc.dispose();
094        }
095    }
096
097    /**
098     * This unit test verifies that if your standard doPerform is called, and it
099     * throws an Exception, the exception is bubbled up out of the
100     * ActionLoader...
101     *
102     * @throws Exception
103     *             If something goes wrong with the unit test
104     */
105    @Test
106    public void testDoPerformBubblesException() throws Exception
107    {
108        System.out.println("tcturbine:"+ tc.getTurbine());
109    }
110
111    /**
112     * This unit test verifies that if an Action Event doEventSubmit_ is called,
113     * and it throws an Exception, the exception is bubbled up out of the
114     * ActionLoader...
115     *
116     * @throws Exception
117     *             If something goes wrong with the unit test
118     */
119    @Test
120    public void testActionEventBubblesException() throws Exception
121    {
122        when(request.getParameterValues("eventSubmit_doCauseexception")).thenReturn(new String[] { "foo" });
123        RunData data = getRunData(request, response, config);
124        PipelineData pipelineData = new DefaultPipelineData();
125        Map<Class<?>, Object> runDataMap = new HashMap<Class<?>, Object>();
126        runDataMap.put(RunData.class, data);
127        pipelineData.put(RunData.class, runDataMap);
128        data.setAction("VelocityActionThrowsException");
129        data.getParameters().add("eventSubmit_doCauseexception", "foo");
130        assertTrue(data.getParameters().containsKey("eventSubmit_doCauseexception"));
131        try
132        {
133            ActionLoader.getInstance().exec(data, data.getAction());
134            fail("Should have bubbled out an exception thrown by the action.");
135        }
136        catch (Exception e)
137        {
138            // good
139        }
140        try
141        {
142            ActionLoader.getInstance().exec(pipelineData, data.getAction());
143            fail("Should have bubbled out an exception thrown by the action.");
144        }
145        catch (Exception e)
146        {
147            // good
148        }
149    }
150
151    /**
152     * This unit test verifies that if your standard doPerform is called, and it
153     * throws an Exception, if the action.event.bubbleexception property is set
154     * to false then the exception is NOT bubbled up
155     *
156     * @throws Exception
157     *             If something goes wrong with the unit test
158     */
159    @Test
160    public void testDoPerformDoesntBubbleException() throws Exception
161    {
162        Turbine.getConfiguration().setProperty("action.event.bubbleexception", Boolean.FALSE);
163        assertFalse(Turbine.getConfiguration().getBoolean("action.event.bubbleexception"));
164        RunData data = getRunData(request, response, config);
165        PipelineData pipelineData = new DefaultPipelineData();
166        Map<Class<?>, Object> runDataMap = new HashMap<Class<?>, Object>();
167        runDataMap.put(RunData.class, data);
168        pipelineData.put(RunData.class, runDataMap);
169        data.setAction("VelocityActionThrowsException");
170        try
171        {
172            ActionLoader.getInstance().exec(data, data.getAction());
173        }
174        catch (Exception e)
175        {
176            fail("Should NOT have thrown an exception:" + e.getMessage());
177        }
178        try
179        {
180            ActionLoader.getInstance().exec(pipelineData, data.getAction());
181        }
182        catch (Exception e)
183        {
184            fail("Should NOT have thrown an exception:" + e.getMessage());
185        }
186    }
187
188    /**
189     * This unit test verifies that if an Action Event doEventSubmit_ is called,
190     * and it throws an Exception, if the action.event.bubbleexception property
191     * is set to false then the exception is NOT bubbled up
192     *
193     * @throws Exception
194     *             If something goes wrong with the unit test
195     */
196    @Test
197    public void testActionEventDoesntBubbleException() throws Exception
198    {
199        // can't seem to figure out how to setup the Mock Request with the right
200        // parameters...
201        Turbine.getConfiguration().setProperty("action.event.bubbleexception", Boolean.FALSE);
202        when(request.getParameterValues("eventSubmit_doCauseexception")).thenReturn(new String[] { "foo" });
203        RunData data = getRunData(request, response, config);
204        PipelineData pipelineData = new DefaultPipelineData();
205        Map<Class<?>, Object> runDataMap = new HashMap<Class<?>, Object>();
206        runDataMap.put(RunData.class, data);
207        pipelineData.put(RunData.class, runDataMap);
208        data.setAction("VelocityActionThrowsException");
209        data.getParameters().add("eventSubmit_doCauseexception", "foo");
210        assertTrue(data.getParameters().containsKey("eventSubmit_doCauseexception"));
211
212        try
213        {
214            ActionLoader.getInstance().exec(data, data.getAction());
215        }
216        catch (Exception e)
217        {
218            fail("Should NOT have thrown an exception:" + e.getMessage());
219        }
220        try
221        {
222            ActionLoader.getInstance().exec(pipelineData, data.getAction());
223        }
224        catch (Exception e)
225        {
226            fail("Should NOT have thrown an exception:" + e.getMessage());
227        }
228    }
229
230    /**
231     * This unit test verifies that if an Action Event doEventSubmit_ is called,
232     * a properly annotated method is being called
233     *
234     * @throws Exception
235     *             If something goes wrong with the unit test
236     */
237    @Test
238    public void testActionEventAnnotation() throws Exception
239    {
240        when(request.getParameterValues("eventSubmit_annotatedEvent")).thenReturn(new String[] { "foo" });
241        RunData data = getRunData(request, response, config);
242        PipelineData pipelineData = data;
243        data.setAction("VelocityActionDoesNothing");
244        data.getParameters().add("eventSubmit_annotatedEvent", "foo");
245
246        int numberOfCalls = VelocityActionDoesNothing.numberOfCalls;
247        int pipelineDataCalls = VelocityActionDoesNothing.pipelineDataCalls;
248        int actionEventCalls = VelocityActionDoesNothing.actionEventCalls;
249        try
250        {
251            ActionLoader.getInstance().exec(pipelineData, data.getAction());
252        }
253        catch (Exception e)
254        {
255            e.printStackTrace();
256            fail("Should not have thrown an exception.");
257        }
258        assertEquals(numberOfCalls + 1, VelocityActionDoesNothing.numberOfCalls);
259        assertEquals(pipelineDataCalls, VelocityActionDoesNothing.pipelineDataCalls);
260        assertEquals(actionEventCalls + 1, VelocityActionDoesNothing.actionEventCalls);
261    }
262
263    @Test
264    public void testNonexistentActionCausesError() throws Exception
265    {
266        RunData data = getRunData(request, response, config);
267        PipelineData pipelineData = new DefaultPipelineData();
268        Map<Class<?>, Object> runDataMap = new HashMap<Class<?>, Object>();
269        runDataMap.put(RunData.class, data);
270        pipelineData.put(RunData.class, runDataMap);
271        data.setAction("ImaginaryAction");
272        try
273        {
274            ActionLoader.getInstance().exec(data, "boo");
275            fail("Should have thrown an exception");
276        }
277        catch (Exception e)
278        {
279            // good
280        }
281        try
282        {
283            ActionLoader.getInstance().exec(pipelineData, "boo");
284            fail("Should have thrown an exception");
285        }
286        catch (Exception e)
287        {
288            // good
289        }
290    }
291
292    @Test
293    public void testDoPerformWithPipelineData() throws Exception
294    {
295        RunData data = getRunData(request, response, config);
296        PipelineData pipelineData = data;
297        data.setAction("VelocityActionDoesNothing");
298        int numberOfCalls = VelocityActionDoesNothing.numberOfCalls;
299        int pipelineDataCalls = VelocityActionDoesNothing.pipelineDataCalls;
300        try
301        {
302            ActionLoader.getInstance().exec(pipelineData, data.getAction());
303        }
304        catch (Exception e)
305        {
306            e.printStackTrace();
307            fail("Should not have thrown an exception.");
308        }
309        assertEquals(numberOfCalls + 1, VelocityActionDoesNothing.numberOfCalls);
310        assertEquals(pipelineDataCalls + 1, VelocityActionDoesNothing.pipelineDataCalls);
311    }
312
313    @Test
314    public void testDoPerformWithServiceInjection() throws Exception
315    {
316        RunData data = getRunData(request, response, config);
317        PipelineData pipelineData = data;
318        data.setAction("VelocityActionWithServiceInjection");
319
320        try
321        {
322            ActionLoader.getInstance().exec(pipelineData, data.getAction());
323        }
324        catch (Exception e)
325        {
326            e.printStackTrace();
327            fail("Should not have thrown an exception.");
328        }
329    }
330}