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