View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.time.roles.web;
17  
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.List;
21  import java.util.Map;
22  
23  import org.apache.log4j.Logger;
24  import org.joda.time.DateTime;
25  import org.joda.time.DateTimeZone;
26  import org.json.simple.JSONArray;
27  import org.json.simple.JSONObject;
28  import org.json.simple.JSONValue;
29  import org.junit.Assert;
30  import org.junit.Test;
31  import org.kuali.hr.time.util.TimeDetailTestUtils;
32  import org.kuali.hr.time.workflow.TimesheetWebTestBase;
33  import org.kuali.hr.util.HtmlUnitUtil;
34  import org.kuali.kpme.core.FunctionalTest;
35  import org.kuali.kpme.core.assignment.Assignment;
36  import org.kuali.kpme.core.calendar.entry.CalendarEntry;
37  import org.kuali.kpme.core.earncode.EarnCode;
38  import org.kuali.kpme.core.service.HrServiceLocator;
39  import org.kuali.kpme.core.util.TKUtils;
40  import org.kuali.kpme.tklm.time.detail.web.TimeDetailActionFormBase;
41  import org.kuali.kpme.tklm.time.service.TkServiceLocator;
42  import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
43  import org.kuali.rice.krad.util.GlobalVariables;
44  
45  import com.gargoylesoftware.htmlunit.WebRequest;
46  import com.gargoylesoftware.htmlunit.WebResponse;
47  import com.gargoylesoftware.htmlunit.html.DomElement;
48  import com.gargoylesoftware.htmlunit.html.HtmlForm;
49  import com.gargoylesoftware.htmlunit.html.HtmlPage;
50  
51  /**
52   * See: https://wiki.kuali.org/display/KPME/Role+Security+Grid
53   */
54  @FunctionalTest
55  public class RoleTimesheetWebIntegrationTest extends TimesheetWebTestBase {
56  
57      private static final Logger LOG = Logger.getLogger(RoleTimesheetWebIntegrationTest.class);
58  
59      // Non Time Entry users (for this test) who have some access to 'fred's'
60      // Time Sheet.
61      private List<String> VALID_NON_ENTRY_USERS = new ArrayList<String>() {{
62      	//add fred too.
63          /*add("testuser6");*/ add("frank"); add("fran"); add("edna"); add("fred"); }};
64  
65      // Users with incorrect Department or Work Area for Time Sheet privilege.
66      private List<String> INVALID_NON_ENTRY_USERS = new ArrayList<String>(){{
67          add("testuser1"); add("testuser2"); add("testuser3"); add("testuser4"); }};
68  
69      private TimesheetDocument fredsDocument = null;
70      DateTime asOfDate = new DateTime(2011, 3, 1, 12, 0, 0, 0, TKUtils.getSystemDateTimeZone());
71  
72      @Override
73      /**
74       * This code is called before each test below - allows us to control how far
75       * into the routing process we are for any given level of testing.
76       */
77      public void setUp() throws Exception {
78          super.setUp();
79  
80          String userId = "fred";
81          DateTimeZone dateTimeZone = DateTimeZone.forID(HrServiceLocator.getTimezoneService().getUserTimezone(userId));
82          
83          CalendarEntry pcd = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates(userId, asOfDate);
84          Assert.assertNotNull("No PayCalendarDates", pcd);
85          fredsDocument = TkServiceLocator.getTimesheetService().openTimesheetDocument(userId, pcd);
86          String tdocId = fredsDocument.getDocumentId();
87  
88          // Verify the non time entry logins.
89          verifyLogins(fredsDocument);
90  
91          // Verify Fred, and Add Timeblocks
92          HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true);
93          Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011"));
94  
95          HtmlForm form = page.getFormByName("TimeDetailActionForm");
96          Assert.assertNotNull(form);
97          List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAssignments(userId, JAN_AS_OF_DATE.toLocalDate());
98          Assignment assignment = assignments.get(0);
99  
100         List<EarnCode> earnCodes = TkServiceLocator.getTimesheetService().getEarnCodesForTime(assignment, JAN_AS_OF_DATE.toLocalDate());
101         EarnCode earnCode = earnCodes.get(0);
102         Assert.assertEquals("There should be no existing time blocks.", 0, fredsDocument.getTimeBlocks().size());
103 
104         // 2. Set Timeblock Start and End time
105         // 3/02/2011 - 8:00a to 6:00pm
106         // OVT - 0 Hrs Expected
107         final DateTime start = new DateTime(2011, 3, 2, 8, 0, 0, 0, dateTimeZone);
108         final DateTime end = new DateTime(2011, 3, 2, 13, 0, 0, 0, dateTimeZone);
109 
110         TimeDetailActionFormBase tdaf = TimeDetailTestUtils.buildDetailActionForm(fredsDocument, assignment, earnCode, start, end, null, false, null, true);
111         List<String> errors = TimeDetailTestUtils.setTimeBlockFormDetails(form, tdaf);
112 
113         Assert.assertEquals("There should be no errors in this time detail submission", 0, errors.size());
114         page = TimeDetailTestUtils.submitTimeDetails(getWebClient(), getTimesheetDocumentUrl(tdocId), tdaf);
115         Assert.assertNotNull(page);
116         page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true);
117 
118         String pageAsText = page.asText();
119         DomElement element = page.getElementById("timeBlockString");
120         Assert.assertNotNull(element);
121         String elementAsText = element.asText();
122         String dataText = page.getElementById("timeBlockString").getFirstChild().getNodeValue();
123         JSONArray jsonData = (JSONArray) JSONValue.parse(dataText);
124         final JSONObject jsonDataObject = (JSONObject) jsonData.get(0);
125         Assert.assertTrue("TimeBlock Data Missing.", checkJSONValues(new JSONObject() {{ put("outer", jsonDataObject); }},
126                 new ArrayList<Map<String, Object>>() {{
127                     add(new HashMap<String, Object>() {{
128                         put("earnCode", "RGN");
129                         put("hours", "5.0");
130                         put("amount", null);
131                     }});
132                 }},
133                 new HashMap<String, Object>() {{
134                     put("earnCode", "RGN");
135                     start.toString();
136                     put("startNoTz", start.toString("yyyy-MM-dd'T'HH:mm:ss"));
137                     put("endNoTz", end.toString("yyyy-MM-dd'T'HH:mm:ss"));
138                     put("title", "SDR1 Work Area");
139                     put("assignment", "30_30_30");
140                 }}
141         ));
142 
143         // Set freds timesheet to have updated info.
144         fredsDocument = TkServiceLocator.getTimesheetService().openTimesheetDocument(userId, pcd);
145     }
146 
147     /*
148      * Tests while Timesheet is in INITIATED state.
149      */
150 
151     @Test
152     public void testInitiatedTimesheetIsVisibleByAll() throws Exception {
153         // test valid users
154         for (String uid : VALID_NON_ENTRY_USERS) {
155             LOG.info("Testing visibility for " + uid);
156             HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), uid, fredsDocument.getDocumentId(), true);
157             Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011"));
158         }
159     }
160 
161     @Test
162     public void testInitiatedTimesheetIsNotVisible() throws Exception {
163         for (String uid : INVALID_NON_ENTRY_USERS) {
164             LOG.info("Testing visibility for " + uid);
165             HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), uid, fredsDocument.getDocumentId(), false);
166             //HtmlUnitUtil.createTempFile(page, "badlogin");
167             Assert.assertTrue("Should not have access", page.asText().contains("You are not authorized to access this portion of the application."));
168         }
169     }
170 
171     public void testInitiatedTimesheetEditable(String userId) throws Exception {
172         // admin, add one timeblock
173         String tdocId = fredsDocument.getDocumentId();
174         HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true);
175         LOG.debug(page.asText());
176         //HtmlUnitUtil.createTempFile(page, "loggedin");
177         Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011"));
178 
179         HtmlForm form = page.getFormByName("TimeDetailActionForm");
180         Assert.assertNotNull(form);
181         List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAssignments("fred", JAN_AS_OF_DATE.toLocalDate());
182         Assignment assignment = assignments.get(0);
183 
184         List<EarnCode> earnCodes = TkServiceLocator.getTimesheetService().getEarnCodesForTime(assignment, JAN_AS_OF_DATE.toLocalDate());
185         EarnCode earnCode = earnCodes.get(0);
186 
187         Assert.assertEquals("There should be one existing time block.", 1, fredsDocument.getTimeBlocks().size());
188 
189         DateTimeZone dateTimeZone = DateTimeZone.forID(HrServiceLocator.getTimezoneService().getUserTimezone(userId));
190         final DateTime start = new DateTime(2011, 3, 2, 13, 0, 0, 0, dateTimeZone);
191         final DateTime end = new DateTime(2011, 3, 2, 18, 0, 0, 0, dateTimeZone);
192         TimeDetailActionFormBase tdaf = TimeDetailTestUtils.buildDetailActionForm(fredsDocument, assignment, earnCode, start, end, null, false, null, true);
193 
194         List<String> errors = TimeDetailTestUtils.setTimeBlockFormDetails(form, tdaf);
195         Assert.assertEquals("There should be no errors in this time detail submission", 0, errors.size());
196         String targetedTimesheetUrl = getTargetedTimesheetDocumentUrl(tdocId,"fred");
197         page = getWebClient().getPage(targetedTimesheetUrl);
198         Assert.assertNotNull(page);
199         String submitDetailsUrl = BASE_DETAIL_URL + tdocId;
200         //The following page does not contain timeBlockString data after KPME-2959.
201         page = TimeDetailTestUtils.submitTimeDetails(getWebClient(), submitDetailsUrl, tdaf);
202         Assert.assertNotNull(page);
203         //This extra page get was needed for KPME-2959.
204         page = getWebClient().getPage(targetedTimesheetUrl);
205         HtmlUnitUtil.createTempFile(page, "initiatetest");
206         String dataText = page.getElementById("timeBlockString").getFirstChild().getNodeValue();
207         JSONArray jsonData = (JSONArray) JSONValue.parse(dataText);
208         final JSONObject jsonDataObject = (JSONObject) jsonData.get(1);
209         Assert.assertTrue("TimeBlock Data Missing.", checkJSONValues(new JSONObject() {{ put("outer", jsonDataObject); }},
210                 new ArrayList<Map<String, Object>>() {{
211                     add(new HashMap<String, Object>() {{
212                         put("earnCode", "RGN");
213                         put("hours", "5.0");
214                         put("amount", null);
215                     }});
216                 }},
217                 new HashMap<String, Object>() {{
218                     put("earnCode", "RGN");
219                     put("startNoTz", start.toString("yyyy-MM-dd'T'HH:mm:ss"));
220                     put("endNoTz", end.toString("yyyy-MM-dd'T'HH:mm:ss"));
221                     put("title", "SDR1 Work Area");
222                     put("assignment", "30_30_30");
223                 }}
224         ));
225     }
226 
227     public void testInitiatedTimesheetNotEditable(String userId) throws Exception {
228         // admin, add one timeblock
229         String tdocId = fredsDocument.getDocumentId();
230         HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true);
231         //HtmlUnitUtil.createTempFile(page, "loggedin");
232         Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011"));
233 
234         HtmlForm form = page.getFormByName("TimeDetailActionForm");
235         Assert.assertNotNull(form);
236         List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAssignments("fred", JAN_AS_OF_DATE.toLocalDate());
237         Assignment assignment = assignments.get(0);
238 
239         List<EarnCode> earnCodes = TkServiceLocator.getTimesheetService().getEarnCodesForTime(assignment, JAN_AS_OF_DATE.toLocalDate());
240         EarnCode earnCode = earnCodes.get(0);
241 
242         Assert.assertEquals("There should be one existing time block.", 1, fredsDocument.getTimeBlocks().size());
243 
244         DateTimeZone dateTimeZone = DateTimeZone.forID(HrServiceLocator.getTimezoneService().getUserTimezone(userId));
245         DateTime start = new DateTime(2011, 3, 4, 8, 0, 0, 0, dateTimeZone);
246         DateTime end = new DateTime(2011, 3, 4, 13, 0, 0, 0, dateTimeZone);
247         TimeDetailActionFormBase tdaf = TimeDetailTestUtils.buildDetailActionForm(fredsDocument, assignment, earnCode, start, end, null, false, null, true);
248         List<String> errors = TimeDetailTestUtils.setTimeBlockFormDetails(form, tdaf);
249         Assert.assertEquals("There should be no errors in this time detail submission", 0, errors.size());
250         page = TimeDetailTestUtils.submitTimeDetails(getWebClient(), userId, getTimesheetDocumentUrl(tdocId), tdaf);
251         Assert.assertNotNull(page);
252         HtmlUnitUtil.createTempFile(page, "aftertdadd");
253         Assert.assertTrue("Should not have access", page.asText().contains("You are not authorized to access this portion of the application."));
254     }
255 
256     @Test
257     public void testInitiatedTimesheetIsEditableByAdmin() throws Exception {
258         testInitiatedTimesheetEditable("admin");
259     }
260 
261     @Test
262     public void testInitiatedTimesheetIsEditableByApprover() throws Exception {
263         testInitiatedTimesheetEditable("fran");
264     }
265 
266     @Test
267     public void testInitiatedTimesheetIsEditableByReviewer() throws Exception {
268         testInitiatedTimesheetEditable("frank");
269     }
270 
271     @Test
272     public void testInitiatedTimesheetIs_NOT_EditableByViewOnly() throws Exception {
273         testInitiatedTimesheetNotEditable("edna");
274     }
275 
276     @Test
277     public void testInitiatedTimesheetIs_NOT_EditableByDeptAdmin() throws Exception {
278         testInitiatedTimesheetNotEditable("testuser6");
279     }
280 
281 
282     @Test
283     public void testInitiatedTimesheetSubmitUser() throws Exception {
284         // User,
285         // Check for submit button.
286         // Click Button
287     }
288 
289     @Test
290     public void testInitiatedTimesheetSubmitAdmin() throws Exception {
291         // Admin
292         // Check for submit button.
293         // Click Button
294     }
295 
296     @Test
297     public void testInitiatedTimesheetSubmitApprover() throws Exception {
298         // Approver
299         // Check for submit button.
300         // Click Button
301     }
302 
303 
304     @Test
305     public void testInitiatedTimesheetIs_NOT_SubmittableByUsers() throws Exception {
306         // DeptAdmin, View Only, Reviewer
307         // Check that submit button is not present.
308     }
309 
310     /*
311      * Test for ENROUTE state.
312      */
313 
314     @Test
315     public void testEnrouteTimesheetIsVisibleByAll() throws Exception {
316         // test valid users
317     }
318 
319     @Test
320     public void testEnrouteTimesheetIsNotVisible() throws Exception {
321         // make sure invalid users do not have access
322     }
323 
324     @Test
325     public void testEnrouteTimesheetIsEditableByAdmin() throws Exception {
326         // admin, add one timeblock
327     }
328 
329     @Test
330     public void testEnrouteTimesheetIsEditableByApprover() throws Exception {
331         // approver, add one timeblock
332     }
333 
334     @Test
335     public void testEnrouteTimesheetIsEditableByReviewer() throws Exception {
336         // reviewer add one timeblock.
337     }
338 
339     @Test
340     public void testEnrouteTimesheetIs_NOT_EditableByViewOnly() throws Exception {
341     }
342 
343     @Test
344     public void testEnrouteTimesheetIs_NOT_EditableByDeptAdmin() throws Exception {
345     }
346 
347 
348     @Test
349     public void testEnrouteTimesheet_NOT_Approvable() throws Exception {
350         // User, Reviewer, View Only, Dept Admin
351         // Check for approve button
352     }
353 
354     @Test
355     public void testEnrouteTimesheetApproveAdmin() throws Exception {
356         // Admin
357         // Check for approve button.
358         // Click Button
359     }
360 
361     @Test
362     public void testEnrouteTimesheetApproveApprover() throws Exception {
363         // Approver
364         // Check for approve button.
365         // Click Button
366     }
367 
368     @Test
369     public void testEnrouteTimesheetIs_NOT_SubmittableByUsers() throws Exception {
370         // DeptAdmin, View Only, Reviewer
371         // Check that submit button is not present.
372     }
373 
374 
375     /*
376      * Final State
377      */
378 
379     @Test
380     public void testFinalTimesheetIsVisibleByAll() throws Exception {
381         // test valid users
382     }
383 
384     @Test
385     public void testFinalTimesheetIsNotVisible() throws Exception {
386         // make sure invalid users do not have access
387     }
388 
389     @Test
390     public void testFinalTimesheetIsNotEditable() throws Exception {
391         // by everyone but admin
392     }
393 
394     @Test
395     public void testFinalTimesheetIsAdminEditable() throws Exception {
396         // admin, add timeblock.
397     }
398 
399     /**
400      * Verifies that each admin/approver/reviewer login is active for this test.
401      */
402     private void verifyLogins(TimesheetDocument tdoc) throws Exception {
403         for (String userId : VALID_NON_ENTRY_USERS) {
404             String tdocId = tdoc.getDocumentId();
405             HtmlPage page = loginAndGetTimeDetailsHtmlPage(getWebClient(), userId, tdocId, true);
406             Assert.assertTrue("Calendar not loaded.", page.asText().contains("March 2011"));
407         }
408     }
409 
410 }