View Javadoc
1   /**
2    * Copyright 2004-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.time.util;
17  
18  import com.gargoylesoftware.htmlunit.WebClient;
19  import com.gargoylesoftware.htmlunit.html.HtmlButton;
20  import com.gargoylesoftware.htmlunit.html.HtmlForm;
21  import com.gargoylesoftware.htmlunit.html.HtmlPage;
22  import org.apache.log4j.Logger;
23  import org.joda.time.DateTime;
24  import org.joda.time.Interval;
25  import org.kuali.hr.TestAutoLoginFilter;
26  import org.kuali.hr.util.HtmlUnitUtil;
27  import org.kuali.kpme.core.api.assignment.Assignment;
28  import org.kuali.kpme.core.api.assignment.AssignmentDescriptionKey;
29  import org.kuali.kpme.core.api.earncode.EarnCode;
30  import org.kuali.kpme.core.util.TKUtils;
31  import org.kuali.kpme.tklm.leave.transfer.BalanceTransfer;
32  import org.kuali.kpme.tklm.time.detail.validation.TimeDetailValidationUtil;
33  import org.kuali.kpme.tklm.time.detail.web.TimeDetailActionFormBase;
34  import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
35  
36  import java.math.BigDecimal;
37  import java.net.URLEncoder;
38  import java.util.List;
39  
40  public class TimeDetailTestUtils {
41  
42      private static final Logger LOG = Logger.getLogger(TimeDetailTestUtils.class);
43  
44      /**
45       * From the provided set of parameters, build an action form suitable for
46       * submitting to the TimeDetailAction servlet. In our case, we are mostly
47       * using it in a mock type of situation.
48       * @param timeshetDocument
49       * @param assignment
50       * @param earnCode
51       * @param start
52       * @param end
53       * @param amount
54       * @param acrossDays
55       * @param timeblockId
56       *
57       * @return A populated TimeDetailActionFormBase object.
58       */
59      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) {
60          TimeDetailActionFormBase tdaf = new TimeDetailActionFormBase();
61          /**
62           * 
63           * 
64           * 
65           */
66          BigDecimal hours = null;
67          String startTimeS = null;
68          String endTimeS = null;
69          String startDateS;
70          String endDateS;
71          String selectedEarnCode;
72          String selectedAssignment;
73  
74          if (hours == null) {
75              if (start != null && end != null) {
76                  Interval se_i = new Interval(start, end);
77                  hours = TKUtils.convertMillisToHours(se_i.toDurationMillis());
78              }
79  
80              // the date/time format is defined in tk.calendar.js. For now, the format is 11/17/2010 8:0
81              startTimeS = start.toString("H:mm");
82              endTimeS = end.toString("H:mm");
83          }
84  
85          startDateS = start.toString("MM/dd/YYYY");
86          endDateS = end.toString("MM/dd/YYYY");
87  
88          AssignmentDescriptionKey adk = new AssignmentDescriptionKey(assignment);
89          selectedAssignment = adk.toAssignmentKeyString();
90  
91          selectedEarnCode = earnCode.getEarnCode();
92  
93          tdaf.setAcrossDays(acrossDays ? "y" : "n");
94  //        tdaf.setSpanningWeeks(spanningWeeks ? "y" : "n"); // KPME-1446
95          tdaf.setAmount(amount);
96          tdaf.setHours(hours);
97          tdaf.setStartTime(startTimeS);
98          tdaf.setEndTime(endTimeS);
99          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 }