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