View Javadoc
1   /**
2    * Copyright 2005-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.rice.kew.actions;
17  
18  import org.junit.Test;
19  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
20  import org.kuali.rice.kew.actions.BlanketApproveTest.NotifySetup;
21  import org.kuali.rice.kew.api.KewApiServiceLocator;
22  import org.kuali.rice.kew.api.WorkflowDocument;
23  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
24  import org.kuali.rice.kew.api.action.ActionRequest;
25  import org.kuali.rice.kew.api.action.ActionType;
26  import org.kuali.rice.kew.api.action.ReturnPoint;
27  import org.kuali.rice.kew.api.document.DocumentStatus;
28  import org.kuali.rice.kew.service.KEWServiceLocator;
29  import org.kuali.rice.kew.test.KEWTestCase;
30  import org.kuali.rice.kew.test.TestUtilities;
31  import org.kuali.rice.test.BaselineTestCase;
32  
33  import java.util.Iterator;
34  import java.util.List;
35  
36  import static org.junit.Assert.*;
37  
38  /**
39   * Tests the super user actions available on the API.
40   */
41  @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
42  public class SuperUserActionTest extends KEWTestCase {
43      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SuperUserActionTest.class);
44  
45      protected void loadTestData() throws Exception {
46          loadXmlFile("ActionsConfig.xml");
47      }
48  	
49      @Test public void testSuperUserApprove() throws Exception {
50          WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), NotifySetup.DOCUMENT_TYPE_NAME);
51          document.route("");
52          
53          document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
54          assertTrue("WorkflowDocument should indicate jhopf as SuperUser", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
55          document.superUserBlanketApprove("");
56          assertTrue("Document should be 'processed' after Super User Approve", document.isProcessed());
57          List requests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
58          assertTrue("Should be active requests still", requests.size() == 2);//number of acks and fyi's configured through rules
59          for (Iterator iter = requests.iterator(); iter.hasNext();) {
60  			ActionRequestValue request = (ActionRequestValue) iter.next();
61  			if (request.isApproveOrCompleteRequest()) {
62  				fail("There should be no approve or complete requests after su approve");
63  			}
64  		}
65  	}
66  
67      // SUApprove == SUBlanketApprove...what?
68      @Test public void testSuperUserApproveDisallowedOnFinalNode() throws Exception {
69          WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "SUApproveFinalNodeDisallowed");
70          document.route("");
71  
72          // approve down to last node, at every step (except the last) jhopf should be able to su_approve
73          // omit "bmcgough", the last approver
74          String nodeBeforeLast = null;
75          for (String user: new String[] { "jhopf", "ewestfal", "rkirkend", "natjohns" }) {
76              document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
77              System.err.println(document.getCurrentNodeNames());
78              nodeBeforeLast = document.getCurrentNodeNames().iterator().next();
79              assertTrue("jhopf should be able to SU Approve", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
80  
81              WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(user), document.getDocumentId()).approve("");
82          }
83  
84          document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
85          // it's the last node, no SU Approve for you!
86          assertFalse("jhopf should NOT be able to SU Approve", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
87  
88          // move back a step
89          document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
90          document.superUserReturnToPreviousNode(ReturnPoint.create("Split"), "returning to non-final node");
91          // now we can SU Approve
92          assertTrue("jhopf should be able to SU Approve", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
93          document.superUserBlanketApprove("blanket approving as jhopf");
94  
95          //assertTrue(document.isFinal());
96          assertTrue(document.isProcessed());
97          assertTrue(document.isApproved());
98          assertFalse("jhopf should NOT be able to SU Approve", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
99  
100         List<ActionRequestValue> requests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
101         assertEquals("Should be active requests still", 5, requests.size());//number of acks and fyi's configured through rules
102         for (ActionRequestValue request: requests) {
103             System.err.println(request.getActionRequestedLabel() + " -> " + request.getPrincipal().getPrincipalName());
104             if (request.isApproveOrCompleteRequest()) {
105                 fail("There should be no approve or complete requests after su approve");
106             }
107         }
108     }
109 	
110     @Test public void testSuperUserApproveExceptionCases() throws Exception {
111     	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), "SUApproveDocument");
112         document.route("");
113         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), document.getDocumentId());
114         try {
115         	document.approve("");
116         } catch (Exception e) {
117         }
118         TestUtilities.getExceptionThreader().join();
119         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
120         assertTrue("Document should be in exception routing", document.isException());
121         document.superUserBlanketApprove("");
122         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
123         assertTrue("Document should be final", document.isFinal());
124         
125         List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
126         assertTrue("Should be no active requests for SU Approved document", actionRequests.isEmpty());
127     }
128     
129     @Test public void testSuperUserApproveExceptionCasesWithNotifications() throws Exception {
130     	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), "SUApproveDocumentNotifications");
131         document.route("");
132         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), document.getDocumentId());
133         try {
134         	document.approve("");
135         } catch (Exception e) {
136         }
137         TestUtilities.getExceptionThreader().join();
138         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
139         assertTrue("Document should be in exception routing", document.isException());
140         document.superUserBlanketApprove("");
141         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
142         assertTrue("Document should be 'processed'", document.isProcessed());
143         
144         List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
145         assertFalse("Should be active requests for SU Approved document", actionRequests.isEmpty());
146         for (Iterator iter = actionRequests.iterator(); iter.hasNext();) {
147 			ActionRequestValue request = (ActionRequestValue) iter.next();
148 			assertTrue("Should be an ack notification request", request.isAcknowledgeRequest());
149 		}
150     }
151     
152     @Test public void testSuperUserInitiatorApprove() throws Exception {
153 		WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), NotifySetup.DOCUMENT_TYPE_NAME);
154         assertTrue("WorkflowDocument should indicate ewestfal as SuperUser", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
155         document.superUserBlanketApprove("");
156         assertTrue("Document should be 'processed' after Super User Approve", document.isProcessed());
157         List requests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
158         assertTrue("Should be active requests still", requests.size() == 2);//number of acks and fyi's configured through rules
159         for (Iterator iter = requests.iterator(); iter.hasNext();) {
160 			ActionRequestValue request = (ActionRequestValue) iter.next();
161 			if (request.isApproveOrCompleteRequest()) {
162 				fail("There should be no approve or complete requests after su approve");
163 			}
164 		}
165 	}
166 	
167 	@Test public void testSuperUserApproveWithNotifications() throws Exception {
168 		WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "NotificationTestChild");
169         assertTrue("WorkflowDocument should indicate ewestfal as SuperUser", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
170         document.superUserBlanketApprove("");
171         assertTrue("Document should be 'processed' after Super User Approve", document.isProcessed());
172         List requests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
173         assertTrue("Should be active requests still", requests.size() > 2);//number of acks and fyi's configured through rules - we need these for approvals too
174         for (Iterator iter = requests.iterator(); iter.hasNext();) {
175 			ActionRequestValue request = (ActionRequestValue) iter.next();
176 			if (request.isApproveOrCompleteRequest()) {
177 				fail("There should be no approve or complete requests after su approve");
178 			}
179 		} 
180 	}
181 	
182 	@Test public void testSuperUserApproveInvalidUser() throws Exception {
183 		WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), NotifySetup.DOCUMENT_TYPE_NAME);
184         document.route("");
185         
186         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("quickstart"), document.getDocumentId());
187         try {
188         	assertFalse("WorkflowDocument should not indicate quickstart as SuperUser", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
189         	document.superUserBlanketApprove("");
190         	fail("invalid user attempted to SuperUserApprove");
191         } catch (Exception e) {
192         }
193         
194 	}
195 	
196 	@Test public void testSuperUserActionDisregardPostProcessing() throws Exception {
197 		
198 		String bmcgoughPrincipalId = getPrincipalIdForName("bmcgough");
199 		
200 	    // verify that the post processor class still throws exceptions when post processing document
201         WorkflowDocument document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), generateDummyEnrouteDocument("ewestfal").getDocumentId());
202         try {
203             document.superUserBlanketApprove("");
204             fail("Document should throw exception from post processor");
205         } catch (Exception e) {
206         }
207         
208         // test that ignoring the post processor works correctly
209         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), generateDummyEnrouteDocument("ewestfal").getDocumentId());
210         try {
211             KEWServiceLocator.getWorkflowDocumentService().superUserCancelAction(bmcgoughPrincipalId, KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId()), "", false);
212         } catch (Exception e) {
213             LOG.error("Exception Found:", e);
214             fail("Document should not throw an exception when ignoring post processor during superUserCancelAction");
215         }
216 
217         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), generateDummyEnrouteDocument("ewestfal").getDocumentId());
218         try {
219             KEWServiceLocator.getWorkflowDocumentService().superUserDisapproveAction(bmcgoughPrincipalId, KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId()), "", false);
220         } catch (Exception e) {
221             LOG.error("Exception Found:", e);
222             fail("Document should not throw an exception when ignoring post processor during superUserDisapproveAction");
223         }
224 
225         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), generateDummyEnrouteDocument("ewestfal").getDocumentId());
226         try {
227             KEWServiceLocator.getWorkflowDocumentService().superUserApprove(bmcgoughPrincipalId, KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId()), "", false);
228         } catch (Exception e) {
229             LOG.error("Exception Found:", e);
230             fail("Document should not throw an exception when ignoring post processor during superUserApprove");
231         }
232 
233         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), generateDummyEnrouteDocument("ewestfal").getDocumentId());
234         try {
235             KEWServiceLocator.getWorkflowDocumentService().superUserNodeApproveAction(bmcgoughPrincipalId, document.getDocumentId(), "Acknowledge1", "", false);
236         } catch (Exception e) {
237             LOG.error("Exception Found:", e);
238             fail("Document should not throw an exception when ignoring post processor during superUserNodeApprove");
239         }
240 
241         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), generateDummyEnrouteDocument("ewestfal").getDocumentId());
242         try {
243             KEWServiceLocator.getWorkflowDocumentService().superUserReturnDocumentToPreviousNode(bmcgoughPrincipalId, document.getDocumentId(), "WorkflowDocumentTemplate", "", false);
244         } catch (Exception e) {
245             LOG.error("Exception Found:", e);
246             fail("Document should not throw an exception when ignoring post processor during superUserReturnDocumentToPreviousNode");
247         }
248 
249         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), generateDummyEnrouteDocument("ewestfal").getDocumentId());
250         try {
251         	String actionRequestId = null;
252             // get actionRequestId to use... there should only be one active action request
253             List<ActionRequest> actionRequests = KewApiServiceLocator.getWorkflowDocumentService().getRootActionRequests(document.getDocumentId());
254             for (ActionRequest actionRequest : actionRequests) {
255                 if (actionRequest.isActivated()) {
256                     // if we already found an active action request fail the test
257                     if (actionRequestId != null) {
258                         fail("Found two active action requests for document.  Ids: " + actionRequestId + "  &  " + actionRequest.getId());
259                     }
260                     actionRequestId = actionRequest.getId();
261                 }
262             }
263             
264             KEWServiceLocator.getWorkflowDocumentService().superUserActionRequestApproveAction(bmcgoughPrincipalId, document.getDocumentId(), actionRequestId, "", false);
265         } catch (Exception e) {
266             LOG.error("Exception Found:", e);
267             fail("Document should not throw an exception when ignoring post processor during superUserActionRequestApproveAction");
268         }
269 
270 	}
271 	
272 	private WorkflowDocument generateDummyEnrouteDocument(String initiatorNetworkId) throws Exception {
273         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(initiatorNetworkId), "SuperUserActionInvalidPostProcessor");
274         assertEquals("Document should be at start node","AdHoc", document.getNodeNames().iterator().next());
275         document.route("");
276         assertEquals("Document should be at WorkflowDocument2 node","WorkflowDocument2", document.getNodeNames().iterator().next());
277         assertEquals("Document should be enroute", DocumentStatus.ENROUTE, document.getStatus());
278         return document;
279 	}
280 	
281 	
282 }