001 /**
002 * Copyright 2005-2011 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.kew.actions;
017
018 import org.junit.Test;
019 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
020 import org.kuali.rice.kew.actions.BlanketApproveTest.NotifySetup;
021 import org.kuali.rice.kew.api.KewApiServiceLocator;
022 import org.kuali.rice.kew.api.WorkflowDocument;
023 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
024 import org.kuali.rice.kew.api.action.ActionRequest;
025 import org.kuali.rice.kew.api.action.ActionType;
026 import org.kuali.rice.kew.api.action.ReturnPoint;
027 import org.kuali.rice.kew.api.document.DocumentStatus;
028 import org.kuali.rice.kew.service.KEWServiceLocator;
029 import org.kuali.rice.kew.test.KEWTestCase;
030 import org.kuali.rice.kew.test.TestUtilities;
031 import org.kuali.rice.test.BaselineTestCase;
032
033 import java.util.Iterator;
034 import java.util.List;
035
036 import static org.junit.Assert.*;
037
038 /**
039 * Tests the super user actions available on the API.
040 */
041 @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
042 public class SuperUserActionTest extends KEWTestCase {
043 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(SuperUserActionTest.class);
044
045 protected void loadTestData() throws Exception {
046 loadXmlFile("ActionsConfig.xml");
047 }
048
049 @Test public void testSuperUserApprove() throws Exception {
050 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), NotifySetup.DOCUMENT_TYPE_NAME);
051 document.route("");
052
053 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
054 assertTrue("WorkflowDocument should indicate jhopf as SuperUser", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
055 document.superUserBlanketApprove("");
056 assertTrue("Document should be 'processed' after Super User Approve", document.isProcessed());
057 List requests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
058 assertTrue("Should be active requests still", requests.size() == 2);//number of acks and fyi's configured through rules
059 for (Iterator iter = requests.iterator(); iter.hasNext();) {
060 ActionRequestValue request = (ActionRequestValue) iter.next();
061 if (request.isApproveOrCompleteRequest()) {
062 fail("There should be no approve or complete requests after su approve");
063 }
064 }
065 }
066
067 // SUApprove == SUBlanketApprove...what?
068 @Test public void testSuperUserApproveDisallowedOnFinalNode() throws Exception {
069 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "SUApproveFinalNodeDisallowed");
070 document.route("");
071
072 // approve down to last node, at every step (except the last) jhopf should be able to su_approve
073 // omit "bmcgough", the last approver
074 String nodeBeforeLast = null;
075 for (String user: new String[] { "jhopf", "ewestfal", "rkirkend", "natjohns" }) {
076 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
077 System.err.println(document.getCurrentNodeNames());
078 nodeBeforeLast = document.getCurrentNodeNames().iterator().next();
079 assertTrue("jhopf should be able to SU Approve", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
080
081 WorkflowDocumentFactory.loadDocument(getPrincipalIdForName(user), document.getDocumentId()).approve("");
082 }
083
084 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
085 // it's the last node, no SU Approve for you!
086 assertFalse("jhopf should NOT be able to SU Approve", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
087
088 // move back a step
089 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
090 document.superUserReturnToPreviousNode(ReturnPoint.create("Split"), "returning to non-final node");
091 // now we can SU Approve
092 assertTrue("jhopf should be able to SU Approve", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
093 document.superUserBlanketApprove("blanket approving as jhopf");
094
095 //assertTrue(document.isFinal());
096 assertTrue(document.isProcessed());
097 assertTrue(document.isApproved());
098 assertFalse("jhopf should NOT be able to SU Approve", document.isValidAction(ActionType.SU_BLANKET_APPROVE));
099
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 }