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 }