View Javadoc
1   /**
2    * Copyright 2004-2015 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.lm.leaveCalendar;
17  
18  import com.gargoylesoftware.htmlunit.html.HtmlButtonInput;
19  import com.gargoylesoftware.htmlunit.html.HtmlElement;
20  import com.gargoylesoftware.htmlunit.html.HtmlForm;
21  import com.gargoylesoftware.htmlunit.html.HtmlPage;
22  import org.apache.commons.lang.StringUtils;
23  import org.joda.time.DateTime;
24  import org.json.simple.JSONArray;
25  import org.json.simple.JSONObject;
26  import org.json.simple.JSONValue;
27  import org.junit.Assert;
28  import org.junit.Ignore;
29  import org.junit.Test;
30  import org.kuali.hr.TestAutoLoginFilter;
31  import org.kuali.hr.util.HtmlUnitUtil;
32  import org.kuali.kpme.core.FunctionalTest;
33  import org.kuali.kpme.core.api.assignment.Assignment;
34  import org.kuali.kpme.core.api.assignment.AssignmentDescriptionKey;
35  import org.kuali.kpme.core.api.calendar.entry.CalendarEntry;
36  import org.kuali.kpme.core.api.earncode.EarnCode;
37  import org.kuali.kpme.core.calendar.entry.CalendarEntryBo;
38  import org.kuali.kpme.core.service.HrServiceLocator;
39  import org.kuali.kpme.core.util.HrContext;
40  import org.kuali.kpme.core.util.TKUtils;
41  import org.kuali.kpme.tklm.leave.calendar.LeaveCalendarDocument;
42  import org.kuali.kpme.tklm.leave.calendar.web.LeaveCalendarWSForm;
43  import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
44  
45  import java.util.ArrayList;
46  import java.util.HashMap;
47  import java.util.List;
48  import java.util.Map;
49  
50  import static org.junit.Assert.assertTrue;
51  
52  @FunctionalTest
53  public class LeaveCalendarWorkflowIntegrationTest extends LeaveCalendarWebTestBase {
54  
55      public static final String USER_PRINCIPAL_ID = "admin";
56  	private DateTime JAN_AS_OF_DATE = new DateTime(2010, 1, 1, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone());
57  
58  	@Ignore
59      @Test
60      /**
61       * - create timesheet
62       * - add two 8 hour time blocks
63       * - submit timesheet for routing
64       * - ## login as approver
65       * - look for approval button
66       * - approve timeblock
67       * - verify approval button gone
68       * - ## login as original user
69       * - verify submit for routing button gone
70       */
71      public void testLeaveCalendarSubmissionIntegration() throws Exception {
72          DateTime asOfDate = new DateTime(2011, 3, 1, 12, 0, 0, 0, TKUtils.getSystemDateTimeZone());
73          CalendarEntry pcd =  HrServiceLocator.getCalendarEntryService().getCurrentCalendarDatesForLeaveCalendar(USER_PRINCIPAL_ID, asOfDate);
74          Assert.assertNotNull("No CalendarEntry", pcd);
75          LeaveCalendarDocument tdoc = LmServiceLocator.getLeaveCalendarService().openLeaveCalendarDocument(USER_PRINCIPAL_ID, pcd);
76          String tdocId = tdoc.getDocumentId();
77          HtmlPage page = loginAndGetLeaveCalendarHtmlPage("admin", tdocId, true);
78  
79          // 1. Obtain User Data
80          Assignment assignment = HrServiceLocator.getAssignmentService().getAssignment(HrContext.getPrincipalId(), AssignmentDescriptionKey.get("IU-BL_30_30_30"), JAN_AS_OF_DATE.toLocalDate());
81          EarnCode earnCode = HrServiceLocator.getEarnCodeService().getEarnCode("VAC", JAN_AS_OF_DATE.toLocalDate());
82  
83          // 2. Set Timeblock Start and End time
84          // 3/02/2011 - 8:00a to 4:00pm
85          DateTime start = new DateTime(2011, 3, 2, 8, 0, 0, 0, TKUtils.getSystemDateTimeZone());
86          DateTime end = new DateTime(2011, 3, 2, 16, 0, 0, 0, TKUtils.getSystemDateTimeZone());
87  
88          HtmlForm form = page.getFormByName("LeaveCalendarForm");
89          Assert.assertNotNull(form);
90  
91          // Build an action form - we're using it as a POJO, it ties into the
92          // existing TK validation setup
93          LeaveCalendarWSForm tdaf = LeaveCalendarTestUtils.buildLeaveCalendarForm(tdoc, assignment, earnCode, start, end, null, true);
94          LeaveCalendarTestUtils.setTimeBlockFormDetails(form, tdaf);
95          page = LeaveCalendarTestUtils.submitLeaveCalendar(getWebClient(), getLeaveCalendarUrl(tdocId), tdaf);
96          Assert.assertNotNull(page);
97          HtmlUnitUtil.createTempFile(page, "LeaveBlockPresent");
98  
99          // Verify block present on rendered page.
100         String pageAsText = page.asText();
101 
102         // JSON
103         //
104         //
105         // Grab the leaveBlock data from the text area. We can check specifics there
106         // to be more fine grained in our validation.
107         String dataText = page.getElementById("leaveBlockString").getFirstChild().getNodeValue();
108         JSONArray jsonData = (JSONArray)JSONValue.parse(dataText);
109         final JSONObject jsonDataObject = (JSONObject) jsonData.get(0);
110         Assert.assertTrue("leaveBlock Data Missing.", checkJSONValues(new JSONObject() {{ put("outer", jsonDataObject); }},
111                 new ArrayList<Map<String, Object>>() {{
112                     add(new HashMap<String, Object>() {{
113                         put("earnCode", "VAC");
114                         put("leaveAmount", "-8");
115                         put("earnCode", "VAC");
116                         put("leaveDate", "03/02/2011");
117                         //put("endNoTz", "2011-03-02T16:00:00");
118                         put("title", "SDR1 Work Area");
119                         put("assignment", "IU-BL_30_30_30");
120                     }});
121                 }},
122                 new HashMap<String, Object>() {{  }}
123         ));
124 
125         // Check the Display Rendered Text for Time Block, Quick Check
126         Assert.assertTrue("TimeBlock not Present.", pageAsText.contains("SDR1 Work Area-SDR1 task"));
127         Assert.assertTrue("TimeBlock not Present.", pageAsText.contains("VAC (-8)"));
128 
129         //
130         // Route Timesheet
131         //
132         // Routing is initiated via javascript, we need to extract the routing
133         // action from the button element to perform this action.
134         HtmlButtonInput routeButton = (HtmlButtonInput)page.getElementById("ts-route-button");
135         String routeHref = HtmlUnitUtil.getOnClickHref(routeButton);
136         // The 'only' way to do the button click.
137         page = HtmlUnitUtil.gotoPageAndLogin(getWebClient(), getBaseURL() + "/" + routeHref);
138         //HtmlUnitUtil.createTempFile(page, "RouteClicked");
139         pageAsText = page.asText();
140         // Verify Route Status via UI
141         Assert.assertTrue("Wrong Document Loaded.", pageAsText.contains(tdocId));
142         Assert.assertTrue("Document not routed.", pageAsText.contains("Enroute"));
143         routeButton = (HtmlButtonInput)page.getElementById("ts-route-button");
144         Assert.assertNull("Route button should not be present.", routeButton);
145         HtmlElement approveButton = (HtmlButtonInput)page.getElementById("ts-approve-button");
146         Assert.assertNull("Approval button should not be present.", approveButton);
147 
148         //
149         // Login as Approver, who is not 'admin'
150         page = loginAndGetLeaveCalendarHtmlPage("eric", tdocId, true);
151         //HtmlUnitUtil.createTempFile(page, "2ndLogin");
152         pageAsText = page.asText();
153         Assert.assertTrue("Document not routed.", pageAsText.contains("Enroute"));
154         approveButton = (HtmlButtonInput)page.getElementById("ts-approve-button");
155         Assert.assertNotNull("No approval button present.", approveButton);
156 
157         // Click Approve
158         // And Verify
159         //
160         routeHref = HtmlUnitUtil.getOnClickHref(approveButton);
161         TestAutoLoginFilter.OVERRIDE_ID = "eric";
162         page = HtmlUnitUtil.gotoPageAndLogin(getWebClient(), getBaseURL() + "/" + routeHref);
163         TestAutoLoginFilter.OVERRIDE_ID = "";
164         //HtmlUnitUtil.createTempFile(page, "ApproveClicked");
165         pageAsText = page.asText();
166         Assert.assertTrue("Wrong Document Loaded.", pageAsText.contains(tdocId));
167         Assert.assertTrue("Login info not present.", pageAsText.contains("Employee Id:"));
168         Assert.assertTrue("Login info not present.", pageAsText.contains("eric, eric"));
169         Assert.assertTrue("Document not routed.", pageAsText.contains("Final"));
170         approveButton = (HtmlElement)page.getElementById("ts-approve-button");
171         Assert.assertNull("Approval button should not be present.", approveButton);
172     }
173     
174 	@Ignore
175     @Test
176     public void testRedirectionForBalanceTransferOnLeaveApprove() throws Exception {
177 		//Create a leave summary with a single row containing an accrual category that has exceeded max balance limit.
178 /*		LeaveSummary ls = new LeaveSummary();
179 		List<LeaveSummaryRow> leaveSummaryRows = new ArrayList<LeaveSummaryRow>();
180 		//A leave summary row for an accrual category over max balance.
181 		LeaveSummaryRow lsr = new LeaveSummaryRow();
182 		lsr.setAccrualCategory("debitAC1");
183 		lsr.setAccrualCategoryId("10055");
184 		lsr.setAccrualCategoryRuleId("3000");
185 		lsr.setLeaveBalance(new BigDecimal(500));
186 		//debitAC1 accrual category has a max balance of 100.
187 		leaveSummaryRows.add(lsr);
188 		//A leave summary row for an accrual category to accept transfers.
189 		lsr = new LeaveSummaryRow();
190 		lsr.setAccrualCategory("creditAC1");
191 		lsr.setAccrualCategoryId("10056");
192 		lsr.setAccrualCategoryRuleId("3001");
193 		lsr.setLeaveBalance(BigDecimal.ZERO);
194 		
195 		leaveSummaryRows.add(lsr);
196 		ls.setLeaveSummaryRows(leaveSummaryRows);
197         setBaseDetailURL(TkTestConstants.Urls.LEAVE_CALENDAR_SUBMIT_URL + "?documentId=");
198         Date asOfDate = new Date((new DateTime(2011, 3, 1, 12, 0, 0, 0, TKUtils.getSystemDateTimeZone())).getMillis());
199         CalendarEntry pcd = HrServiceLocator.getCalendarService().getCurrentCalendarDatesForLeaveCalendar(USER_PRINCIPAL_ID, asOfDate);
200         Assert.assertNotNull("No CalendarEntry", pcd);
201         LeaveCalendarDocument tdoc = LmServiceLocator.getLeaveCalendarService().openLeaveCalendarDocument(USER_PRINCIPAL_ID, pcd);
202         String tdocId = tdoc.getDocumentId();
203 
204         // Build an action form - we're using it as a POJO, it ties into the
205         // existing TK validation setup
206         LeaveCalendarWSForm tdaf = LeaveCalendarTestUtils.buildLeaveCalendarFormForSubmission(tdoc, ls);
207 
208         HtmlPage page = LeaveCalendarTestUtils.submitLeaveCalendar2(getLeaveCalendarUrl(tdocId), tdaf);
209         Assert.assertNotNull(page);
210         HtmlUnitUtil.createTempFile(page, "LeaveBlockPresent");
211 
212         // Verify block present on rendered page.
213         String pageAsText = page.asText();
214         System.out.print(pageAsText);
215 		
216 		*/
217 		//LeaveCalendarWSForm mockForm = LeaveCalendarTestUtils.buildLeaveCalendarForm(tdoc, assignment, earnCode, start, end, null, true);
218 		//Attach leave summary to relevant object (leavecalendardocument?)
219 		//load LeaveCalendarDocument into web container
220 		//leave calendar document must have status "initiated"
221 		//mock the submit action on behalf of the principal who owns the leave calendar.
222 		//redirect should occur, which loads the balance transfer document.
223 		//balance transfer document should have all fields locked except for transfer amount.
224 		//mock transfer action on behalf of the principal.
225 		//verify leave block creation
226 		assertTrue("Dummy assertion 2", true);
227 
228     }
229 
230 
231     /**
232      * Examines the JSON structure that is written to each output TimeDetails
233      * page.
234      * @param json The JSON Object to examine
235      * @param thdList The (optional) list of Time Hour Details values
236      * @param checkValues The list of values to check for in the JSON object
237      * @return true if the JSON object contains the required values, false otherwise.
238      */
239     public static boolean checkJSONValues(JSONObject json, List<Map<String,Object>> thdList, Map<String,Object> checkValues) {
240         boolean contains = false;
241 
242         for(Object eso : json.entrySet()) {
243             // This is the outer TimeBlock ID -> Time Block Data mapping
244             Map.Entry e = (Map.Entry)eso;
245             JSONObject innerMap = (JSONObject)e.getValue(); // the values we actually care about.
246             boolean localContains = true;
247             for (Map.Entry<String,Object> cve : checkValues.entrySet()) {
248                 Object joValue = innerMap.get(cve.getKey());
249                 Object cvValue = cve.getValue();
250 
251                 // Null Checks..
252                 if (cvValue == null && joValue == null)
253                     localContains &= true;
254                 else if (joValue == null || cvValue == null)
255                     localContains = false;
256                 else
257                     localContains &= StringUtils.equals(joValue.toString(), cvValue.toString());
258             }
259 
260             contains |= localContains;
261         }
262 
263         return contains;
264     }
265 
266     public static boolean checkJSONValues(String json, List<Map<String,Object>> thdList, Map<String,Object> checkValues) {
267         return checkJSONValues((JSONObject)JSONValue.parse(json), thdList, checkValues);
268     }
269 }