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.lm.leaveCalendar;
017
018 import static org.junit.Assert.assertTrue;
019
020 import com.gargoylesoftware.htmlunit.html.HtmlButtonInput;
021 import com.gargoylesoftware.htmlunit.html.HtmlElement;
022 import com.gargoylesoftware.htmlunit.html.HtmlForm;
023 import com.gargoylesoftware.htmlunit.html.HtmlPage;
024 import org.apache.commons.lang.StringUtils;
025 import org.joda.time.DateTime;
026 import org.json.simple.JSONArray;
027 import org.json.simple.JSONObject;
028 import org.json.simple.JSONValue;
029 import org.junit.Assert;
030 import org.junit.Ignore;
031 import org.junit.Test;
032 import org.kuali.hr.lm.leave.web.LeaveCalendarWSForm;
033 import org.kuali.hr.lm.leaveSummary.LeaveSummary;
034 import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
035 import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
036 import org.kuali.hr.lm.util.LeaveCalendarTestUtils;
037 import org.kuali.hr.time.assignment.Assignment;
038 import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
039 import org.kuali.hr.time.calendar.CalendarEntries;
040 import org.kuali.hr.time.earncode.EarnCode;
041 import org.kuali.hr.time.service.base.TkServiceLocator;
042 import org.kuali.hr.time.test.HtmlUnitUtil;
043 import org.kuali.hr.time.test.TkTestConstants;
044 import org.kuali.hr.time.test.TkTestUtils;
045 import org.kuali.hr.time.util.TKContext;
046 import org.kuali.hr.time.util.TKUtils;
047 import org.kuali.hr.util.filter.TestAutoLoginFilter;
048 import org.kuali.rice.kew.api.exception.WorkflowException;
049
050 import java.math.BigDecimal;
051 import java.sql.Date;
052 import java.util.ArrayList;
053 import java.util.HashMap;
054 import java.util.List;
055 import java.util.Map;
056
057 public class LeaveCalendarWorkflowIntegrationTest extends LeaveCalendarWebTestBase {
058
059 public static final String USER_PRINCIPAL_ID = "admin";
060 private Date JAN_AS_OF_DATE = new Date((new DateTime(2010, 1, 1, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone())).getMillis());
061
062 @Ignore
063 @Test
064 /**
065 * - create timesheet
066 * - add two 8 hour time blocks
067 * - submit timesheet for routing
068 * - ## login as approver
069 * - look for approval button
070 * - approve timeblock
071 * - verify approval button gone
072 * - ## login as original user
073 * - verify submit for routing button gone
074 */
075 public void testLeaveCalendarSubmissionIntegration() throws Exception {
076 Date asOfDate = new Date((new DateTime(2011, 3, 1, 12, 0, 0, 0, TKUtils.getSystemDateTimeZone())).getMillis());
077 CalendarEntries pcd = TkServiceLocator.getCalendarService().getCurrentCalendarDatesForLeaveCalendar(USER_PRINCIPAL_ID, asOfDate);
078 Assert.assertNotNull("No CalendarEntries", pcd);
079 LeaveCalendarDocument tdoc = TkServiceLocator.getLeaveCalendarService().openLeaveCalendarDocument(USER_PRINCIPAL_ID, pcd);
080 String tdocId = tdoc.getDocumentId();
081 HtmlPage page = loginAndGetLeaveCalendarHtmlPage("admin", tdocId, true);
082
083 // 1. Obtain User Data
084 Assignment assignment = TkServiceLocator.getAssignmentService().getAssignment(TKContext.getPrincipalId(), new AssignmentDescriptionKey("30_30_30"), JAN_AS_OF_DATE);
085 EarnCode earnCode = TkServiceLocator.getEarnCodeService().getEarnCode("VAC", JAN_AS_OF_DATE);
086
087 // 2. Set Timeblock Start and End time
088 // 3/02/2011 - 8:00a to 4:00pm
089 DateTime start = new DateTime(2011, 3, 2, 8, 0, 0, 0, TKUtils.getSystemDateTimeZone());
090 DateTime end = new DateTime(2011, 3, 2, 16, 0, 0, 0, TKUtils.getSystemDateTimeZone());
091
092 HtmlForm form = page.getFormByName("LeaveCalendarForm");
093 Assert.assertNotNull(form);
094
095 // Build an action form - we're using it as a POJO, it ties into the
096 // existing TK validation setup
097 LeaveCalendarWSForm tdaf = LeaveCalendarTestUtils.buildLeaveCalendarForm(tdoc, assignment, earnCode, start, end, null, true);
098 LeaveCalendarTestUtils.setTimeBlockFormDetails(form, tdaf);
099 page = LeaveCalendarTestUtils.submitLeaveCalendar(getWebClient(), getLeaveCalendarUrl(tdocId), tdaf);
100 Assert.assertNotNull(page);
101 HtmlUnitUtil.createTempFile(page, "LeaveBlockPresent");
102
103 // Verify block present on rendered page.
104 String pageAsText = page.asText();
105
106 // JSON
107 //
108 //
109 // Grab the leaveBlock data from the text area. We can check specifics there
110 // to be more fine grained in our validation.
111 String dataText = page.getElementById("leaveBlockString").getFirstChild().getNodeValue();
112 JSONArray jsonData = (JSONArray)JSONValue.parse(dataText);
113 final JSONObject jsonDataObject = (JSONObject) jsonData.get(0);
114 Assert.assertTrue("leaveBlock Data Missing.", checkJSONValues(new JSONObject() {{ put("outer", jsonDataObject); }},
115 new ArrayList<Map<String, Object>>() {{
116 add(new HashMap<String, Object>() {{
117 put("earnCode", "VAC");
118 put("leaveAmount", "-8");
119 put("earnCode", "VAC");
120 put("leaveDate", "03/02/2011");
121 //put("endNoTz", "2011-03-02T16:00:00");
122 put("title", "SDR1 Work Area");
123 put("assignment", "30_30_30");
124 }});
125 }},
126 new HashMap<String, Object>() {{ }}
127 ));
128
129 // Check the Display Rendered Text for Time Block, Quick Check
130 Assert.assertTrue("TimeBlock not Present.", pageAsText.contains("SDR1 Work Area-SDR1 task"));
131 Assert.assertTrue("TimeBlock not Present.", pageAsText.contains("VAC (-8)"));
132
133 //
134 // Route Timesheet
135 //
136 // Routing is initiated via javascript, we need to extract the routing
137 // action from the button element to perform this action.
138 HtmlButtonInput routeButton = (HtmlButtonInput)page.getElementById("ts-route-button");
139 String routeHref = TkTestUtils.getOnClickHref(routeButton);
140 // The 'only' way to do the button click.
141 page = HtmlUnitUtil.gotoPageAndLogin(getWebClient(), TkTestConstants.BASE_URL + "/" + routeHref);
142 //HtmlUnitUtil.createTempFile(page, "RouteClicked");
143 pageAsText = page.asText();
144 // Verify Route Status via UI
145 Assert.assertTrue("Wrong Document Loaded.", pageAsText.contains(tdocId));
146 Assert.assertTrue("Document not routed.", pageAsText.contains("Enroute"));
147 routeButton = (HtmlButtonInput)page.getElementById("ts-route-button");
148 Assert.assertNull("Route button should not be present.", routeButton);
149 HtmlElement approveButton = (HtmlButtonInput)page.getElementById("ts-approve-button");
150 Assert.assertNull("Approval button should not be present.", approveButton);
151
152 //
153 // Login as Approver, who is not 'admin'
154 page = loginAndGetLeaveCalendarHtmlPage("eric", tdocId, true);
155 //HtmlUnitUtil.createTempFile(page, "2ndLogin");
156 pageAsText = page.asText();
157 Assert.assertTrue("Document not routed.", pageAsText.contains("Enroute"));
158 approveButton = (HtmlButtonInput)page.getElementById("ts-approve-button");
159 Assert.assertNotNull("No approval button present.", approveButton);
160
161 // Click Approve
162 // And Verify
163 //
164 routeHref = TkTestUtils.getOnClickHref(approveButton);
165 TestAutoLoginFilter.OVERRIDE_ID = "eric";
166 page = HtmlUnitUtil.gotoPageAndLogin(getWebClient(), TkTestConstants.BASE_URL + "/" + routeHref);
167 TestAutoLoginFilter.OVERRIDE_ID = "";
168 //HtmlUnitUtil.createTempFile(page, "ApproveClicked");
169 pageAsText = page.asText();
170 Assert.assertTrue("Wrong Document Loaded.", pageAsText.contains(tdocId));
171 Assert.assertTrue("Login info not present.", pageAsText.contains("Employee Id:"));
172 Assert.assertTrue("Login info not present.", pageAsText.contains("eric, eric"));
173 Assert.assertTrue("Document not routed.", pageAsText.contains("Final"));
174 approveButton = (HtmlElement)page.getElementById("ts-approve-button");
175 Assert.assertNull("Approval button should not be present.", approveButton);
176 }
177
178 @Ignore
179 @Test
180 public void testRedirectionForBalanceTransferOnLeaveApprove() throws Exception {
181 //Create a leave summary with a single row containing an accrual category that has exceeded max balance limit.
182 /* LeaveSummary ls = new LeaveSummary();
183 List<LeaveSummaryRow> leaveSummaryRows = new ArrayList<LeaveSummaryRow>();
184 //A leave summary row for an accrual category over max balance.
185 LeaveSummaryRow lsr = new LeaveSummaryRow();
186 lsr.setAccrualCategory("debitAC1");
187 lsr.setAccrualCategoryId("10055");
188 lsr.setAccrualCategoryRuleId("3000");
189 lsr.setLeaveBalance(new BigDecimal(500));
190 //debitAC1 accrual category has a max balance of 100.
191 leaveSummaryRows.add(lsr);
192 //A leave summary row for an accrual category to accept transfers.
193 lsr = new LeaveSummaryRow();
194 lsr.setAccrualCategory("creditAC1");
195 lsr.setAccrualCategoryId("10056");
196 lsr.setAccrualCategoryRuleId("3001");
197 lsr.setLeaveBalance(BigDecimal.ZERO);
198
199 leaveSummaryRows.add(lsr);
200 ls.setLeaveSummaryRows(leaveSummaryRows);
201 setBaseDetailURL(TkTestConstants.Urls.LEAVE_CALENDAR_SUBMIT_URL + "?documentId=");
202 Date asOfDate = new Date((new DateTime(2011, 3, 1, 12, 0, 0, 0, TKUtils.getSystemDateTimeZone())).getMillis());
203 CalendarEntries pcd = TkServiceLocator.getCalendarService().getCurrentCalendarDatesForLeaveCalendar(USER_PRINCIPAL_ID, asOfDate);
204 Assert.assertNotNull("No CalendarEntries", pcd);
205 LeaveCalendarDocument tdoc = TkServiceLocator.getLeaveCalendarService().openLeaveCalendarDocument(USER_PRINCIPAL_ID, pcd);
206 String tdocId = tdoc.getDocumentId();
207
208 // Build an action form - we're using it as a POJO, it ties into the
209 // existing TK validation setup
210 LeaveCalendarWSForm tdaf = LeaveCalendarTestUtils.buildLeaveCalendarFormForSubmission(tdoc, ls);
211
212 HtmlPage page = LeaveCalendarTestUtils.submitLeaveCalendar2(getLeaveCalendarUrl(tdocId), tdaf);
213 Assert.assertNotNull(page);
214 HtmlUnitUtil.createTempFile(page, "LeaveBlockPresent");
215
216 // Verify block present on rendered page.
217 String pageAsText = page.asText();
218 System.out.print(pageAsText);
219
220 */
221 //LeaveCalendarWSForm mockForm = LeaveCalendarTestUtils.buildLeaveCalendarForm(tdoc, assignment, earnCode, start, end, null, true);
222 //Attach leave summary to relevant object (leavecalendardocument?)
223 //load LeaveCalendarDocument into web container
224 //leave calendar document must have status "initiated"
225 //mock the submit action on behalf of the principal who owns the leave calendar.
226 //redirect should occur, which loads the balance transfer document.
227 //balance transfer document should have all fields locked except for transfer amount.
228 //mock transfer action on behalf of the principal.
229 //verify leave block creation
230 assertTrue("Dummy assertion 2", true);
231
232 }
233
234
235 /**
236 * Examines the JSON structure that is written to each output TimeDetails
237 * page.
238 * @param json The JSON Object to examine
239 * @param thdList The (optional) list of Time Hour Details values
240 * @param checkValues The list of values to check for in the JSON object
241 * @return true if the JSON object contains the required values, false otherwise.
242 */
243 public static boolean checkJSONValues(JSONObject json, List<Map<String,Object>> thdList, Map<String,Object> checkValues) {
244 boolean contains = false;
245
246 for(Object eso : json.entrySet()) {
247 // This is the outer TimeBlock ID -> Time Block Data mapping
248 Map.Entry e = (Map.Entry)eso;
249 JSONObject innerMap = (JSONObject)e.getValue(); // the values we actually care about.
250 boolean localContains = true;
251 for (Map.Entry<String,Object> cve : checkValues.entrySet()) {
252 Object joValue = innerMap.get(cve.getKey());
253 Object cvValue = cve.getValue();
254
255 // Null Checks..
256 if (cvValue == null && joValue == null)
257 localContains &= true;
258 else if (joValue == null || cvValue == null)
259 localContains = false;
260 else
261 localContains &= StringUtils.equals(joValue.toString(), cvValue.toString());
262 }
263
264 contains |= localContains;
265 }
266
267 return contains;
268 }
269
270 public static boolean checkJSONValues(String json, List<Map<String,Object>> thdList, Map<String,Object> checkValues) {
271 return checkJSONValues((JSONObject)JSONValue.parse(json), thdList, checkValues);
272 }
273 }