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.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 }