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 com.gargoylesoftware.htmlunit.WebClient;
019import com.gargoylesoftware.htmlunit.html.HtmlForm;
020import com.gargoylesoftware.htmlunit.html.HtmlPage;
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.api.assignment.Assignment;
026import org.kuali.kpme.core.api.assignment.AssignmentDescriptionKey;
027import org.kuali.kpme.core.api.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 java.math.BigDecimal;
035import java.net.URLEncoder;
036
037public class LeaveCalendarTestUtils {
038
039    private static final Logger LOG = Logger.getLogger(LeaveCalendarTestUtils.class);
040
041    /**
042     * From the provided set of parameters, build an action form suitable for
043     * submitting to the TimeDetailAction servlet. In our case, we are mostly
044     * using it in a mock type of situation, the situation of leave block addition.
045     *
046     * @param leaveCalendarDocument
047     * @param assignment
048     * @param earnCode
049     * @param start
050     * @param end
051     * @param amount
052     *
053     * @return A populated TimeDetailActionFormBase object.
054     */
055    public static LeaveCalendarWSForm buildLeaveCalendarForm(LeaveCalendarDocument leaveCalendarDocument, Assignment assignment, EarnCode earnCode, DateTime start, DateTime end, BigDecimal amount, boolean spanningWeeks) {
056        LeaveCalendarWSForm lcf = new LeaveCalendarWSForm();
057
058        BigDecimal hours = null;
059        String startTimeS = null;
060        String endTimeS = null;
061        String startDateS;
062        String endDateS;
063        String selectedEarnCode;
064        String selectedAssignment;
065
066        if (amount == null) {
067            if (start != null && end != null) {
068                Interval se_i = new Interval(start, end);
069                hours = TKUtils.convertMillisToHours(se_i.toDurationMillis());
070            }
071
072            // the date/time format is defined in tk.calendar.js. For now, the format is 11/17/2010 8:0
073            startTimeS = start.toString("H:mm");
074            endTimeS = end.toString("H:mm");
075        } else {
076            hours = amount;
077        }
078
079        startDateS = start.toString("MM/dd/YYYY");
080        endDateS = end.toString("MM/dd/YYYY");
081
082        AssignmentDescriptionKey adk = new AssignmentDescriptionKey(assignment);
083        selectedAssignment = adk.toAssignmentKeyString();
084
085        selectedEarnCode = earnCode.getEarnCode();
086
087        //lcf.setAcrossDays(acrossDays ? "y" : "n");
088
089        lcf.setSpanningWeeks(spanningWeeks ? "y" : "n"); // KPME-1446
090
091        lcf.setLeaveAmount(hours);
092        //lcf.setHours(hours);
093        lcf.setStartDate(startDateS);
094        lcf.setEndDate(endDateS);
095        //lcf.setTkTimeBlockId(timeblockId);
096        lcf.setLeaveCalendarDocument(leaveCalendarDocument);
097        lcf.setSelectedAssignment(selectedAssignment);
098        lcf.setSelectedEarnCode(selectedEarnCode);
099        lcf.setMethodToCall("addLeaveBlock");
100
101        return lcf;
102    }
103    
104    /**
105     * Builds a simple "mock" leave calendar form primed for action "approveLeaveCalendar".
106     * Suitable for testing logic LeaveCalendarSubmitAction actions.
107     *
108     * @param leaveCalendarDocument
109     * @param assignment
110     * @param earnCode
111     * @param start
112     * @param end
113     * @param amount
114     *
115     * @return A populated TimeDetailActionFormBase object.
116     */
117    public static LeaveCalendarWSForm buildLeaveCalendarFormForSubmission(LeaveCalendarDocument leaveCalendarDocument, LeaveSummary leaveSummary) {
118        LeaveCalendarWSForm lcf = new LeaveCalendarWSForm();
119
120        lcf.setMethodToCall("approveLeaveCalendar");
121        lcf.setLeaveSummary(leaveSummary);
122
123        return lcf;
124    }
125    
126
127    /**
128     * Set the attributes on the provided html form to the values found in the provided
129     * ActionForm. Returns void, not a List<String> of errors.
130     *
131     * @param form The HtmlForm to populate.
132     * @param tdaf The ActionForm with values we will use to populate.
133     */
134    public static void setTimeBlockFormDetails(HtmlForm form, LeaveCalendarWSForm tdaf) {
135        //if (tdaf.getLeaveBlockId() != null) {
136        //    form.setAttribute("leaveBlockId", tdaf.getLeaveBlockId().toString());
137        //}
138        form.setAttribute("startDate", tdaf.getStartDate());
139        form.setAttribute("endDate", tdaf.getEndDate());
140
141        if (tdaf.getLeaveAmount() != null) {
142            form.setAttribute("leaveAmount", tdaf.getLeaveAmount().toString());
143        }
144
145        form.setAttribute("selectedEarnCode", tdaf.getSelectedEarnCode());
146        form.setAttribute("selectedAssignment", tdaf.getSelectedAssignment());
147        //form.setAttribute("acrossDays", tdaf.getAcrossDays());
148        form.setAttribute("methodToCall", tdaf.getMethodToCall());
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 submitLeaveCalendar(WebClient webClient, String baseUrl, LeaveCalendarWSForm 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 submitLeaveCalendar2(WebClient webClient, String baseUrl, LeaveCalendarWSForm 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 + buildPostActionRequested(tdaf);
217        
218        HtmlPage page = null;
219
220        try {
221            page = HtmlUnitUtil.gotoPageAndLogin(webClient, url);
222        } catch (Exception e) {
223            LOG.error("Error while submitting form", e);
224        }
225
226        return page;
227    }
228
229    /**
230     * A method to wrap the submission of the time details.
231     * @param       //baseUrl
232     * @param       //tdaf
233     * @return
234     */
235    /*public static HtmlPage submitTimeDetails(String principalId, String baseUrl, TimeDetailActionFormBase tdaf) {
236        // For now, until a more HtmlUnit based click method can be found
237        // workable, we're building a url-encoded string to directly
238        // post to the servlet.
239
240        String url = baseUrl + buildPostFromFormParams(tdaf);
241        HtmlPage page = null;
242
243        try {
244            TestAutoLoginFilter.OVERRIDE_ID = principalId;
245            page = HtmlUnitUtil.gotoPageAndLogin(url);
246            TestAutoLoginFilter.OVERRIDE_ID = "";
247        } catch (Exception e) {
248            LOG.error("Error while submitting form", e);
249        }
250
251        return page;
252    }*/
253
254    /**
255     * This will build a form post for the addition of leave blocks on the current leave calendar.
256     * @param tdaf
257     * @return
258     */
259    private static String buildPostFromFormParams(LeaveCalendarWSForm tdaf) {
260        StringBuilder builder = new StringBuilder();
261
262        try {
263            builder.append("&methodToCall=").append(URLEncoder.encode(tdaf.getMethodToCall(), "UTF-8"));
264            //builder.append("&acrossDays=").append(URLEncoder.encode(tdaf.getAcrossDays(), "UTF-8"));
265            if (tdaf.getLeaveAmount() != null) {
266                builder.append("&leaveAmount=").append(URLEncoder.encode(tdaf.getLeaveAmount().toString(), "UTF-8"));
267            //} else {
268                //builder.append("&hours=").append(URLEncoder.encode(tdaf.getHours().toString(), "UTF-8"));
269                //builder.append("&startDate=").append(URLEncoder.encode(tdaf.getStartDate(), "UTF-8"));
270                //builder.append("&endDate=").append(URLEncoder.encode(tdaf.getEndDate(), "UTF-8"));
271            }
272            builder.append("&startDate=").append(URLEncoder.encode(tdaf.getStartDate(), "UTF-8"));
273            builder.append("&endDate=").append(URLEncoder.encode(tdaf.getEndDate(), "UTF-8"));
274            builder.append("&selectedAssignment=").append(URLEncoder.encode(tdaf.getSelectedAssignment(), "UTF-8"));
275            builder.append("&selectedEarnCode=").append(URLEncoder.encode(tdaf.getSelectedEarnCode(), "UTF-8"));
276            //if (tdaf.getTkTimeBlockId() != null) {
277            //    builder.append("&tkTimeBlockId=").append(URLEncoder.encode(tdaf.getTkTimeBlockId().toString(), "UTF-8"));
278            //}
279        } catch (Exception e) {
280            LOG.error("Exception building Post String", e);
281        }
282
283        return builder.toString();
284    }
285    
286    private static String buildPostActionRequested(LeaveCalendarWSForm tdaf) {
287        StringBuilder builder = new StringBuilder();
288
289        try {
290                builder.append("&action=").append(URLEncoder.encode(HrConstants.DOCUMENT_ACTIONS.ROUTE,"UTF-8"));
291            builder.append("&methodToCall=").append(URLEncoder.encode(tdaf.getMethodToCall(), "UTF-8"));
292            //add more post params.
293        } catch (Exception e) {
294            LOG.error("Exception building Post String", e);
295        }
296
297        return builder.toString();
298    }
299}