View Javadoc
1   package org.apache.fulcrum.testcontainer;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import static org.mockito.ArgumentMatchers.any;
23  import static org.mockito.ArgumentMatchers.anyInt;
24  import static org.mockito.ArgumentMatchers.anyString;
25  import static org.mockito.Mockito.doAnswer;
26  import static org.mockito.Mockito.mock;
27  import static org.mockito.Mockito.when;
28  
29  import java.util.HashMap;
30  import java.util.Locale;
31  import java.util.Map;
32  import java.util.Vector;
33  
34  import javax.servlet.http.HttpServletRequest;
35  import javax.servlet.http.HttpSession;
36  
37  import org.apache.avalon.framework.component.ComponentException;
38  import org.apache.avalon.framework.logger.ConsoleLogger;
39  import org.junit.After;
40  import org.mockito.invocation.InvocationOnMock;
41  import org.mockito.stubbing.Answer;
42  
43  /**
44   * Alternative Base class to {@link BaseUnitTest} for component tests.
45   * 
46   * This version doesn't load the container until the first request for a
47   * component. This allows the tester to populate the configurationFileName and
48   * roleFileName, possible one per test.
49   * 
50   * JUnit 4 Version of BaseUnitTest class.
51   * 
52   * @see BaseUnitTest
53   *
54   * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
55   * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
56   * @version $Id$
57   */
58  
59  public class BaseUnit4Test {
60  	public static final String CONTAINER_ECM = "CONTAINER_ECM";
61  	public static final String CONTAINER_YAAFI = "CONTAINER_YAAFI";
62  
63  	/** Key used in the context for defining the application root */
64  	public static final String COMPONENT_APP_ROOT = Container.COMPONENT_APP_ROOT;
65  
66  	/** Pick the default container to be YAAFI **/
67  	private String containerType = CONTAINER_YAAFI;
68  
69  	/** Use INFO for ConsoleLogger */
70  	public static final int defaultLogLevel = ConsoleLogger.LEVEL_INFO;
71  
72  	/** Container for the components */
73  	private Container container;
74  
75  	/** Setup our default configurationFileName */
76  	private String configurationFileName = "src/test/TestComponentConfig.xml";
77  
78  	/** Setup our default roleFileName */
79  	private String roleFileName = "src/test/TestRoleConfig.xml";
80  
81  	/** Setup our default parameterFileName */
82  	private String parameterFileName = null;
83  
84  	/** Set the log level (only works for YAAFI container) */
85  	private int logLevel = defaultLogLevel;
86  
87  	/** Hash map to store attributes for the test **/
88  	public Map<String, Object> attributes = new HashMap<String, Object>();
89  
90  	/** set the Max inactive interval **/
91  	public int maxInactiveInterval = 0;
92  
93  	/**
94  	 * Gets the configuration file name for the container should use for this test.
95  	 * By default it is src/test/TestComponentConfig.
96  	 * 
97  	 * @param configurationFileName the location of the config file
98  	 */
99  	protected void setConfigurationFileName(String configurationFileName) 
100 	{
101 		this.configurationFileName = configurationFileName;
102 	}
103 
104 	/**
105 	 * Override the role file name for the container should use for this test. By
106 	 * default it is src/test/TestRoleConfig.
107 	 * 
108 	 * @param roleFileName location of the role file
109 	 */
110 	protected void setRoleFileName(String roleFileName) 
111 	{
112 		this.roleFileName = roleFileName;
113 	}
114 
115 	/**
116 	 * Set the console logger level
117 	 * 
118 	 * @see org.apache.avalon.framework.logger.ConsoleLogger for debugging levels
119 	 * @param logLevel set valid logging level
120 	 */
121 	protected void setLogLevel(int logLevel) 
122 	{
123 		this.logLevel = logLevel;
124 	}
125 
126 	/**
127 	 * Constructor for test.
128 	 */
129 	public BaseUnit4Test() 
130 	{
131 	}
132 
133 	/**
134 	 * Clean up after each test is run.
135 	 */
136 	@After
137 	public void tearDown() 
138 	{
139 		if (container != null) {
140 			container.dispose();
141 		}
142 		container = null;
143 	}
144 
145 	/**
146 	 * Gets the configuration file name for the container should use for this test.
147 	 *
148 	 * @return The filename of the configuration file
149 	 */
150 	protected String getConfigurationFileName() 
151 	{
152 		return configurationFileName;
153 	}
154 
155 	/**
156 	 * Gets the role file name for the container should use for this test.
157 	 *
158 	 * @return The filename of the role configuration file
159 	 */
160 	protected String getRoleFileName() 
161 	{
162 		return roleFileName;
163 	}
164 
165 	/**
166 	 * Gets the parameter file name for the container should use for this test.
167 	 *
168 	 * @return The filename of the role configuration file
169 	 */
170 	protected String getParameterFileName() 
171 	{
172 		return parameterFileName;
173 	}
174 
175 	/**
176 	 * Returns an instance of the named component. This method will also start the
177 	 * container if it has not been started already
178 	 *
179 	 * @param roleName Name of the role the component fills.
180 	 * @return instance of the component
181 	 * @throws ComponentException generic exception
182 	 */
183 	protected Object lookup(String roleName) throws ComponentException 
184 	{
185 		if (container == null) 
186 		{
187 			if (containerType.equals(CONTAINER_ECM)) 
188 			{
189 				container = new ECMContainer();
190 			} 
191 			else 
192 			{
193 				container = new YAAFIContainer(logLevel);
194 			}
195 			container.startup(getConfigurationFileName(), getRoleFileName(), getParameterFileName());
196 		}
197 		return container.lookup(roleName);
198 	}
199 
200 	/**
201 	 * Releases the component.
202 	 *
203 	 * @param component component to be released
204 	 */
205 	protected void release(Object component) 
206 	{
207 		if (container != null) 
208 		{
209 			container.release(component);
210 		}
211 	}
212 
213 	/**
214 	 * Get a mock requestion
215 	 *
216 	 * @return HttpServletRequest a mock servlet request
217 	 */
218 	protected HttpServletRequest getMockRequest() 
219 	{
220 		HttpServletRequest request = mock(HttpServletRequest.class);
221 		HttpSession session = mock(HttpSession.class);
222 
223 		doAnswer(new Answer<Object>() 
224 		{
225 			@Override
226 			public Object answer(InvocationOnMock invocation) throws Throwable 
227 			{
228 				String key = (String) invocation.getArguments()[0];
229 				return attributes.get(key);
230 			}
231 		}).when(session).getAttribute(anyString());
232 
233 		doAnswer(new Answer<Object>() 
234 		{
235 			@Override
236 			public Object answer(InvocationOnMock invocation) throws Throwable 
237 			{
238 				String key = (String) invocation.getArguments()[0];
239 				Object value = invocation.getArguments()[1];
240 				attributes.put(key, value);
241 				return null;
242 			}
243 		}).when(session).setAttribute(anyString(), any());
244 
245 		when(session.getMaxInactiveInterval()).thenReturn(maxInactiveInterval);
246 
247 		doAnswer(new Answer<Integer>() 
248 		{
249 			@Override
250 			public Integer answer(InvocationOnMock invocation) throws Throwable {
251 				return Integer.valueOf(maxInactiveInterval);
252 			}
253 		}).when(session).getMaxInactiveInterval();
254 
255 		doAnswer(new Answer<Object>() 
256 		{
257 			@Override
258 			public Object answer(InvocationOnMock invocation) throws Throwable 
259 			{
260 				Integer value = (Integer) invocation.getArguments()[0];
261 				maxInactiveInterval = value.intValue();
262 				return null;
263 			}
264 		}).when(session).setMaxInactiveInterval(anyInt());
265 
266 		when(session.isNew()).thenReturn(true);
267 		when(request.getSession()).thenReturn(session);
268 
269 		when(request.getServerName()).thenReturn("bob");
270 		when(request.getProtocol()).thenReturn("http");
271 		when(request.getScheme()).thenReturn("scheme");
272 		when(request.getPathInfo()).thenReturn("damn");
273 		when(request.getServletPath()).thenReturn("damn2");
274 		when(request.getContextPath()).thenReturn("wow");
275 		when(request.getContentType()).thenReturn("text/html");
276 
277 		when(request.getCharacterEncoding()).thenReturn("US-ASCII");
278 		when(request.getServerPort()).thenReturn(8080);
279 		when(request.getLocale()).thenReturn(Locale.US);
280 
281 		when(request.getHeader("Content-type")).thenReturn("text/html");
282 		when(request.getHeader("Accept-Language")).thenReturn("en-US");
283 
284 		Vector<String> v = new Vector<String>();
285 		when(request.getParameterNames()).thenReturn(v.elements());
286 		return request;
287 	}
288 
289 	public String getContainerType() 
290 	{
291 		return containerType;
292 	}
293 
294 	public void setContainerType(String containerType) 
295 	{
296 		this.containerType = containerType;
297 	}
298 }