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 */
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.Ignore;
031 import org.junit.Test;
032 import org.kuali.hr.time.util.TimeDetailTestUtils;
033 import org.kuali.hr.time.workflow.TimesheetWebTestBase;
034 import org.kuali.hr.util.HtmlUnitUtil;
035 import org.kuali.kpme.core.FunctionalTest;
036 import org.kuali.kpme.core.assignment.Assignment;
037 import org.kuali.kpme.core.calendar.entry.CalendarEntry;
038 import org.kuali.kpme.core.earncode.EarnCode;
039 import org.kuali.kpme.core.service.HrServiceLocator;
040 import org.kuali.kpme.core.util.TKUtils;
041 import org.kuali.kpme.tklm.time.detail.web.TimeDetailActionFormBase;
042 import org.kuali.kpme.tklm.time.service.TkServiceLocator;
043 import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
044 import org.kuali.rice.krad.util.GlobalVariables;
045
046 import com.gargoylesoftware.htmlunit.WebRequest;
047 import com.gargoylesoftware.htmlunit.WebResponse;
048 import com.gargoylesoftware.htmlunit.html.DomElement;
049 import com.gargoylesoftware.htmlunit.html.HtmlForm;
050 import com.gargoylesoftware.htmlunit.html.HtmlPage;
051
052 /**
053 * See: https://wiki.kuali.org/display/KPME/Role+Security+Grid
054 */
055 @FunctionalTest
056 public 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 }