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