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.clock.web;
17  
18  import java.math.BigDecimal;
19  import java.sql.Timestamp;
20  import java.util.*;
21  
22  import org.joda.time.DateTime;
23  import org.junit.Assert;
24  import org.junit.Ignore;
25  import org.junit.Test;
26  import org.kuali.hr.test.KPMETestCase;
27  import org.kuali.hr.time.clocklog.ClockLog;
28  import org.kuali.hr.time.graceperiod.rule.GracePeriodRule;
29  import org.kuali.hr.time.service.base.TkServiceLocator;
30  import org.kuali.hr.time.test.HtmlUnitUtil;
31  import org.kuali.hr.time.test.TkTestConstants;
32  import org.kuali.hr.time.timeblock.TimeBlock;
33  import org.kuali.hr.time.timeblock.TimeHourDetail;
34  import org.kuali.hr.time.timesheet.TimesheetDocument;
35  import org.kuali.hr.time.util.TKUtils;
36  import org.kuali.hr.time.util.TkConstants;
37  import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
38  import org.kuali.rice.krad.service.KRADServiceLocator;
39  
40  import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
41  import com.gargoylesoftware.htmlunit.WebClient;
42  import com.gargoylesoftware.htmlunit.html.HtmlElement;
43  import com.gargoylesoftware.htmlunit.html.HtmlPage;
44  
45  
46  public class ClockWebTest extends KPMETestCase {
47  
48      private String tbId;
49  
50      public Long maxDocumentId() {
51          Collection aCol = KRADServiceLocator.getBusinessObjectService().findAll(TimesheetDocumentHeader.class);
52          Long maxId = new Long(-1);
53          Iterator<TimesheetDocumentHeader> itr = aCol.iterator();
54          while (itr.hasNext()) {
55              TimesheetDocumentHeader tdh = itr.next();
56              Long temp = new Long(tdh.getDocumentId());
57              if (temp > maxId) {
58                  maxId = temp;
59              }
60          }
61          return maxId;
62      }
63  
64      public Long maxTimeBlockId() {
65          Collection aCol = KRADServiceLocator.getBusinessObjectService().findAll(TimeBlock.class);
66          Long maxId = new Long(-1);
67          Iterator<TimeBlock> itr = aCol.iterator();
68          while (itr.hasNext()) {
69              TimeBlock tb = itr.next();
70              Long temp = new Long(tb.getTkTimeBlockId());
71              if (temp > maxId) {
72                  maxId = temp;
73              }
74          }
75          return maxId;
76      }
77  
78      public void createTB() {
79          TimeBlock timeBlock = new TimeBlock();
80          timeBlock.setUserPrincipalId("admin");
81          timeBlock.setJobNumber(2L);
82          timeBlock.setWorkArea(1234L);
83          timeBlock.setTask(1L);
84          timeBlock.setEarnCode("RGN");
85          Timestamp beginTimestamp = new Timestamp(System.currentTimeMillis());
86          timeBlock.setBeginTimestamp(beginTimestamp);
87          Timestamp endTimestamp = new Timestamp(System.currentTimeMillis());
88          timeBlock.setEndTimestamp(endTimestamp);
89          TimeHourDetail timeHourDetail = new TimeHourDetail();
90          timeHourDetail.setEarnCode("RGN");
91          timeHourDetail.setHours(new BigDecimal(2.0));
92          timeBlock.getTimeHourDetails().add(timeHourDetail);
93          timeBlock.setHours(new BigDecimal(2.0));
94          List<TimeBlock> tbList = new ArrayList<TimeBlock>();
95          String documentId = this.maxDocumentId().toString();
96          timeBlock.setDocumentId(documentId);
97          tbList.add(timeBlock);
98          TkServiceLocator.getTimeBlockService().saveTimeBlocks(tbList);
99  
100         tbId = timeBlock.getTkTimeBlockId();
101         TimesheetDocument td = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId);
102         td.setTimeBlocks(tbList);
103 
104     }
105 
106     @Ignore
107     public void testDistributeTB() throws Exception {
108         String baseUrl = TkTestConstants.Urls.CLOCK_URL;
109         HtmlPage page = HtmlUnitUtil.gotoPageAndLogin(getWebClient(), baseUrl);
110         Assert.assertNotNull(page);
111         Assert.assertTrue("Clock Page contains Distribute Button", page.asText().contains("Distribute Time Blocks"));
112         this.createTB();
113         updateWebClient();
114         HtmlElement element = page.getElementByName("distributeTime");
115         Assert.assertNotNull(element);
116 //	  	HtmlPage testPage1 = element.click();
117 //	  	assertTrue("Distribute Page contains Close button", testPage1.asText().contains("Close"));
118 //        assertTrue("Distribute Page contains Close button", testPage1.asText().contains("Edit"));
119 
120         // timeDistribute.jsp
121         String distributeUrl = baseUrl + "?methodToCall=distributeTimeBlocks";
122         HtmlPage page1 = HtmlUnitUtil.gotoPageAndLogin(getWebClient(), distributeUrl);
123         Assert.assertTrue("Distribute Page contains Close button", page1.asText().contains("Close"));
124         Assert.assertTrue("Distribute Page contains Close button", page1.asText().contains("Edit"));
125 
126         element = page1.getElementByName("editTimeBlock");
127         Assert.assertNotNull(element);
128         Assert.assertTrue("Onclick attribute of Edit button contains", element.getAttribute("onclick").contains("Clock.do?methodToCall=editTimeBlock&editTimeBlockId="));
129 
130         if (tbId == null) {
131             tbId = this.maxTimeBlockId().toString();
132         }
133 
134         //editTimeBlock.jsp
135         String editUrl = baseUrl + "?methodToCall=editTimeBlock&editTimeBlockId=" + tbId;
136         HtmlPage page3 = HtmlUnitUtil.gotoPageAndLogin(getWebClient(), editUrl);
137 
138         // editTimeBlock.jsp
139         Assert.assertTrue("Edit Time Blocks Page contains Cancel button", page3.asText().contains("Add"));
140         Assert.assertTrue("Edit Time Blocks Page contains Save button", page3.asText().contains("Save"));
141         Assert.assertTrue("Edit Time Blocks Page contains Cancel button", page3.asText().contains("Cancel"));
142 
143         element = page3.getElementByName("addTimeBlock");
144         Assert.assertNotNull(element);
145         Assert.assertTrue("Onclick attribute of Add button contains", element.getAttribute("onclick").contains("javascript: addTimeBlockRow(this.form);"));
146 
147         updateWebClient();
148 
149 //	  	HtmlPage page4 = element.click();
150 //	  	assertTrue("Edit Time Blocks Page contains Cancel button", page4.asText().contains("Add"));
151 
152     }
153 
154     public void updateWebClient() {
155         WebClient webClient = getWebClient();
156         webClient.setJavaScriptEnabled(true);
157         webClient.setThrowExceptionOnScriptError(false);
158         webClient.setAjaxController(new NicelyResynchronizingAjaxController());
159         webClient.waitForBackgroundJavaScript(10000);
160     }
161 
162     /**
163      * This test is to :
164      * 1) make sure the seconds on clockTimestamp and timestamp are preserved when there is no grace period rule.
165      * 2) the clock in / out button is correctly rendered
166      *
167      * @throws Exception
168      */
169     @Test
170     public void testClockActionWithoutGracePeriodRule() throws Exception {
171         // Make sure there is no active grace period rule
172         GracePeriodRule gpr = TkServiceLocator.getGracePeriodService().getGracePeriodRule(TKUtils.getCurrentDate());
173         if (gpr != null && gpr.isActive()) {
174             gpr.setActive(false);
175             KRADServiceLocator.getBusinessObjectService().save(gpr);
176         }
177 
178         // Clock in
179         clockIn();
180         // Make sure clock out button is rendered
181         ClockLog lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog("admin");
182         // Make sure both timestamps preserve seconds
183         Assert.assertTrue("The seconds on clock timestamp should be preserved", new DateTime(lastClockLog.getClockTimestamp().getTime()).getSecondOfMinute() != 0);
184         Assert.assertTrue("The seconds on timestamp should be preserved", new DateTime(lastClockLog.getTimestamp().getTime()).getSecondOfMinute() != 0);
185 
186         // Clock out
187         clockOut();
188         // Make sure both timestamps preserve seconds
189         lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog("admin");
190         Assert.assertTrue("The seconds on clock timestamp should be preserved", new DateTime(lastClockLog.getClockTimestamp().getTime()).getSecondOfMinute() != 0);
191         Assert.assertTrue("The seconds on timestamp should be preserved", new DateTime(lastClockLog.getTimestamp().getTime()).getSecondOfMinute() != 0);
192     }
193 
194     @Test
195     public void testClockActionWithGracePeriodRule() throws Exception {
196         //clean clock logs
197         KRADServiceLocator.getBusinessObjectService().deleteMatching(ClockLog.class, Collections.singletonMap("principalId", "admin"));
198         GracePeriodRule gpr = new GracePeriodRule();
199         //gpr.setTkGracePeriodRuleId("1");
200         gpr.setEffectiveDate(TKUtils.createDate(1, 1, 2010, 0, 0, 0));
201         gpr.setHourFactor(new BigDecimal(3));
202         gpr.setTimestamp(new Timestamp(System.currentTimeMillis()));
203         
204         gpr.setActive(true);
205         KRADServiceLocator.getBusinessObjectService().save(gpr);
206 
207         // Clock in
208         clockIn();
209         // Make sure clock out button is rendered
210         ClockLog lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog("admin");
211         // Make sure both timestamps preserve seconds
212         Assert.assertTrue("The seconds on clock timestamp should NOT be preserved", new DateTime(lastClockLog.getClockTimestamp().getTime()).getSecondOfMinute() == 0);
213         Assert.assertTrue("The seconds on timestamp should be preserved", new DateTime(lastClockLog.getTimestamp().getTime()).getSecondOfMinute() != 0);
214 
215         // Clock out
216         clockOut();
217         // Make sure both timestamps preserve seconds
218         lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog("admin");
219         Assert.assertTrue("The seconds on clock timestamp should NOT be preserved", new DateTime(lastClockLog.getClockTimestamp().getTime()).getSecondOfMinute() == 0);
220         Assert.assertTrue("The seconds on timestamp should be preserved", new DateTime(lastClockLog.getTimestamp().getTime()).getSecondOfMinute() != 0);
221 
222 
223     }
224 
225     private HtmlPage clockIn() throws Exception {
226 
227         // Clock in
228         HtmlPage page = clockAction(TkConstants.CLOCK_IN);
229 
230         // Make sure clock in button is rendered
231         HtmlUnitUtil.createTempFile(page);
232         Assert.assertTrue("The clock out button should have displayed", page.asText().contains("Clock Out"));
233         Assert.assertTrue("The clock out button should have displayed", page.asText().contains("Take Lunch"));
234 
235         return page;
236     }
237 
238     private HtmlPage clockOut() throws Exception {
239         DateTime dateTime = new DateTime();
240         if (dateTime.getSecondOfMinute() >= 58
241                 || dateTime.getSecondOfMinute() == 0) {
242             Thread.sleep(4000);
243         }
244         // Clock out
245         HtmlPage page = clockAction(TkConstants.CLOCK_OUT);
246 
247         // Make sure clock in button is rendered
248         HtmlUnitUtil.createTempFile(page);
249         Assert.assertTrue("The clock out button should have displayed", page.asText().contains("Clock In"));
250 
251         return page;
252     }
253 
254     /**
255      * This method is used for clocking in and out.
256      * For some reason, htmlunit couldn't click the clock action button correctly.
257      * It's probably because we bind a onClick event to the button instead of submitting the form.
258      *
259      * @param clockAction
260      * @return HtmlPage page
261      */
262     private HtmlPage clockAction(String clockAction) throws Exception {
263         DateTime dateTime = new DateTime();
264         if (dateTime.getSecondOfMinute() >= 58
265                 || dateTime.getSecondOfMinute() == 0) {
266             Thread.sleep(4000);
267         }
268         String baseUrl = TkTestConstants.Urls.CLOCK_URL;
269         String actionUrl = baseUrl + "?methodToCall=clockAction&selectedAssignment=30_30_30&currentClockAction=" + clockAction;
270         HtmlPage page = HtmlUnitUtil.gotoPageAndLogin(getWebClient(), actionUrl);
271         Assert.assertNotNull("The login page shouldn't be null", page);
272         Thread.sleep(3000);
273         return page;
274     }
275 
276 
277 }