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 }