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