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