001 /**
002 * Copyright 2004-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.hr.test;
017
018 import java.io.File;
019 import java.util.ArrayList;
020 import java.util.Calendar;
021 import java.util.List;
022
023 import com.gargoylesoftware.htmlunit.BrowserVersion;
024 import com.gargoylesoftware.htmlunit.WebClient;
025 import com.gargoylesoftware.htmlunit.html.*;
026 import org.apache.log4j.Logger;
027 import org.junit.Assert;
028 import org.kuali.hr.time.test.HtmlUnitUtil;
029 import org.kuali.hr.time.test.TkTestConstants;
030 import org.kuali.hr.time.util.*;
031 import org.kuali.rice.core.api.config.property.Config;
032 import org.kuali.rice.core.api.config.property.ConfigContext;
033 import org.kuali.rice.core.api.lifecycle.BaseLifecycle;
034 import org.kuali.rice.core.api.lifecycle.Lifecycle;
035 import org.kuali.rice.core.impl.services.CoreImplServiceLocator;
036 import org.kuali.rice.krad.UserSession;
037 import org.kuali.rice.krad.service.KRADServiceLocatorInternal;
038 import org.kuali.rice.krad.util.GlobalVariables;
039 import org.kuali.rice.krad.util.MessageMap;
040 import org.kuali.rice.test.RiceInternalSuiteDataTestCase;
041 import org.kuali.rice.test.TransactionalLifecycle;
042 import org.kuali.rice.test.lifecycles.JettyServerLifecycle;
043 import org.kuali.rice.test.lifecycles.JettyServerLifecycle.ConfigMode;
044 import org.kuali.rice.test.lifecycles.KPMEXmlDataLoaderLifecycle;
045 import org.springframework.cache.CacheManager;
046 import org.springframework.mock.web.MockHttpServletRequest;
047
048 /**
049 * Default test base for a full KPME unit test.
050 */
051 public abstract class KPMETestCase extends RiceInternalSuiteDataTestCase {
052
053 private static final String FILE_PREFIX = System.getProperty("user.dir") + "/src/main/config/workflow/";
054
055 private static final String RELATIVE_WEBAPP_ROOT = "/src/main/webapp";
056
057 private TransactionalLifecycle transactionalLifecycle;
058 private WebClient webClient;
059
060 @Override
061 protected String getModuleName() {
062 return "kpme";
063 }
064
065 @Override
066 public void setUp() throws Exception {
067 if (System.getProperty("basedir") == null) {
068 System.setProperty("basedir", System.getProperty("user.dir") + "/");
069 }
070
071 super.setUp();
072
073 GlobalVariables.setMessageMap(new MessageMap());
074
075 final boolean needsSpring = false;
076 if (needsSpring) {
077 transactionalLifecycle = new TransactionalLifecycle();
078 transactionalLifecycle.setTransactionManager(KRADServiceLocatorInternal.getTransactionManager());
079 transactionalLifecycle.start();
080 }
081
082 new ClearDatabaseLifecycle().start();
083
084 new LoadDatabaseDataLifeCycle(this.getClass()).start();
085
086 //lets try to create a user session
087 GlobalVariables.setUserSession(new UserSession("admin"));
088 TKContext.setHttpServletRequest(new MockHttpServletRequest());
089 setWebClient(new WebClient(BrowserVersion.FIREFOX_10));
090 getWebClient().setJavaScriptEnabled(true);
091 getWebClient().setTimeout(0);
092 }
093
094 @Override
095 public void tearDown() throws Exception {
096 // runs custom SQL at the end of each test.
097 // useful for difficult to reset test additions, not handled by
098 // our ClearDatabaseLifecycle.
099 TKUser.clearTargetUser();
100 getWebClient().closeAllWindows();
101 new DatabaseCleanupDataLifecycle(this.getClass()).start();
102
103 final boolean needsSpring = true;
104 if (needsSpring) {
105 if ( (transactionalLifecycle != null) && (transactionalLifecycle.isStarted()) ) {
106 transactionalLifecycle.stop();
107 }
108 }
109
110 GlobalVariables.setMessageMap(new MessageMap());
111
112 super.tearDown();
113 }
114
115 @Override
116 protected List<Lifecycle> getPerTestLifecycles() {
117 List<Lifecycle> lifecycles = super.getPerTestLifecycles();
118 lifecycles.add(new ClearCacheLifecycle());
119 return lifecycles;
120 }
121
122 @Override
123 protected List<Lifecycle> getSuiteLifecycles() {
124 List<Lifecycle> lifecycles = super.getPerTestLifecycles();
125 lifecycles.add(new Lifecycle() {
126 boolean started = false;
127
128 public boolean isStarted() {
129 return this.started;
130 }
131
132 public void start() throws Exception {
133 setModuleName(getModuleName());
134 setBaseDirSystemProperty(getModuleName());
135 Config config = getTestHarnessConfig();
136 ConfigContext.init(config);
137 this.started = true;
138 }
139
140 public void stop() throws Exception {
141 this.started = false;
142 }
143 });
144 /**
145 * Loads the TestHarnessSpringBeans.xml file which obtains connections to the DB for us
146 */
147 /*lifecycles.add(getTestHarnessSpringResourceLoader());*/
148
149 /**
150 * Establishes the TestHarnessServiceLocator so that it has a reference to the Spring context
151 * created from TestHarnessSpringBeans.xml
152 */
153 /*lifecycles.add(new BaseLifecycle() {
154 @Override
155 public void start() throws Exception {
156 TestHarnessServiceLocator.setContext(getTestHarnessSpringResourceLoader().getContext());
157 super.start();
158 }
159 });*/
160
161 lifecycles.add(new Lifecycle() {
162 private JettyServerLifecycle jettyServerLifecycle;
163
164 public boolean isStarted() {
165 return jettyServerLifecycle.isStarted();
166 }
167
168 public void start() throws Exception {
169 System.setProperty("web.bootstrap.spring.file", "classpath:TestHarnessSpringBeans.xml");
170 jettyServerLifecycle = new JettyServerLifecycle(HtmlUnitUtil.getPort(), HtmlUnitUtil.getContext(), RELATIVE_WEBAPP_ROOT);
171 jettyServerLifecycle.setConfigMode(ConfigMode.OVERRIDE);
172 jettyServerLifecycle.start();
173 }
174
175 public void stop() throws Exception {
176 this.jettyServerLifecycle.stop();
177 }
178 });
179
180 ClearDatabaseLifecycle clearDatabaseLifecycle = new ClearDatabaseLifecycle();
181 clearDatabaseLifecycle.getAlternativeTablesToClear().add("KREW_RULE_T");
182 clearDatabaseLifecycle.getAlternativeTablesToClear().add("KREW_RULE_RSP_T");
183 clearDatabaseLifecycle.getAlternativeTablesToClear().add("KREW_DLGN_RSP_T");
184 clearDatabaseLifecycle.getAlternativeTablesToClear().add("KREW_RULE_ATTR_T");
185 clearDatabaseLifecycle.getAlternativeTablesToClear().add("KREW_RULE_TMPL_T");
186 clearDatabaseLifecycle.getAlternativeTablesToClear().add("KREW_DOC_TYP_T");
187 lifecycles.add(clearDatabaseLifecycle);
188
189 File[] files = new File(FILE_PREFIX).listFiles();
190 if (files != null) {
191 for (File file : files) {
192 if (file.getName().endsWith(".xml")) {
193 lifecycles.add(new KPMEXmlDataLoaderLifecycle(FILE_PREFIX + file.getName()));
194 }
195 }
196 }
197 return lifecycles;
198 }
199
200 protected final void setFieldValue(HtmlPage page, String fieldId, String fieldValue) {
201 HtmlElement element = page.getHtmlElementById(fieldId);
202 Assert.assertTrue("element " + fieldId + " is null, page: " + page.asText(), element != null);
203
204 if (element instanceof HtmlTextInput) {
205 HtmlTextInput textField = (HtmlTextInput) element;
206 textField.setValueAttribute(fieldValue);
207 } else if (element instanceof HtmlTextArea) {
208 HtmlTextArea textAreaField = (HtmlTextArea) element;
209 textAreaField.setText(fieldValue);
210 } else if (element instanceof HtmlHiddenInput) {
211 HtmlHiddenInput hiddenField = (HtmlHiddenInput) element;
212 hiddenField.setValueAttribute(fieldValue);
213 } else if (element instanceof HtmlSelect) {
214 HtmlSelect selectField = (HtmlSelect) element;
215 try {
216 selectField.setSelectedAttribute(fieldValue, true);
217 } catch (IllegalArgumentException e) {
218 Assert.fail("select element [" + element.asText() + "] " + e.getMessage());
219 }
220 } else if (element instanceof HtmlCheckBoxInput) {
221 HtmlCheckBoxInput checkboxField = (HtmlCheckBoxInput) element;
222 if (fieldValue.equals("on")) {
223 checkboxField.setChecked(true);
224 } else if (fieldValue.equals("off")) {
225 checkboxField.setChecked(false);
226 } else {
227 Assert.assertTrue("Invalid checkbox value", false);
228 }
229 } else if (element instanceof HtmlFileInput) {
230 HtmlFileInput fileInputField = (HtmlFileInput) element;
231 fileInputField.setValueAttribute(fieldValue);
232 } else if (element instanceof HtmlRadioButtonInput) {
233 HtmlRadioButtonInput radioButton = (HtmlRadioButtonInput) element;
234 if (fieldValue.equals("on")) {
235 radioButton.setChecked(true);
236 } else if (fieldValue.equals("off")) {
237 radioButton.setChecked(false);
238 }
239 } else {
240 Assert.fail("Unknown control field: " + fieldId);
241 }
242 }
243
244 public void futureEffectiveDateValidation(String baseUrl) throws Exception {
245 HtmlPage page = HtmlUnitUtil.gotoPageAndLogin(getWebClient(), baseUrl);
246 Assert.assertNotNull(page);
247
248 HtmlForm form = page.getFormByName("KualiForm");
249 Assert.assertNotNull("Search form was missing from page.", form);
250 // use past dates
251 setFieldValue(page, "document.newMaintainableObject.effectiveDate", "04/01/2011");
252 HtmlInput input = HtmlUnitUtil.getInputContainingText(form, "methodToCall.route");
253 Assert.assertNotNull("Could not locate submit button", input);
254 page = ((HtmlButtonInput)page.getElementByName("methodToCall.route")).click();
255 Assert.assertTrue("page text does not contain:\n" + TkTestConstants.EFFECTIVE_DATE_ERROR, page.asText().contains(TkTestConstants.EFFECTIVE_DATE_ERROR));
256 Calendar futureDate = Calendar.getInstance();
257 futureDate.add(java.util.Calendar.YEAR, 2);// 2 years in the future
258 String futureDateString = "01/01/" + Integer.toString(futureDate.get(Calendar.YEAR));
259
260 // use dates 2 years in the future
261 setFieldValue(page, "document.newMaintainableObject.effectiveDate", futureDateString);
262 page = ((HtmlButtonInput)page.getElementByName("methodToCall.route")).click();
263 Assert.assertTrue("page text does not contain:\n" + TkTestConstants.EFFECTIVE_DATE_ERROR, page.asText().contains(TkTestConstants.EFFECTIVE_DATE_ERROR));
264 Calendar validDate = Calendar.getInstance();
265 validDate.add(java.util.Calendar.MONTH, 5); // 5 month in the future
266 String validDateString = Integer.toString(validDate.get(Calendar.MONTH)) + '/' + Integer.toString(validDate.get(Calendar.DAY_OF_MONTH))
267 + '/' + Integer.toString(validDate.get(Calendar.YEAR));
268 setFieldValue(page, "document.newMaintainableObject.effectiveDate", validDateString);
269 page = ((HtmlElement)page.getElementByName("methodToCall.route")).click();
270 Assert.assertFalse("page text contains:\n" + TkTestConstants.EFFECTIVE_DATE_ERROR, page.asText().contains(TkTestConstants.EFFECTIVE_DATE_ERROR));
271 }
272
273 public class ClearCacheLifecycle extends BaseLifecycle {
274 private final Logger LOG = Logger.getLogger(ClearCacheLifecycle.class);
275
276 @Override
277 public void start() throws Exception {
278 long startTime = System.currentTimeMillis();
279 LOG.info("Starting cache flushing");
280 List<CacheManager> cms = new ArrayList<CacheManager>(CoreImplServiceLocator.getCacheManagerRegistry().getCacheManagers());
281 for (CacheManager cm : cms) {
282 for (String cacheName : cm.getCacheNames()) {
283 //LOG.info("Clearing cache: " + cacheName);
284 cm.getCache(cacheName).clear();
285 }
286 }
287 long endTime = System.currentTimeMillis();
288 LOG.info("Caches cleared in " + (endTime - startTime) + "ms");
289 }
290
291 @Override
292 public void stop() throws Exception {
293 super.stop();
294 }
295
296 }
297
298 public WebClient getWebClient() {
299 return this.webClient;
300 }
301
302 public void setWebClient(WebClient webClient) {
303 this.webClient = webClient;
304 }
305
306 }