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    }