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