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.time.roles.web; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.log4j.Logger; 024import org.joda.time.DateTime; 025import org.joda.time.DateTimeZone; 026import org.json.simple.JSONArray; 027import org.json.simple.JSONObject; 028import org.json.simple.JSONValue; 029import org.junit.Assert; 030import org.junit.Ignore; 031import org.junit.Test; 032import org.kuali.hr.time.util.TimeDetailTestUtils; 033import org.kuali.hr.time.workflow.TimesheetWebTestBase; 034import org.kuali.hr.util.HtmlUnitUtil; 035import org.kuali.kpme.core.FunctionalTest; 036import org.kuali.kpme.core.assignment.Assignment; 037import org.kuali.kpme.core.calendar.entry.CalendarEntry; 038import org.kuali.kpme.core.earncode.EarnCode; 039import org.kuali.kpme.core.service.HrServiceLocator; 040import org.kuali.kpme.core.util.TKUtils; 041import org.kuali.kpme.tklm.time.detail.web.TimeDetailActionFormBase; 042import org.kuali.kpme.tklm.time.service.TkServiceLocator; 043import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument; 044import org.kuali.rice.krad.util.GlobalVariables; 045 046import com.gargoylesoftware.htmlunit.WebRequest; 047import com.gargoylesoftware.htmlunit.WebResponse; 048import com.gargoylesoftware.htmlunit.html.DomElement; 049import com.gargoylesoftware.htmlunit.html.HtmlForm; 050import com.gargoylesoftware.htmlunit.html.HtmlPage; 051 052/** 053 * See: https://wiki.kuali.org/display/KPME/Role+Security+Grid 054 */ 055@FunctionalTest 056public class RoleTimesheetWebIntegrationTest extends TimesheetWebTestBase { 057 058 private static final Logger LOG = Logger.getLogger(RoleTimesheetWebIntegrationTest.class); 059 060 // Non Time Entry users (for this test) who have some access to 'fred's' 061 // Time Sheet. 062 private List<String> VALID_NON_ENTRY_USERS = new ArrayList<String>() {{ 063 //add fred too. 064 /*add("testuser6");*/ add("frank"); add("fran"); add("edna"); add("fred"); }}; 065 066 // Users with incorrect Department or Work Area for Time Sheet privilege. 067 private List<String> INVALID_NON_ENTRY_USERS = new ArrayList<String>(){{ 068 add("testuser1"); add("testuser2"); add("testuser3"); add("testuser4"); }}; 069 070 private TimesheetDocument fredsDocument = null; 071 DateTime asOfDate = new DateTime(2011, 3, 1, 12, 0, 0, 0, TKUtils.getSystemDateTimeZone()); 072 073 @Override 074 /** 075 * This code is called before each test below - allows us to control how far 076 * into the routing process we are for any given level of testing. 077 */ 078 public void setUp() throws Exception { 079 super.setUp(); 080 081 String userId = "fred"; 082 DateTimeZone dateTimeZone = DateTimeZone.forID(HrServiceLocator.getTimezoneService().getUserTimezone(userId)); 083 084 CalendarEntry pcd = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates(userId, asOfDate); 085 Assert.assertNotNull("No PayCalendarDates", pcd); 086 fredsDocument = TkServiceLocator.getTimesheetService().openTimesheetDocument(userId, pcd); 087 String tdocId = fredsDocument.getDocumentId(); 088 089 // Verify the non time entry logins. 090 verifyLogins(fredsDocument); 091 092 // Verify Fred, and Add Timeblocks 093 HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true); 094 Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011")); 095 096 HtmlForm form = page.getFormByName("TimeDetailActionForm"); 097 Assert.assertNotNull(form); 098 List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAssignments(userId, JAN_AS_OF_DATE.toLocalDate()); 099 Assignment assignment = assignments.get(0); 100 101 List<EarnCode> earnCodes = TkServiceLocator.getTimesheetService().getEarnCodesForTime(assignment, JAN_AS_OF_DATE.toLocalDate()); 102 EarnCode earnCode = earnCodes.get(0); 103 Assert.assertEquals("There should be no existing time blocks.", 0, fredsDocument.getTimeBlocks().size()); 104 105 // 2. Set Timeblock Start and End time 106 // 3/02/2011 - 8:00a to 6:00pm 107 // OVT - 0 Hrs Expected 108 final DateTime start = new DateTime(2011, 3, 2, 8, 0, 0, 0, dateTimeZone); 109 final DateTime end = new DateTime(2011, 3, 2, 13, 0, 0, 0, dateTimeZone); 110 111 TimeDetailActionFormBase tdaf = TimeDetailTestUtils.buildDetailActionForm(fredsDocument, assignment, earnCode, start, end, null, false, null, true); 112 List<String> errors = TimeDetailTestUtils.setTimeBlockFormDetails(form, tdaf); 113 114 Assert.assertEquals("There should be no errors in this time detail submission", 0, errors.size()); 115 page = TimeDetailTestUtils.submitTimeDetails(getWebClient(), getTimesheetDocumentUrl(tdocId), tdaf); 116 Assert.assertNotNull(page); 117 page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true); 118 119 String pageAsText = page.asText(); 120 DomElement element = page.getElementById("timeBlockString"); 121 Assert.assertNotNull(element); 122 String elementAsText = element.asText(); 123 String dataText = page.getElementById("timeBlockString").getFirstChild().getNodeValue(); 124 JSONArray jsonData = (JSONArray) JSONValue.parse(dataText); 125 final JSONObject jsonDataObject = (JSONObject) jsonData.get(0); 126 Assert.assertTrue("TimeBlock Data Missing.", checkJSONValues(new JSONObject() {{ put("outer", jsonDataObject); }}, 127 new ArrayList<Map<String, Object>>() {{ 128 add(new HashMap<String, Object>() {{ 129 put("earnCode", "RGN"); 130 put("hours", "5.0"); 131 put("amount", null); 132 }}); 133 }}, 134 new HashMap<String, Object>() {{ 135 put("earnCode", "RGN"); 136 start.toString(); 137 put("startNoTz", start.toString("yyyy-MM-dd'T'HH:mm:ss")); 138 put("endNoTz", end.toString("yyyy-MM-dd'T'HH:mm:ss")); 139 put("title", "SDR1 Work Area"); 140 put("assignment", "30_30_30"); 141 }} 142 )); 143 144 // Set freds timesheet to have updated info. 145 fredsDocument = TkServiceLocator.getTimesheetService().openTimesheetDocument(userId, pcd); 146 } 147 148 /* 149 * Tests while Timesheet is in INITIATED state. 150 */ 151 152 @Test 153 public void testInitiatedTimesheetIsVisibleByAll() throws Exception { 154 // test valid users 155 for (String uid : VALID_NON_ENTRY_USERS) { 156 LOG.info("Testing visibility for " + uid); 157 HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), uid, fredsDocument.getDocumentId(), true); 158 Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011")); 159 } 160 } 161 162 @Test 163 //@Ignore 164 public void testInitiatedTimesheetIsNotVisible() throws Exception { 165 for (String uid : INVALID_NON_ENTRY_USERS) { 166 LOG.info("Testing visibility for " + uid); 167 HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), uid, fredsDocument.getDocumentId(), false); 168 //HtmlUnitUtil.createTempFile(page, "badlogin"); 169 Assert.assertTrue(uid + " should not have access" , page.asText().contains("You are not authorized to access this portion of the application.")); 170 } 171 } 172 173 public void testInitiatedTimesheetEditable(String userId) throws Exception { 174 // admin, add one timeblock 175 String tdocId = fredsDocument.getDocumentId(); 176 HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true); 177 LOG.debug(page.asText()); 178 //HtmlUnitUtil.createTempFile(page, "loggedin"); 179 Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011")); 180 181 HtmlForm form = page.getFormByName("TimeDetailActionForm"); 182 Assert.assertNotNull(form); 183 List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAssignments("fred", JAN_AS_OF_DATE.toLocalDate()); 184 Assignment assignment = assignments.get(0); 185 186 List<EarnCode> earnCodes = TkServiceLocator.getTimesheetService().getEarnCodesForTime(assignment, JAN_AS_OF_DATE.toLocalDate()); 187 EarnCode earnCode = earnCodes.get(0); 188 189 Assert.assertEquals("There should be one existing time block.", 1, fredsDocument.getTimeBlocks().size()); 190 191 DateTimeZone dateTimeZone = DateTimeZone.forID(HrServiceLocator.getTimezoneService().getUserTimezone(userId)); 192 final DateTime start = new DateTime(2011, 3, 2, 13, 0, 0, 0, dateTimeZone); 193 final DateTime end = new DateTime(2011, 3, 2, 18, 0, 0, 0, dateTimeZone); 194 TimeDetailActionFormBase tdaf = TimeDetailTestUtils.buildDetailActionForm(fredsDocument, assignment, earnCode, start, end, null, false, null, true); 195 196 List<String> errors = TimeDetailTestUtils.setTimeBlockFormDetails(form, tdaf); 197 Assert.assertEquals("There should be no errors in this time detail submission", 0, errors.size()); 198 String targetedTimesheetUrl = getTargetedTimesheetDocumentUrl(tdocId,"fred"); 199 page = getWebClient().getPage(targetedTimesheetUrl); 200 Assert.assertNotNull(page); 201 String submitDetailsUrl = BASE_DETAIL_URL + tdocId; 202 //The following page does not contain timeBlockString data after KPME-2959. 203 page = TimeDetailTestUtils.submitTimeDetails(getWebClient(), submitDetailsUrl, tdaf); 204 Assert.assertNotNull(page); 205 //This extra page get was needed for KPME-2959. 206 page = getWebClient().getPage(targetedTimesheetUrl); 207 HtmlUnitUtil.createTempFile(page, "initiatetest"); 208 String dataText = page.getElementById("timeBlockString").getFirstChild().getNodeValue(); 209 JSONArray jsonData = (JSONArray) JSONValue.parse(dataText); 210 final JSONObject jsonDataObject = (JSONObject) jsonData.get(1); 211 Assert.assertTrue("TimeBlock Data Missing.", checkJSONValues(new JSONObject() {{ put("outer", jsonDataObject); }}, 212 new ArrayList<Map<String, Object>>() {{ 213 add(new HashMap<String, Object>() {{ 214 put("earnCode", "RGN"); 215 put("hours", "5.0"); 216 put("amount", null); 217 }}); 218 }}, 219 new HashMap<String, Object>() {{ 220 put("earnCode", "RGN"); 221 put("startNoTz", start.toString("yyyy-MM-dd'T'HH:mm:ss")); 222 put("endNoTz", end.toString("yyyy-MM-dd'T'HH:mm:ss")); 223 put("title", "SDR1 Work Area"); 224 put("assignment", "30_30_30"); 225 }} 226 )); 227 } 228 229 public void testInitiatedTimesheetNotEditable(String userId) throws Exception { 230 // admin, add one timeblock 231 String tdocId = fredsDocument.getDocumentId(); 232 HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true); 233 //HtmlUnitUtil.createTempFile(page, "loggedin"); 234 Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011")); 235 236 HtmlForm form = page.getFormByName("TimeDetailActionForm"); 237 Assert.assertNotNull(form); 238 List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAssignments("fred", JAN_AS_OF_DATE.toLocalDate()); 239 Assignment assignment = assignments.get(0); 240 241 List<EarnCode> earnCodes = TkServiceLocator.getTimesheetService().getEarnCodesForTime(assignment, JAN_AS_OF_DATE.toLocalDate()); 242 EarnCode earnCode = earnCodes.get(0); 243 244 Assert.assertEquals("There should be one existing time block.", 1, fredsDocument.getTimeBlocks().size()); 245 246 DateTimeZone dateTimeZone = DateTimeZone.forID(HrServiceLocator.getTimezoneService().getUserTimezone(userId)); 247 DateTime start = new DateTime(2011, 3, 4, 8, 0, 0, 0, dateTimeZone); 248 DateTime end = new DateTime(2011, 3, 4, 13, 0, 0, 0, dateTimeZone); 249 TimeDetailActionFormBase tdaf = TimeDetailTestUtils.buildDetailActionForm(fredsDocument, assignment, earnCode, start, end, null, false, null, true); 250 List<String> errors = TimeDetailTestUtils.setTimeBlockFormDetails(form, tdaf); 251 Assert.assertEquals("There should be no errors in this time detail submission", 0, errors.size()); 252 page = TimeDetailTestUtils.submitTimeDetails(getWebClient(), userId, getTimesheetDocumentUrl(tdocId), tdaf); 253 Assert.assertNotNull(page); 254 HtmlUnitUtil.createTempFile(page, "aftertdadd"); 255 Assert.assertTrue("Should not have access", page.asText().contains("You are not authorized to access this portion of the application.")); 256 } 257 258 @Test 259 public void testInitiatedTimesheetIsEditableByAdmin() throws Exception { 260 testInitiatedTimesheetEditable("admin"); 261 } 262 263 @Test 264 public void testInitiatedTimesheetIsEditableByApprover() throws Exception { 265 testInitiatedTimesheetEditable("fran"); 266 } 267 268 @Test 269 public void testInitiatedTimesheetIsEditableByReviewer() throws Exception { 270 testInitiatedTimesheetEditable("frank"); 271 } 272 273 @Test 274 public void testInitiatedTimesheetIs_NOT_EditableByViewOnly() throws Exception { 275 testInitiatedTimesheetNotEditable("edna"); 276 } 277 278 @Test 279 public void testInitiatedTimesheetIs_NOT_EditableByDeptAdmin() throws Exception { 280 testInitiatedTimesheetNotEditable("testuser6"); 281 } 282 283 284 @Test 285 public void testInitiatedTimesheetSubmitUser() throws Exception { 286 // User, 287 // Check for submit button. 288 // Click Button 289 } 290 291 @Test 292 public void testInitiatedTimesheetSubmitAdmin() throws Exception { 293 // Admin 294 // Check for submit button. 295 // Click Button 296 } 297 298 @Test 299 public void testInitiatedTimesheetSubmitApprover() throws Exception { 300 // Approver 301 // Check for submit button. 302 // Click Button 303 } 304 305 306 @Test 307 public void testInitiatedTimesheetIs_NOT_SubmittableByUsers() throws Exception { 308 // DeptAdmin, View Only, Reviewer 309 // Check that submit button is not present. 310 } 311 312 /* 313 * Test for ENROUTE state. 314 */ 315 316 @Test 317 public void testEnrouteTimesheetIsVisibleByAll() throws Exception { 318 // test valid users 319 } 320 321 @Test 322 public void testEnrouteTimesheetIsNotVisible() throws Exception { 323 // make sure invalid users do not have access 324 } 325 326 @Test 327 public void testEnrouteTimesheetIsEditableByAdmin() throws Exception { 328 // admin, add one timeblock 329 } 330 331 @Test 332 public void testEnrouteTimesheetIsEditableByApprover() throws Exception { 333 // approver, add one timeblock 334 } 335 336 @Test 337 public void testEnrouteTimesheetIsEditableByReviewer() throws Exception { 338 // reviewer add one timeblock. 339 } 340 341 @Test 342 public void testEnrouteTimesheetIs_NOT_EditableByViewOnly() throws Exception { 343 } 344 345 @Test 346 public void testEnrouteTimesheetIs_NOT_EditableByDeptAdmin() throws Exception { 347 } 348 349 350 @Test 351 public void testEnrouteTimesheet_NOT_Approvable() throws Exception { 352 // User, Reviewer, View Only, Dept Admin 353 // Check for approve button 354 } 355 356 @Test 357 public void testEnrouteTimesheetApproveAdmin() throws Exception { 358 // Admin 359 // Check for approve button. 360 // Click Button 361 } 362 363 @Test 364 public void testEnrouteTimesheetApproveApprover() throws Exception { 365 // Approver 366 // Check for approve button. 367 // Click Button 368 } 369 370 @Test 371 public void testEnrouteTimesheetIs_NOT_SubmittableByUsers() throws Exception { 372 // DeptAdmin, View Only, Reviewer 373 // Check that submit button is not present. 374 } 375 376 377 /* 378 * Final State 379 */ 380 381 @Test 382 public void testFinalTimesheetIsVisibleByAll() throws Exception { 383 // test valid users 384 } 385 386 @Test 387 public void testFinalTimesheetIsNotVisible() throws Exception { 388 // make sure invalid users do not have access 389 } 390 391 @Test 392 public void testFinalTimesheetIsNotEditable() throws Exception { 393 // by everyone but admin 394 } 395 396 @Test 397 public void testFinalTimesheetIsAdminEditable() throws Exception { 398 // admin, add timeblock. 399 } 400 401 /** 402 * Verifies that each admin/approver/reviewer login is active for this test. 403 */ 404 private void verifyLogins(TimesheetDocument tdoc) throws Exception { 405 for (String userId : VALID_NON_ENTRY_USERS) { 406 String tdocId = tdoc.getDocumentId(); 407 HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true); 408 Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011")); 409 } 410 } 411 412}