001 /** 002 * Copyright 2004-2014 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.time.util; 017 018 import java.math.BigDecimal; 019 import java.net.URLEncoder; 020 import java.util.ArrayList; 021 import java.util.List; 022 023 import org.apache.log4j.Logger; 024 import org.joda.time.DateTime; 025 import org.joda.time.Interval; 026 import org.kuali.hr.TestAutoLoginFilter; 027 import org.kuali.hr.util.HtmlUnitUtil; 028 import org.kuali.kpme.core.assignment.Assignment; 029 import org.kuali.kpme.core.assignment.AssignmentDescriptionKey; 030 import org.kuali.kpme.core.earncode.EarnCode; 031 import org.kuali.kpme.core.util.TKUtils; 032 import org.kuali.kpme.tklm.time.detail.validation.TimeDetailValidationUtil; 033 import org.kuali.kpme.tklm.time.detail.web.TimeDetailActionFormBase; 034 import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument; 035 036 import com.gargoylesoftware.htmlunit.WebClient; 037 import com.gargoylesoftware.htmlunit.html.HtmlButton; 038 import com.gargoylesoftware.htmlunit.html.HtmlForm; 039 import com.gargoylesoftware.htmlunit.html.HtmlPage; 040 041 public class TimeDetailTestUtils { 042 043 private static final Logger LOG = Logger.getLogger(TimeDetailTestUtils.class); 044 045 /** 046 * From the provided set of parameters, build an action form suitable for 047 * submitting to the TimeDetailAction servlet. In our case, we are mostly 048 * using it in a mock type of situation. 049 * @param timeshetDocument 050 * @param assignment 051 * @param earnCode 052 * @param start 053 * @param end 054 * @param amount 055 * @param acrossDays 056 * @param timeblockId 057 * 058 * @return A populated TimeDetailActionFormBase object. 059 */ 060 public static TimeDetailActionFormBase buildDetailActionForm(TimesheetDocument timeshetDocument, Assignment assignment, EarnCode earnCode, DateTime start, DateTime end, BigDecimal amount, boolean acrossDays, String timeblockId, boolean spanningWeeks) { 061 TimeDetailActionFormBase tdaf = new TimeDetailActionFormBase(); 062 /** 063 * 064 * 065 * 066 */ 067 BigDecimal hours = null; 068 String startTimeS = null; 069 String endTimeS = null; 070 String startDateS; 071 String endDateS; 072 String selectedEarnCode; 073 String selectedAssignment; 074 075 if (hours == null) { 076 if (start != null && end != null) { 077 Interval se_i = new Interval(start, end); 078 hours = TKUtils.convertMillisToHours(se_i.toDurationMillis()); 079 } 080 081 // the date/time format is defined in tk.calendar.js. For now, the format is 11/17/2010 8:0 082 startTimeS = start.toString("H:mm"); 083 endTimeS = end.toString("H:mm"); 084 } 085 086 startDateS = start.toString("MM/dd/YYYY"); 087 endDateS = end.toString("MM/dd/YYYY"); 088 089 AssignmentDescriptionKey adk = new AssignmentDescriptionKey(assignment); 090 selectedAssignment = adk.toAssignmentKeyString(); 091 092 selectedEarnCode = earnCode.getEarnCode(); 093 094 tdaf.setAcrossDays(acrossDays ? "y" : "n"); 095 tdaf.setSpanningWeeks(spanningWeeks ? "y" : "n"); // KPME-1446 096 tdaf.setAmount(amount); 097 tdaf.setHours(hours); 098 tdaf.setStartTime(startTimeS); 099 tdaf.setEndTime(endTimeS); 100 tdaf.setStartDate(startDateS); 101 tdaf.setEndDate(endDateS); 102 tdaf.setTkTimeBlockId(timeblockId); 103 tdaf.setTimesheetDocument(timeshetDocument); 104 tdaf.setSelectedAssignment(selectedAssignment); 105 tdaf.setSelectedEarnCode(selectedEarnCode); 106 //tdaf.setPrincipalId(principalId); 107 tdaf.setMethodToCall("addTimeBlock"); 108 109 return tdaf; 110 } 111 112 /** 113 * Set the attributes on the provided html form to the values found in the provided 114 * ActionForm. Errors are returned in the List<String> object. 115 * 116 * @param form The HtmlForm to populate. 117 * @param tdaf The ActionForm with values we will use to populate. 118 * 119 * @return A list of string error messages from the validation call. 120 */ 121 public static List<String> setTimeBlockFormDetails(HtmlForm form, TimeDetailActionFormBase tdaf) { 122 // Validation -- the same call the WS makes. (should already be valid...) 123 List<String> errors = TimeDetailValidationUtil.validateTimeEntryDetails(tdaf); 124 /* errors = new ArrayList<String>();*/ 125 // If validation passes, we can add the time block. 126 if (errors.size() == 0) { 127 if (tdaf.getTkTimeBlockId() != null) { 128 form.setAttribute("tkTimeBlockId", tdaf.getTkTimeBlockId().toString()); 129 } 130 form.setAttribute("startDate", tdaf.getStartDate()); 131 form.setAttribute("endDate", tdaf.getEndDate()); 132 133 if (tdaf.getAmount() != null) { 134 form.setAttribute("amount", tdaf.getAmount().toString()); 135 } else { 136 form.setAttribute("startTime", tdaf.getStartTime()); 137 form.setAttribute("endTime", tdaf.getEndTime()); 138 form.setAttribute("hours", tdaf.getHours().toString()); 139 } 140 141 form.setAttribute("selectedEarnCode", tdaf.getSelectedEarnCode()); 142 form.setAttribute("selectedAssignment", tdaf.getSelectedAssignment()); 143 form.setAttribute("acrossDays", tdaf.getAcrossDays()); 144 form.setAttribute("methodToCall", tdaf.getMethodToCall()); 145 //form.setAttribute("principalId", tdaf.getPrincipalId()); 146 } 147 148 return errors; 149 } 150 151 /** 152 * This is a 'hacker' method to get around the fact that in HtmlUnit you 153 * can no longer directly submit forms if there are no buttons. We 154 * simply add a button to the form, and click it! 155 * 156 * @param page The HtmlPage the form came from. 157 * @param form The HtmlForm you wish to submit. 158 * @return The return results from clicking .submit() 159 */ 160 private static HtmlPage submitTimeDetailsDep(HtmlPage page, HtmlForm form) { 161 HtmlButton submitButton = null; 162 163 //ScriptResult sr = page.executeJavaScript("document.forms[\"TimeDetailActionForm\"].submit();"); 164 165 if (submitButton == null) { 166 submitButton = (HtmlButton)page.createElement("button"); 167 submitButton.setAttribute("type", "submit"); 168 form.appendChild(submitButton); 169 } 170 171 HtmlPage newPage = null; 172 try { 173 submitButton.click(); 174 } catch (Exception e) { 175 LOG.error("While submitting time detail form", e); 176 } 177 178 return newPage; 179 } 180 181 182 /** 183 * A method to wrap the submission of the time details. 184 * @param baseUrl 185 * @param tdaf 186 * @return 187 */ 188 public static HtmlPage submitTimeDetails(WebClient webClient, String baseUrl, TimeDetailActionFormBase tdaf) { 189 // For now, until a more HtmlUnit based click method can be found 190 // workable, we're building a url-encoded string to directly 191 // post to the servlet. 192 193 String url = baseUrl + buildPostFromFormParams(tdaf); 194 HtmlPage page = null; 195 196 try { 197 page = HtmlUnitUtil.gotoPageAndLogin(webClient, url); 198 } catch (Exception e) { 199 LOG.error("Error while submitting form", e); 200 } 201 202 return page; 203 } 204 205 /** 206 * A method to wrap the submission of the time details. 207 * @param baseUrl 208 * @param tdaf 209 * @return 210 */ 211 public static HtmlPage submitTimeDetails(WebClient webClient, String principalId, String baseUrl, TimeDetailActionFormBase tdaf) { 212 // For now, until a more HtmlUnit based click method can be found 213 // workable, we're building a url-encoded string to directly 214 // post to the servlet. 215 216 String url = baseUrl + buildPostFromFormParams(tdaf); 217 HtmlPage page = null; 218 219 try { 220 TestAutoLoginFilter.OVERRIDE_ID = principalId; 221 page = HtmlUnitUtil.gotoPageAndLogin(webClient, url); 222 TestAutoLoginFilter.OVERRIDE_ID = ""; 223 } catch (Exception e) { 224 LOG.error("Error while submitting form", e); 225 } 226 227 return page; 228 } 229 230 private static String buildPostFromFormParams(TimeDetailActionFormBase tdaf) { 231 StringBuilder builder = new StringBuilder(); 232 233 try { 234 builder.append("&methodToCall=").append(URLEncoder.encode(tdaf.getMethodToCall(), "UTF-8")); 235 builder.append("&acrossDays=").append(URLEncoder.encode(tdaf.getAcrossDays(), "UTF-8")); 236 if (tdaf.getAmount() != null) { 237 builder.append("&amount=").append(URLEncoder.encode(tdaf.getAmount().toString(), "UTF-8")); 238 } else { 239 builder.append("&hours=").append(URLEncoder.encode(tdaf.getHours().toString(), "UTF-8")); 240 builder.append("&startTime=").append(URLEncoder.encode(tdaf.getStartTime(), "UTF-8")); 241 builder.append("&endTime=").append(URLEncoder.encode(tdaf.getEndTime(), "UTF-8")); 242 } 243 builder.append("&startDate=").append(URLEncoder.encode(tdaf.getStartDate(), "UTF-8")); 244 builder.append("&endDate=").append(URLEncoder.encode(tdaf.getEndDate(), "UTF-8")); 245 builder.append("&selectedAssignment=").append(URLEncoder.encode(tdaf.getSelectedAssignment(), "UTF-8")); 246 builder.append("&selectedEarnCode=").append(URLEncoder.encode(tdaf.getSelectedEarnCode(), "UTF-8")); 247 //builder.append("&principalId=").append(URLEncoder.encode(tdaf.getPrincipalId(), "UTF-8")); 248 if (tdaf.getTkTimeBlockId() != null) { 249 builder.append("&tkTimeBlockId=").append(URLEncoder.encode(tdaf.getTkTimeBlockId().toString(), "UTF-8")); 250 } 251 } catch (Exception e) { 252 LOG.error("Exception building Post String", e); 253 } 254 255 return builder.toString(); 256 } 257 }