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