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 */
016package org.kuali.hr.lm.leaveCalendar;
017
018import java.math.BigDecimal;
019import java.net.URLEncoder;
020
021import org.apache.log4j.Logger;
022import org.joda.time.DateTime;
023import org.joda.time.Interval;
024import org.kuali.hr.util.HtmlUnitUtil;
025import org.kuali.kpme.core.assignment.Assignment;
026import org.kuali.kpme.core.assignment.AssignmentDescriptionKey;
027import org.kuali.kpme.core.earncode.EarnCode;
028import org.kuali.kpme.core.util.HrConstants;
029import org.kuali.kpme.core.util.TKUtils;
030import org.kuali.kpme.tklm.leave.calendar.LeaveCalendarDocument;
031import org.kuali.kpme.tklm.leave.calendar.web.LeaveCalendarWSForm;
032import org.kuali.kpme.tklm.leave.summary.LeaveSummary;
033
034import com.gargoylesoftware.htmlunit.WebClient;
035import com.gargoylesoftware.htmlunit.html.HtmlForm;
036import com.gargoylesoftware.htmlunit.html.HtmlPage;
037
038public class LeaveCalendarTestUtils {
039
040    private static final Logger LOG = Logger.getLogger(LeaveCalendarTestUtils.class);
041
042    /**
043     * From the provided set of parameters, build an action form suitable for
044     * submitting to the TimeDetailAction servlet. In our case, we are mostly
045     * using it in a mock type of situation, the situation of leave block addition.
046     *
047     * @param leaveCalendarDocument
048     * @param assignment
049     * @param earnCode
050     * @param start
051     * @param end
052     * @param amount
053     *
054     * @return A populated TimeDetailActionFormBase object.
055     */
056    public static LeaveCalendarWSForm buildLeaveCalendarForm(LeaveCalendarDocument leaveCalendarDocument, Assignment assignment, EarnCode earnCode, DateTime start, DateTime end, BigDecimal amount, boolean spanningWeeks) {
057        LeaveCalendarWSForm lcf = new LeaveCalendarWSForm();
058
059        BigDecimal hours = null;
060        String startTimeS = null;
061        String endTimeS = null;
062        String startDateS;
063        String endDateS;
064        String selectedEarnCode;
065        String selectedAssignment;
066
067        if (amount == null) {
068            if (start != null && end != null) {
069                Interval se_i = new Interval(start, end);
070                hours = TKUtils.convertMillisToHours(se_i.toDurationMillis());
071            }
072
073            // the date/time format is defined in tk.calendar.js. For now, the format is 11/17/2010 8:0
074            startTimeS = start.toString("H:mm");
075            endTimeS = end.toString("H:mm");
076        } else {
077            hours = amount;
078        }
079
080        startDateS = start.toString("MM/dd/YYYY");
081        endDateS = end.toString("MM/dd/YYYY");
082
083        AssignmentDescriptionKey adk = new AssignmentDescriptionKey(assignment);
084        selectedAssignment = adk.toAssignmentKeyString();
085
086        selectedEarnCode = earnCode.getEarnCode();
087
088        //lcf.setAcrossDays(acrossDays ? "y" : "n");
089
090        lcf.setSpanningWeeks(spanningWeeks ? "y" : "n"); // KPME-1446
091
092        lcf.setLeaveAmount(hours);
093        //lcf.setHours(hours);
094        lcf.setStartDate(startDateS);
095        lcf.setEndDate(endDateS);
096        //lcf.setTkTimeBlockId(timeblockId);
097        lcf.setLeaveCalendarDocument(leaveCalendarDocument);
098        lcf.setSelectedAssignment(selectedAssignment);
099        lcf.setSelectedEarnCode(selectedEarnCode);
100        lcf.setMethodToCall("addLeaveBlock");
101
102        return lcf;
103    }
104    
105    /**
106     * Builds a simple "mock" leave calendar form primed for action "approveLeaveCalendar".
107     * Suitable for testing logic LeaveCalendarSubmitAction actions.
108     *
109     * @param leaveCalendarDocument
110     * @param assignment
111     * @param earnCode
112     * @param start
113     * @param end
114     * @param amount
115     *
116     * @return A populated TimeDetailActionFormBase object.
117     */
118    public static LeaveCalendarWSForm buildLeaveCalendarFormForSubmission(LeaveCalendarDocument leaveCalendarDocument, LeaveSummary leaveSummary) {
119        LeaveCalendarWSForm lcf = new LeaveCalendarWSForm();
120
121        lcf.setMethodToCall("approveLeaveCalendar");
122        lcf.setLeaveSummary(leaveSummary);
123
124        return lcf;
125    }
126    
127
128    /**
129     * Set the attributes on the provided html form to the values found in the provided
130     * ActionForm. Returns void, not a List<String> of errors.
131     *
132     * @param form The HtmlForm to populate.
133     * @param tdaf The ActionForm with values we will use to populate.
134     */
135    public static void setTimeBlockFormDetails(HtmlForm form, LeaveCalendarWSForm tdaf) {
136        //if (tdaf.getLeaveBlockId() != null) {
137        //    form.setAttribute("leaveBlockId", tdaf.getLeaveBlockId().toString());
138        //}
139        form.setAttribute("startDate", tdaf.getStartDate());
140        form.setAttribute("endDate", tdaf.getEndDate());
141
142        if (tdaf.getLeaveAmount() != null) {
143            form.setAttribute("leaveAmount", tdaf.getLeaveAmount().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    }
151
152    /**
153     * This is a 'hacker' method to get around the fact that in HtmlUnit you
154     * can no longer directly submit forms if there are no buttons. We
155     * simply add a button to the form, and click it!
156     *
157     * @param page The HtmlPage the form came from.
158     * @param form The HtmlForm you wish to submit.
159     * @return The return results from clicking .submit()
160     */
161    /*private static HtmlPage submitTimeDetailsDep(HtmlPage page, HtmlForm form) {
162        HtmlButton submitButton = null;
163
164        //ScriptResult sr = page.executeJavaScript("document.forms[\"TimeDetailActionForm\"].submit();");
165
166        if (submitButton == null) {
167            submitButton = (HtmlButton)page.createElement("button");
168            submitButton.setAttribute("type", "submit");
169            form.appendChild(submitButton);
170        }
171
172        HtmlPage newPage = null;
173        try {
174            submitButton.click();
175        } catch (Exception e) {
176            LOG.error("While submitting time detail form", e);
177        }
178
179        return newPage;
180    }*/
181
182
183    /**
184     * A method to wrap the submission of the time details.
185     * @param baseUrl
186     * @param tdaf
187     * @return
188     */
189    public static HtmlPage submitLeaveCalendar(WebClient webClient, String baseUrl, LeaveCalendarWSForm tdaf) {
190        // For now, until a more HtmlUnit based click method can be found
191        // workable, we're building a url-encoded string to directly
192        // post to the servlet.
193
194        String url = baseUrl + buildPostFromFormParams(tdaf);
195        HtmlPage page = null;
196
197        try {
198            page = HtmlUnitUtil.gotoPageAndLogin(webClient, url);
199        } catch (Exception e) {
200            LOG.error("Error while submitting form", e);
201        }
202
203        return page;
204    }
205    
206    /**
207     * A method to wrap the submission of the time details.
208     * @param baseUrl
209     * @param tdaf
210     * @return
211     */
212    public static HtmlPage submitLeaveCalendar2(WebClient webClient, String baseUrl, LeaveCalendarWSForm tdaf) {
213        // For now, until a more HtmlUnit based click method can be found
214        // workable, we're building a url-encoded string to directly
215        // post to the servlet.
216
217        String url = baseUrl + buildPostActionRequested(tdaf);
218        
219        HtmlPage page = null;
220
221        try {
222            page = HtmlUnitUtil.gotoPageAndLogin(webClient, url);
223        } catch (Exception e) {
224            LOG.error("Error while submitting form", e);
225        }
226
227        return page;
228    }
229
230    /**
231     * A method to wrap the submission of the time details.
232     * @param       //baseUrl
233     * @param       //tdaf
234     * @return
235     */
236    /*public static HtmlPage submitTimeDetails(String principalId, String baseUrl, TimeDetailActionFormBase tdaf) {
237        // For now, until a more HtmlUnit based click method can be found
238        // workable, we're building a url-encoded string to directly
239        // post to the servlet.
240
241        String url = baseUrl + buildPostFromFormParams(tdaf);
242        HtmlPage page = null;
243
244        try {
245            TestAutoLoginFilter.OVERRIDE_ID = principalId;
246            page = HtmlUnitUtil.gotoPageAndLogin(url);
247            TestAutoLoginFilter.OVERRIDE_ID = "";
248        } catch (Exception e) {
249            LOG.error("Error while submitting form", e);
250        }
251
252        return page;
253    }*/
254
255    /**
256     * This will build a form post for the addition of leave blocks on the current leave calendar.
257     * @param tdaf
258     * @return
259     */
260    private static String buildPostFromFormParams(LeaveCalendarWSForm tdaf) {
261        StringBuilder builder = new StringBuilder();
262
263        try {
264            builder.append("&methodToCall=").append(URLEncoder.encode(tdaf.getMethodToCall(), "UTF-8"));
265            //builder.append("&acrossDays=").append(URLEncoder.encode(tdaf.getAcrossDays(), "UTF-8"));
266            if (tdaf.getLeaveAmount() != null) {
267                builder.append("&leaveAmount=").append(URLEncoder.encode(tdaf.getLeaveAmount().toString(), "UTF-8"));
268            //} else {
269                //builder.append("&hours=").append(URLEncoder.encode(tdaf.getHours().toString(), "UTF-8"));
270                //builder.append("&startDate=").append(URLEncoder.encode(tdaf.getStartDate(), "UTF-8"));
271                //builder.append("&endDate=").append(URLEncoder.encode(tdaf.getEndDate(), "UTF-8"));
272            }
273            builder.append("&startDate=").append(URLEncoder.encode(tdaf.getStartDate(), "UTF-8"));
274            builder.append("&endDate=").append(URLEncoder.encode(tdaf.getEndDate(), "UTF-8"));
275            builder.append("&selectedAssignment=").append(URLEncoder.encode(tdaf.getSelectedAssignment(), "UTF-8"));
276            builder.append("&selectedEarnCode=").append(URLEncoder.encode(tdaf.getSelectedEarnCode(), "UTF-8"));
277            //if (tdaf.getTkTimeBlockId() != null) {
278            //    builder.append("&tkTimeBlockId=").append(URLEncoder.encode(tdaf.getTkTimeBlockId().toString(), "UTF-8"));
279            //}
280        } catch (Exception e) {
281            LOG.error("Exception building Post String", e);
282        }
283
284        return builder.toString();
285    }
286    
287    private static String buildPostActionRequested(LeaveCalendarWSForm tdaf) {
288        StringBuilder builder = new StringBuilder();
289
290        try {
291                builder.append("&action=").append(URLEncoder.encode(HrConstants.DOCUMENT_ACTIONS.ROUTE,"UTF-8"));
292            builder.append("&methodToCall=").append(URLEncoder.encode(tdaf.getMethodToCall(), "UTF-8"));
293            //add more post params.
294        } catch (Exception e) {
295            LOG.error("Exception building Post String", e);
296        }
297
298        return builder.toString();
299    }
300}