View Javadoc
1   /**
2    * Copyright 2005-2014 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.rice.krad.demo.travel.account;
17  
18  import org.kuali.rice.testtools.selenium.WebDriverLegacyITBase;
19  import org.openqa.selenium.By;
20  import org.apache.commons.lang.RandomStringUtils;
21  import org.junit.Test;
22  
23  /**
24   * @author Kuali Rice Team (rice.collab@kuali.org)
25   */
26  public class DemoTravelAccountMaintenanceEditAft extends WebDriverLegacyITBase {
27  
28      /**
29       * /kr-krad/maintenance?methodToCall=maintenanceEdit&number=a14&dataObjectClassName=org.kuali.rice.krad.demo.travel.dataobject.TravelAccount&hideReturnLink=true
30       */
31      public static final String BOOKMARK_URL = "/kr-krad/maintenance?methodToCall=maintenanceEdit&number=a14&dataObjectClassName=org.kuali.rice.krad.demo.travel.dataobject.TravelAccount&hideReturnLink=true";
32  
33      /**
34       * Description field
35       */
36      public static final String DESCRIPTION_FIELD = "document.documentHeader.documentDescription";
37  
38      /**
39       * Explanation field
40       */
41      public static final String EXPLANATION_FIELD = "document.documentHeader.explanation";
42  
43      /**
44       * Organization document number field
45       */
46      public static final String ORGANIZATION_DOCUMENT_NUMBER_FIELD = "document.documentHeader.organizationDocumentNumber";
47  
48      /**
49       * Travel sub account field
50       */
51      public static final String SUB_ACCOUNT_FIELD = "newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccount";
52  
53      /**
54       * Travel sub account name field
55       */
56      public static final String SUB_ACCOUNT_NAME_FIELD = "newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName";
57  
58      /**
59       * Subsidized percent
60       */
61      public static final String SUBSIDIZED_PERCENT_FIELD = "document.newMaintainableObject.dataObject.subsidizedPercent";
62  
63      /**
64       * Date created.
65       */
66      public static final String DATE_CREATED_FIELD = "document.newMaintainableObject.dataObject.createDate";
67  
68      /**
69       * Fiscal officer ID
70       */
71      public static final String FISCAL_OFFICER_ID_FIELD = "document.newMaintainableObject.dataObject.foId";
72  
73      @Override
74      public String getBookmarkUrl() {
75          return BOOKMARK_URL;
76      }
77  
78      protected void navigate() throws Exception {
79          waitAndClickDemoLink();
80          waitAndClickByLinkText("Travel Account Maintenance (Edit)");
81      }
82  
83      protected void testTravelAccountMaintenanceEdit() throws Exception {
84          waitAndTypeByName("document.documentHeader.documentDescription", "Travel Account Edit"+RandomStringUtils.randomAlphabetic(2));
85  
86          // Verify that adding a duplicate Sub Account is not allowed.
87          String subAccountDuplicate = "A";
88          waitAndTypeByName(SUB_ACCOUNT_FIELD, subAccountDuplicate);
89          waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName", "Sub Account 1"+RandomStringUtils.randomAlphabetic(2));
90          waitAndClickButtonByText("Add");
91          String errorMessage []={"Duplicate Sub Accounts (Travel Sub Account Number) are not allowed."};
92          assertTextPresent(errorMessage);
93  
94          // Verify that adding a duplicate Sub Account and Sub Account Name is not allowed.
95          waitAndTypeByName(SUB_ACCOUNT_FIELD, subAccountDuplicate);
96          waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName", "Sub Account A");
97          waitAndClickButtonByText("Add");
98          String errorMessage2 []={"Duplicate Sub Accounts (Travel Sub Account Number) are not allowed."};
99          assertTextPresent(errorMessage2);
100         
101         //Check for LookUp search
102         waitAndClickByXpath("//button[@class='btn btn-default uif-action icon-search']");
103         gotoLightBox();
104         waitAndClickSearchByText();
105         waitAndClickReturnValue();
106         waitAndClickByXpath("//a/span[contains(text(),'Ad Hoc Recipients')]");
107         waitAndClickByXpath("//div[@data-parent='Uif-AdHocPersonCollection']/div/div/button[@class='btn btn-default uif-action icon-search']");
108         gotoLightBox();
109         waitAndClickSearchByText();
110         waitAndClickReturnValue();
111         waitAndClickByXpath("//div[@data-parent='CollectionGroup_AdHocWorkgroup']/div/div/button[@class='btn btn-default uif-action icon-search']");
112         gotoLightBox();
113         waitAndClickSearchByText();
114         waitAndClickReturnValue();
115 
116         // Add a new sub account
117         String subAccount = "Z1" + RandomStringUtils.randomAlphabetic(2);
118         waitAndTypeByName(SUB_ACCOUNT_FIELD, subAccount);
119         waitAndTypeByName("newCollectionLines['document.newMaintainableObject.dataObject.subAccounts'].subAccountName", "Sub Account 1"+RandomStringUtils.randomAlphabetic(2));
120         waitForElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.number' and @value='a14']");
121         waitForElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.name' and @value='Travel Account 14']");
122         waitForElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.foId' and @value='fran']");
123         waitAndClickButtonByText("Add");
124         waitForElementPresentByXpath("//a[contains(text(),subAccount)]");
125 
126         saveSuccessfully();
127 
128         assertTextPresent("SAVED");
129         waitAndClickSubmitByText();
130         waitAndClickConfirmationOk();
131         waitAndClickButtonByText("Reload");
132         waitForProgressLoading();
133         checkForDocErrorKrad();
134         waitForTextPresent("Document was successfully reloaded.");
135         assertTextPresent("ENROUTE");
136     }
137 
138     protected void testTravelAccountMaintenanceEditBlanketApprove() throws Exception {
139         waitAndTypeByName("document.documentHeader.documentDescription", "Travel Account Edit"+RandomStringUtils.randomAlphabetic(2));
140         clearTextByName("document.newMaintainableObject.dataObject.subsidizedPercent");
141         waitAndTypeByName("document.newMaintainableObject.dataObject.subsidizedPercent", "42");
142         waitAndClickBlanketApprove();
143 
144         //click on confirmation message
145         waitAndClickByXpath("/html/body/form/div/div[2]/main/div/section[1]/div/div/div[2]/button[2]");
146         acceptAlertIfPresent();
147         waitForProgressLoading();
148         checkForDocErrorKrad();
149         waitAndClickDemoLink();
150         waitAndClickByLinkText("Travel Account Maintenance (Edit)");
151         if(!isElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.subsidizedPercent' and @value='42']")) {
152             jiraAwareFail("BlanketApprove was not successful. subsidizedPercent should be 42");
153         }
154         waitAndTypeByName("document.documentHeader.documentDescription", "Travel Account Edit"+RandomStringUtils.randomAlphabetic(2));
155         clearTextByName("document.newMaintainableObject.dataObject.subsidizedPercent");
156         waitAndClickBlanketApprove();
157         waitAndClickByXpath("/html/body/form/div/div[2]/main/div/section[1]/div/div/div[2]/button[2]");
158         acceptAlertIfPresent();
159 
160     }
161 
162 
163     protected void testTravelAccountMaintenanceEditXss() throws Exception {
164         waitAndTypeByName(DESCRIPTION_FIELD,"\"/><script>alert('!')</script>");
165         waitAndTypeByName(EXPLANATION_FIELD,"\"/><script>alert('!')</script>");
166         waitAndTypeByName(ORGANIZATION_DOCUMENT_NUMBER_FIELD,"\"/><script>alert('!')</script>");
167         waitAndTypeByName(SUB_ACCOUNT_FIELD,"blah");
168         waitAndTypeByName(SUB_ACCOUNT_NAME_FIELD,"\"/><script>alert('!')</script>");
169         waitAndTypeByName(SUBSIDIZED_PERCENT_FIELD,"\"/><script>alert('!')</script>");
170 //        waitAndTypeByName(DATE_CREATED_FIELD,"\"/><script>alert('!')</script>"); // no longer an input field
171 //        waitAndTypeByName(FISCAL_OFFICER_ID_FIELD,"\"/><script>alert('!')</script>");
172         waitAndClickSaveByText();
173         Thread.sleep(1000);
174         if(isAlertPresent())    {
175             fail("XSS vulnerability identified.");
176         }
177     }
178 
179     protected boolean isAlertPresent() {
180         try {
181             driver.switchTo().alert();
182             return true;
183         }   // try
184         catch (Exception Ex) {
185             return false;
186         }   // catch
187     }
188     
189     protected void testEditFiscalOfficer() throws Exception {
190         String currentFiscalOfficer = findElement(By.name("document.newMaintainableObject.dataObject.foId")).getAttribute("value");
191         String newFiscalOfficer = "fran";
192         if ("fran".equals(currentFiscalOfficer)) {
193             newFiscalOfficer = "eric";
194         }
195 
196         checkForRequiredFields();
197         changeFiscalOfficer(newFiscalOfficer);
198         
199         // change eric back to fran
200         changeFiscalOfficer(currentFiscalOfficer);
201     }
202     
203     protected void testSubAccountOperations() throws Exception {
204         waitForElementNotPresent(By.xpath("//button[contains(text(),'Delete')]"));
205         waitAndTypeByXpath("//div[@data-label='Travel Sub Account Number']/input","A");
206         waitAndTypeByXpath("//div[@data-label='Sub Account Name']/input","Sub Account A");
207         waitAndClickButtonByExactText("Add");
208         waitForTextPresent("Duplicate Sub Accounts (Travel Sub Account Number) are not allowed.");
209     }
210 
211     private void changeFiscalOfficer(String newUser) throws Exception {
212         waitAndTypeByName("document.documentHeader.documentDescription", "Edit Fiscal Officer to " + newUser + " "  + RandomStringUtils.randomAlphabetic(2));
213         clearTextByName("document.newMaintainableObject.dataObject.foId");
214         waitAndTypeByName("document.newMaintainableObject.dataObject.foId", newUser);
215         waitAndClickBlanketApprove();
216         jGrowl("Click OK");
217         waitAndClickByXpath("//div[@data-parent='ConfirmBlanketApproveDialog']/button[contains(text(),'OK')]");
218         acceptAlert();
219         checkForDocErrorKrad();
220 
221         // Redirected to Home page after Blanket Approve https://jira.kuali.org/browse/KULRICE-13042
222         waitAndClickDemoLink();
223         waitAndClickByLinkText("Travel Account Maintenance (Edit)");
224 
225         if(!isElementPresentByXpath("//input[@name='document.newMaintainableObject.dataObject.foId' and @value='" + newUser + "']")) {
226             jiraAwareFail("Fiscal Officer Not Changed to " + newUser);
227         }
228     }
229 
230     private void checkForRequiredFields() throws Exception{
231     	waitForElementPresentByXpath("//label[contains(text(),'Description')]/span[contains(text(),'*')]");
232     	waitForElementPresentByXpath("//label[contains(text(),'Travel Account Number:')]/span[contains(text(),'*')]");
233     	waitForElementPresentByXpath("//label[contains(text(),'Travel Account Name:')]/span[contains(text(),'*')]");
234     	waitForElementPresentByXpath("//label[contains(text(),'Travel Account Type Code:')]/span[contains(text(),'*')]");
235     	waitForElementPresentByXpath("//label[contains(text(),'Date Created:')]/span[contains(text(),'*')]");
236     	waitForElementPresentByXpath("//label[contains(text(),'Travel Sub Account Number:')]/span[contains(text(),'*')]");
237     	waitForElementPresentByXpath("//label[contains(text(),'Sub Account Name:')]/span[contains(text(),'*')]");
238         jGrowl("Verify required messages are displayed");
239         clearTextByName("document.newMaintainableObject.dataObject.name");
240         waitAndClickSubmitByText();
241         waitForElementPresentByXpath("//h3[@id='pageValidationHeader' and contains(text(),'This page has 2 errors')]");
242         waitForElementPresentByXpath("//ul[@id='pageValidationList']/li/a[contains(text(),'Document Overview: 1 error')]");
243         waitForElementPresentByXpath("//ul[@id='pageValidationList']/li/a[contains(text(),'Account Information: 1 error')]");
244         waitForElementPresentByXpath("//div[@class='uif-messageCount' and contains(text(),'  1 error')]");
245     	String requiredMessage []={"Description: Required","Travel Account Name: Required"};
246     	assertTextPresent(requiredMessage);
247         waitAndClickSaveByText();
248     	assertTextPresent(requiredMessage);
249         waitAndClickBlanketApprove();
250     	assertTextPresent(requiredMessage);
251     	waitForElementPresentByXpath("//div[@data-label='Date Created']");
252     	waitAndTypeByName("document.newMaintainableObject.dataObject.name","Travel Account 14");
253     }
254 
255     @Test
256     public void testDemoTravelAccountMaintenanceEditBookmark() throws Exception {
257         testTravelAccountMaintenanceEdit();
258         passed();
259     }
260 
261     @Test
262     public void testDemoTravelAccountMaintenanceEditNav() throws Exception {
263         testTravelAccountMaintenanceEdit();
264         passed();
265     }
266 
267     @Test
268     public void testDemoTravelAccountMaintenanceEditBlanketApproveBookmark() throws Exception {
269         testTravelAccountMaintenanceEditBlanketApprove();
270         passed();
271     }
272 
273     @Test
274     public void testDemoTravelAccountMaintenanceEditBlanketApproveNav() throws Exception {
275         testTravelAccountMaintenanceEditBlanketApprove();
276         passed();
277     }
278 
279     @Test
280     public void testDemoTravelAccountMaintenanceEditXssBookmark() throws Exception {
281         testTravelAccountMaintenanceEditXss();
282         passed();
283     }
284 
285     @Test
286     public void testDemoTravelAccountMaintenanceEditXssNav() throws Exception {
287         testTravelAccountMaintenanceEditXss();
288         passed();
289     }
290     
291     @Test
292     public void testDemoTravelAccountMaintenanceEditFiscalOfficerBookmark() throws Exception {
293     	testEditFiscalOfficer();
294         passed();
295     }
296 
297     @Test
298     public void testDemoTravelAccountMaintenanceEditFiscalOfficerNav() throws Exception {
299         testEditFiscalOfficer();
300         passed();
301     }
302 
303     @Test
304     public void testDemoTravelAccountMaintenanceSubAccountOperationsBookmark() throws Exception {
305     	testSubAccountOperations();
306         passed();
307     }
308     @Test
309     public void testDemoTravelAccountMaintenanceSubAccountOperationsNav() throws Exception {
310         testSubAccountOperations();
311         passed();
312     }
313 
314 }