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    }