View Javadoc

1   /*
2    * $Id: TestActionConfig.java 421117 2006-07-12 04:35:47Z wsmoak $
3    *
4    * Copyright 1999-2004 The Apache Software Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.struts.config;
19  
20  import junit.framework.Test;
21  import junit.framework.TestCase;
22  import junit.framework.TestSuite;
23  
24  import java.lang.reflect.InvocationTargetException;
25  
26  /***
27   * Unit tests for the <code>org.apache.struts.config.ActionConfig</code>
28   * class.  Currently only contains code to test the methods that support
29   * configuration inheritance.
30   *
31   * @version $Rev: 421117 $ $Date: 2005-05-25 19:35:00 -0400 (Wed, 25 May 2005)
32   *          $
33   */
34  public class TestActionConfig extends TestCase {
35      // ----------------------------------------------------- Instance Variables
36  
37      /***
38       * The ModuleConfig we'll use.
39       */
40      protected ModuleConfig config = null;
41  
42      /***
43       * The common base we'll use.
44       */
45      protected ActionConfig baseConfig = null;
46  
47      // ----------------------------------------------------------- Constructors
48  
49      /***
50       * Construct a new instance of this test case.
51       *
52       * @param name Name of the test case
53       */
54      public TestActionConfig(String name) {
55          super(name);
56      }
57  
58      // --------------------------------------------------------- Public Methods
59  
60      /***
61       * Set up instance variables required by this test case.
62       */
63      public void setUp() {
64          ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();
65  
66          config = factoryObject.createModuleConfig("");
67  
68          // setup the base form
69          baseConfig = new ActionConfig();
70          baseConfig.setPath("/base");
71          baseConfig.setType("org.apache.struts.actions.DummyAction");
72  
73          // set up success and failure forward
74          ForwardConfig forward =
75              new ForwardConfig("success", "/success.jsp", false);
76  
77          baseConfig.addForwardConfig(forward);
78  
79          forward = new ForwardConfig("failure", "/failure.jsp", false);
80          forward.setProperty("forwardCount", "10");
81          baseConfig.addForwardConfig(forward);
82  
83          // setup an exception handler
84          ExceptionConfig exceptionConfig = new ExceptionConfig();
85  
86          exceptionConfig.setType("java.sql.SQLException");
87          exceptionConfig.setKey("msg.exception.sql");
88          exceptionConfig.setProperty("exceptionCount", "10");
89          baseConfig.addExceptionConfig(exceptionConfig);
90  
91          // set some arbitrary properties
92          baseConfig.setProperty("label", "base");
93          baseConfig.setProperty("version", "1a");
94  
95          // register it to our config
96          config.addActionConfig(baseConfig);
97      }
98  
99      /***
100      * Return the tests included in this test suite.
101      */
102     public static Test suite() {
103         return (new TestSuite(TestActionConfig.class));
104     }
105 
106     /***
107      * Tear down instance variables required by this test case.
108      */
109     public void tearDown() {
110         config = null;
111         baseConfig = null;
112     }
113 
114     // ------------------------------------------------------- Individual Tests
115 
116     /***
117      * Basic check that shouldn't detect circular inheritance.
118      */
119     public void testCheckCircularInheritance() {
120         ActionConfig child = new ActionConfig();
121 
122         child.setPath("/child");
123         child.setExtends("/base");
124 
125         ActionConfig grandChild = new ActionConfig();
126 
127         grandChild.setPath("/grandChild");
128         grandChild.setExtends("/child");
129 
130         config.addActionConfig(child);
131         config.addActionConfig(grandChild);
132 
133         assertTrue("Circular inheritance shouldn't have been detected",
134             !grandChild.checkCircularInheritance(config));
135     }
136 
137     /***
138      * Basic check that should detect circular inheritance.
139      */
140     public void testCheckCircularInheritanceError() {
141         ActionConfig child = new ActionConfig();
142 
143         child.setPath("/child");
144         child.setExtends("/base");
145 
146         ActionConfig grandChild = new ActionConfig();
147 
148         grandChild.setPath("/grandChild");
149         grandChild.setExtends("/child");
150 
151         // establish the circular relationship with base
152         baseConfig.setExtends("/grandChild");
153 
154         config.addActionConfig(child);
155         config.addActionConfig(grandChild);
156 
157         assertTrue("Circular inheritance should've been detected",
158             grandChild.checkCircularInheritance(config));
159     }
160 
161     /***
162      * Test that processExtends() makes sure that a base action's own
163      * extension has been processed.
164      */
165     public void testProcessExtendsActionExtends()
166         throws Exception {
167         CustomActionConfig first = new CustomActionConfig();
168 
169         first.setPath("/first");
170 
171         CustomActionConfig second = new CustomActionConfig();
172 
173         second.setPath("/second");
174         second.setExtends("/first");
175 
176         config.addActionConfig(first);
177         config.addActionConfig(second);
178 
179         // set baseConfig to extend second
180         baseConfig.setExtends("/second");
181 
182         baseConfig.processExtends(config);
183 
184         assertTrue("The first action's processExtends() wasn't called",
185             first.processExtendsCalled);
186         assertTrue("The second action's processExtends() wasn't called",
187             second.processExtendsCalled);
188     }
189 
190     /***
191      * Make sure that correct exception is thrown if a base action can't be
192      * found.
193      */
194     public void testProcessExtendsMissingAction()
195         throws Exception {
196         baseConfig.setExtends("/someMissingAction");
197 
198         try {
199             baseConfig.processExtends(config);
200             fail(
201                 "An exception should be thrown if a super form can't be found.");
202         } catch (NullPointerException e) {
203             // succeed
204         } catch (InstantiationException e) {
205             fail("Unrecognized exception thrown.");
206         }
207     }
208 
209     /***
210      * Test a typical form bean configuration extension where various forwards
211      * and exception handlers should be inherited from a base form. This
212      * method checks all the subelements.
213      */
214     public void testInheritFrom()
215         throws Exception {
216         // create a basic subform
217         ActionConfig subConfig = new ActionConfig();
218         String subConfigPath = "subConfig";
219 
220         subConfig.setPath(subConfigPath);
221         subConfig.setExtends("/base");
222 
223         // override success
224         ForwardConfig forward = new ForwardConfig();
225 
226         forward.setName("success");
227         forward.setPath("/newSuccess.jsp");
228         forward.setRedirect(true);
229         subConfig.addForwardConfig(forward);
230 
231         // add an exception handler
232         ExceptionConfig handler = new ExceptionConfig();
233 
234         handler.setType("java.lang.NullPointerException");
235         handler.setKey("msg.exception.npe");
236         subConfig.addExceptionConfig(handler);
237 
238         // override arbitrary "label" property
239         subConfig.setProperty("label", "sub");
240 
241         config.addActionConfig(subConfig);
242 
243         subConfig.inheritFrom(baseConfig);
244 
245         // check that our subConfig is still the one in the config
246         assertSame("subConfig no longer in ModuleConfig", subConfig,
247             config.findActionConfig("subConfig"));
248 
249         // check our configured sub config
250         assertNotNull("Action type was not inherited", subConfig.getType());
251         assertEquals("Wrong config path", subConfigPath, subConfig.getPath());
252         assertEquals("Wrong config type", baseConfig.getType(),
253             subConfig.getType());
254 
255         // check our forwards
256         ForwardConfig[] forwards = subConfig.findForwardConfigs();
257 
258         assertEquals("Wrong forwards count", 2, forwards.length);
259 
260         forward = subConfig.findForwardConfig("success");
261         assertNotNull("'success' forward was not found", forward);
262         assertEquals("Wrong path for success", "/newSuccess.jsp",
263             forward.getPath());
264 
265         forward = subConfig.findForwardConfig("failure");
266 
267         ForwardConfig origForward = baseConfig.findForwardConfig("failure");
268 
269         assertNotNull("'failure' forward was not inherited", forward);
270         assertEquals("Wrong type for 'failure'", origForward.getPath(),
271             forward.getPath());
272         assertEquals("Arbitrary property not copied",
273             origForward.getProperty("forwardCount"),
274             forward.getProperty("forwardCount"));
275 
276         // check our exceptions
277         ExceptionConfig[] handlers = subConfig.findExceptionConfigs();
278 
279         assertEquals("Wrong exception config count", 2, handlers.length);
280 
281         handler = subConfig.findExceptionConfig("java.sql.SQLException");
282 
283         ExceptionConfig origHandler =
284             baseConfig.findExceptionConfig("java.sql.SQLException");
285 
286         assertNotNull("'SQLException' handler was not found", handler);
287         assertEquals("Wrong key for 'SQLException'", origHandler.getKey(),
288             handler.getKey());
289         assertEquals("Arbitrary property not copied",
290             origHandler.getProperty("exceptionCount"),
291             handler.getProperty("exceptionCount"));
292 
293         handler =
294             subConfig.findExceptionConfig("java.lang.NullPointerException");
295         assertNotNull("'NullPointerException' handler disappeared", handler);
296 
297         // check the arbitrary properties
298         String version = subConfig.getProperty("version");
299 
300         assertEquals("Arbitrary property 'version' wasn't inherited", "1a",
301             version);
302 
303         String label = subConfig.getProperty("label");
304 
305         assertEquals("Arbitrary property 'label' shouldn't have changed",
306             "sub", label);
307     }
308 
309     /***
310      * Used to detect that ActionConfig is making the right calls.
311      */
312     public static class CustomActionConfig extends ActionConfig {
313         boolean processExtendsCalled = false;
314 
315         public void processExtends(ModuleConfig moduleConfig)
316             throws ClassNotFoundException, IllegalAccessException,
317                 InstantiationException, InvocationTargetException {
318             super.processExtends(moduleConfig);
319             processExtendsCalled = true;
320         }
321     }
322 }