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 }