1   /* Copyright 2004 Acegi Technology Pty Limited
2    *
3    * Licensed under the Apache License, Version 2.0 (the "License");
4    * you may not use this file except in compliance with the License.
5    * You may obtain a copy of the License at
6    *
7    *     http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  package org.acegisecurity.intercept.method;
17  
18  import junit.framework.TestCase;
19  
20  import org.acegisecurity.ConfigAttributeDefinition;
21  import org.acegisecurity.MockJoinPoint;
22  import org.acegisecurity.SecurityConfig;
23  import org.acegisecurity.TargetObject;
24  
25  import org.aopalliance.intercept.MethodInvocation;
26  
27  import java.lang.reflect.AccessibleObject;
28  import java.lang.reflect.Method;
29  
30  import java.util.Iterator;
31  
32  
33  /***
34   * Tests {@link MethodDefinitionSourceEditor} and its asociated {@link
35   * MethodDefinitionMap}.
36   *
37   * @author Ben Alex
38   * @version $Id: MethodDefinitionSourceEditorTests.java,v 1.5 2005/11/17 00:55:50 benalex Exp $
39   */
40  public class MethodDefinitionSourceEditorTests extends TestCase {
41      //~ Constructors ===========================================================
42  
43      public MethodDefinitionSourceEditorTests() {
44          super();
45      }
46  
47      public MethodDefinitionSourceEditorTests(String arg0) {
48          super(arg0);
49      }
50  
51      //~ Methods ================================================================
52  
53      public final void setUp() throws Exception {
54          super.setUp();
55      }
56  
57      public static void main(String[] args) {
58          junit.textui.TestRunner.run(MethodDefinitionSourceEditorTests.class);
59      }
60  
61      public void testAspectJJointPointLookup() throws Exception {
62          MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
63          editor.setAsText(
64              "org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY");
65  
66          MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
67  
68          Class clazz = TargetObject.class;
69          Method method = clazz.getMethod("countLength",
70                  new Class[] {String.class});
71          MockJoinPoint joinPoint = new MockJoinPoint(new TargetObject(), method);
72  
73          ConfigAttributeDefinition returnedCountLength = map.getAttributes(joinPoint);
74  
75          ConfigAttributeDefinition expectedCountLength = new ConfigAttributeDefinition();
76          expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_ONE"));
77          expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_TWO"));
78          expectedCountLength.addConfigAttribute(new SecurityConfig(
79                  "RUN_AS_ENTRY"));
80          assertEquals(expectedCountLength, returnedCountLength);
81      }
82  
83      public void testClassNameNotFoundResultsInException() {
84          MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
85  
86          try {
87              editor.setAsText("org.acegisecurity.DOES_NOT_EXIST_NAME=FOO,BAR");
88              fail("Should have given IllegalArgumentException");
89          } catch (IllegalArgumentException expected) {
90              assertTrue(true);
91          }
92      }
93  
94      public void testClassNameNotInProperFormatResultsInException() {
95          MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
96  
97          try {
98              editor.setAsText("DOES_NOT_EXIST_NAME=FOO,BAR");
99              fail("Should have given IllegalArgumentException");
100         } catch (IllegalArgumentException expected) {
101             assertTrue(true);
102         }
103     }
104 
105     public void testClassNameValidButMethodNameInvalidResultsInException() {
106         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
107 
108         try {
109             editor.setAsText(
110                 "org.acegisecurity.TargetObject.INVALID_METHOD=FOO,BAR");
111             fail("Should have given IllegalArgumentException");
112         } catch (IllegalArgumentException expected) {
113             assertTrue(true);
114         }
115     }
116 
117     public void testConcreteClassInvocationsAlsoReturnDefinitionsAgainstInterface()
118         throws Exception {
119         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
120         editor.setAsText(
121             "org.acegisecurity.ITargetObject.makeLower*=ROLE_FROM_INTERFACE\r\norg.acegisecurity.ITargetObject.makeUpper*=ROLE_FROM_INTERFACE\r\norg.acegisecurity.TargetObject.makeUpper*=ROLE_FROM_IMPLEMENTATION");
122 
123         MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
124         assertEquals(3, map.getMethodMapSize());
125 
126         ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(
127                     TargetObject.class, "makeLowerCase",
128                     new Class[] {String.class}));
129         ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition();
130         expectedMakeLower.addConfigAttribute(new SecurityConfig(
131                 "ROLE_FROM_INTERFACE"));
132         assertEquals(expectedMakeLower, returnedMakeLower);
133 
134         ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(
135                     TargetObject.class, "makeUpperCase",
136                     new Class[] {String.class}));
137         ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition();
138         expectedMakeUpper.addConfigAttribute(new SecurityConfig(
139                 "ROLE_FROM_IMPLEMENTATION"));
140         expectedMakeUpper.addConfigAttribute(new SecurityConfig(
141                 "ROLE_FROM_INTERFACE"));
142         assertEquals(expectedMakeUpper, returnedMakeUpper);
143     }
144 
145     public void testEmptyStringReturnsEmptyMap() {
146         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
147         editor.setAsText("");
148 
149         MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
150         assertEquals(0, map.getMethodMapSize());
151     }
152 
153     public void testIterator() {
154         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
155         editor.setAsText(
156             "org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY\r\norg.acegisecurity.TargetObject.make*=ROLE_NINE,ROLE_SUPERVISOR");
157 
158         MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
159         Iterator iter = map.getConfigAttributeDefinitions();
160         int counter = 0;
161 
162         while (iter.hasNext()) {
163             iter.next();
164             counter++;
165         }
166 
167         assertEquals(3, counter);
168     }
169 
170     public void testMultiMethodParsing() {
171         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
172         editor.setAsText(
173             "org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY\r\norg.acegisecurity.TargetObject.make*=ROLE_NINE,ROLE_SUPERVISOR");
174 
175         MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
176         assertEquals(3, map.getMethodMapSize());
177     }
178 
179     public void testMultiMethodParsingWhereLaterMethodsOverrideEarlierMethods()
180         throws Exception {
181         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
182         editor.setAsText(
183             "org.acegisecurity.TargetObject.*=ROLE_GENERAL\r\norg.acegisecurity.TargetObject.makeLower*=ROLE_LOWER\r\norg.acegisecurity.TargetObject.make*=ROLE_MAKE\r\norg.acegisecurity.TargetObject.makeUpper*=ROLE_UPPER");
184 
185         MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
186         assertEquals(5, map.getMethodMapSize());
187 
188         ConfigAttributeDefinition returnedMakeLower = map.getAttributes(new MockMethodInvocation(
189                     TargetObject.class, "makeLowerCase",
190                     new Class[] {String.class}));
191         ConfigAttributeDefinition expectedMakeLower = new ConfigAttributeDefinition();
192         expectedMakeLower.addConfigAttribute(new SecurityConfig("ROLE_LOWER"));
193         assertEquals(expectedMakeLower, returnedMakeLower);
194 
195         ConfigAttributeDefinition returnedMakeUpper = map.getAttributes(new MockMethodInvocation(
196                     TargetObject.class, "makeUpperCase",
197                     new Class[] {String.class}));
198         ConfigAttributeDefinition expectedMakeUpper = new ConfigAttributeDefinition();
199         expectedMakeUpper.addConfigAttribute(new SecurityConfig("ROLE_UPPER"));
200         assertEquals(expectedMakeUpper, returnedMakeUpper);
201 
202         ConfigAttributeDefinition returnedCountLength = map.getAttributes(new MockMethodInvocation(
203                     TargetObject.class, "countLength",
204                     new Class[] {String.class}));
205         ConfigAttributeDefinition expectedCountLength = new ConfigAttributeDefinition();
206         expectedCountLength.addConfigAttribute(new SecurityConfig(
207                 "ROLE_GENERAL"));
208         assertEquals(expectedCountLength, returnedCountLength);
209     }
210 
211     public void testNullIsReturnedByMethodDefinitionSourceWhenMethodInvocationNotDefined()
212         throws Exception {
213         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
214         editor.setAsText(
215             "org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY");
216 
217         MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
218 
219         ConfigAttributeDefinition configAttributeDefinition = map.getAttributes(new MockMethodInvocation(
220                     TargetObject.class, "makeLowerCase",
221                     new Class[] {String.class}));
222         assertNull(configAttributeDefinition);
223     }
224 
225     public void testNullReturnsEmptyMap() {
226         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
227         editor.setAsText(null);
228 
229         MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
230         assertEquals(0, map.getMethodMapSize());
231     }
232 
233     public void testSingleMethodParsing() throws Exception {
234         MethodDefinitionSourceEditor editor = new MethodDefinitionSourceEditor();
235         editor.setAsText(
236             "org.acegisecurity.TargetObject.countLength=ROLE_ONE,ROLE_TWO,RUN_AS_ENTRY");
237 
238         MethodDefinitionMap map = (MethodDefinitionMap) editor.getValue();
239 
240         ConfigAttributeDefinition returnedCountLength = map.getAttributes(new MockMethodInvocation(
241                     TargetObject.class, "countLength",
242                     new Class[] {String.class}));
243         ConfigAttributeDefinition expectedCountLength = new ConfigAttributeDefinition();
244         expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_ONE"));
245         expectedCountLength.addConfigAttribute(new SecurityConfig("ROLE_TWO"));
246         expectedCountLength.addConfigAttribute(new SecurityConfig(
247                 "RUN_AS_ENTRY"));
248         assertEquals(expectedCountLength, returnedCountLength);
249     }
250 
251     //~ Inner Classes ==========================================================
252 
253     private class MockMethodInvocation implements MethodInvocation {
254         Method method;
255 
256         public MockMethodInvocation(Class clazz, String methodName,
257             Class[] parameterTypes) throws NoSuchMethodException {
258             method = clazz.getMethod(methodName, parameterTypes);
259         }
260 
261         private MockMethodInvocation() {
262             super();
263         }
264 
265         public Object[] getArguments() {
266             return null;
267         }
268 
269         public Method getMethod() {
270             return method;
271         }
272 
273         public AccessibleObject getStaticPart() {
274             return null;
275         }
276 
277         public Object getThis() {
278             return null;
279         }
280 
281         public Object proceed() throws Throwable {
282             return null;
283         }
284     }
285 }