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.actionlist.ActionListFilter;
20  import org.kuali.rice.kew.api.KewApiServiceLocator;
21  import org.kuali.rice.kew.api.WorkflowDocument;
22  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
23  import org.kuali.rice.kew.api.action.RoutingReportActionToTake;
24  import org.kuali.rice.kew.api.action.RoutingReportCriteria;
25  import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
26  import org.kuali.rice.kew.api.document.DocumentDetail;
27  import org.kuali.rice.kew.engine.node.BranchState;
28  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
29  import org.kuali.rice.kew.rule.TestRuleAttribute;
30  import org.kuali.rice.kew.service.KEWServiceLocator;
31  import org.kuali.rice.kew.test.KEWTestCase;
32  import org.kuali.rice.kew.util.FutureRequestDocumentStateManager;
33  import org.kuali.rice.kew.api.KewApiConstants;
34  
35  import java.util.ArrayList;
36  import java.util.Collections;
37  import java.util.List;
38  
39  import static org.junit.Assert.*;
40  
41  /**
42   * Tests users requesting to see all future requests, not seeing any future requests on documents and the clearing of those
43   * statuses on documents.
44   *
45   * @author Kuali Rice Team (rice.collab@kuali.org)
46   */
47  public class FutureRequestsTest extends KEWTestCase {
48  
49      /**
50       * Verify future requests status are being preserved on {@link DocumentRouteHeaderValue} objects when set from the
51       * {@link WorkflowDocumentFactory}
52       *
53       * @throws Exception
54       */
55      @Test
56      public void testSavingFutureRequestsStatuses() throws Exception {
57          List<String> ids = new ArrayList<String>();
58          ids.add(getPrincipalIdForName("user1"));
59          TestRuleAttribute.setRecipientPrincipalIds("TestRole", "TestRole-user1", ids);
60  
61          // Test receiving future requests
62  
63          String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
64          WorkflowDocument document = WorkflowDocumentFactory.createDocument(rkirkendPrincipalId, "TestDocumentType");
65          document.setReceiveFutureRequests();
66          document.route("");
67  
68          DocumentRouteHeaderValue routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
69          
70          FutureRequestDocumentStateManager futRequestStateMan = new FutureRequestDocumentStateManager(routeHeader, rkirkendPrincipalId);
71          assertTrue(futRequestStateMan.isReceiveFutureRequests());
72          assertFalse(futRequestStateMan.isClearFutureRequestState());
73          assertFalse(futRequestStateMan.isDoNotReceiveFutureRequests());
74  
75          // Test not receiving future requests
76  
77          document = WorkflowDocumentFactory.createDocument(rkirkendPrincipalId, "TestDocumentType");
78          document.setDoNotReceiveFutureRequests();
79          document.route("");
80  
81          routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
82          
83          futRequestStateMan = new FutureRequestDocumentStateManager(routeHeader, rkirkendPrincipalId);
84          assertFalse(futRequestStateMan.isReceiveFutureRequests());
85          assertFalse(futRequestStateMan.isClearFutureRequestState());
86          assertTrue(futRequestStateMan.isDoNotReceiveFutureRequests());
87  
88          // test clearing state from existing document
89          document = WorkflowDocumentFactory.loadDocument(rkirkendPrincipalId, document.getDocumentId());
90          document.setClearFutureRequests();
91          document.approve("");
92  
93          routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
94          futRequestStateMan = new FutureRequestDocumentStateManager(routeHeader, rkirkendPrincipalId);
95          assertFalse(futRequestStateMan.isReceiveFutureRequests());
96          assertTrue(futRequestStateMan.isClearFutureRequestState());
97          assertFalse(futRequestStateMan.isDoNotReceiveFutureRequests());
98  
99          // reload the route header
100         routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
101         int deactivatedCount = 0;
102         for (BranchState state : routeHeader.getRootBranchState()) {
103             if (state.getKey().contains(FutureRequestDocumentStateManager.FUTURE_REQUESTS_VAR_KEY)) {
104                 fail("state clearing should have removed all future request vars");
105             } else if (state.getKey().contains(FutureRequestDocumentStateManager.DEACTIVATED_REQUESTS_VARY_KEY)) {
106                 deactivatedCount++;
107             }
108         }
109         assertEquals(2, deactivatedCount);
110         // test standard scenario of not setting a future request status on the document
111         document = WorkflowDocumentFactory.createDocument(rkirkendPrincipalId, "TestDocumentType");
112         document.route("");
113         routeHeader = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
114         futRequestStateMan = new FutureRequestDocumentStateManager(routeHeader, rkirkendPrincipalId);
115         assertFalse(futRequestStateMan.isReceiveFutureRequests());
116         assertFalse(futRequestStateMan.isClearFutureRequestState());
117         assertFalse(futRequestStateMan.isDoNotReceiveFutureRequests());
118     }
119 
120     /**
121      * Tests future requests work with routing and force action rules
122      *
123      * @throws Exception
124      */
125     @Test
126     public void testFutureRequestsWithRouting() throws Exception {
127         this.loadXmlFile(this.getClass(), "FutureRequestsConfig.xml");
128 
129         String user1PrincipalId = getPrincipalIdForName("user1");
130         String user2PrincipalId = getPrincipalIdForName("user2");
131 
132         // Node 1 - user1 approval (forceAction true)
133         //          user2 approval (forceAction false)
134         // Node 2 - NonSIT approval (forceAction false)
135         //          user1 approval (forceAction true)
136         // Node 3 - user2 approval (forceAction false)
137         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user1PrincipalId, "FutureRequestsDoc");
138         document.setDoNotReceiveFutureRequests();
139         document.route("");
140 
141         document = WorkflowDocumentFactory.loadDocument(user1PrincipalId, document.getDocumentId());
142         assertFalse(document.isApprovalRequested());
143 
144         document = WorkflowDocumentFactory.loadDocument(user2PrincipalId, document.getDocumentId());
145         assertTrue(document.isApprovalRequested());
146         document.setReceiveFutureRequests();
147         document.approve("");
148 
149         // should have another request from second rule that is not force action because
150         // of policy
151         document = WorkflowDocumentFactory.loadDocument(user2PrincipalId, document.getDocumentId());
152         assertTrue(document.isApprovalRequested());
153 
154         // user2 should have action items. user1 should not
155         assertEquals(1, KEWServiceLocator.getActionListService().getActionList(user2PrincipalId, new ActionListFilter()).size());
156         assertEquals(1, KEWServiceLocator.getActionListService().getActionList(user1PrincipalId, new ActionListFilter()).size());
157 
158         document.approve("");
159 
160         // test for request to user2 and not a workgroup
161         document = WorkflowDocumentFactory.loadDocument(user2PrincipalId, document.getDocumentId());
162         assertTrue(document.isApprovalRequested());
163     }
164 
165     /**
166      * Tests future requests operation
167      *
168      * @throws Exception
169      */
170     @Test
171     public void testFutureRequestsWithRoutingAndWorkflowInfoActionRequestCheck() throws Exception {
172         this.loadXmlFile(this.getClass(), "FutureRequestsConfig.xml");
173 
174         String user1PrincipalId = getPrincipalIdForName("user1");
175         String user2PrincipalId = getPrincipalIdForName("user2");
176 
177         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user1PrincipalId, "FutureRequestsDoc");
178         document.route("");
179 
180         // Node1
181         //user1 should have approval requested
182         document = WorkflowDocumentFactory.loadDocument(user1PrincipalId, document.getDocumentId());
183         WorkflowDocumentActionsService actionService = KewApiServiceLocator.getWorkflowDocumentActionsService();
184         RoutingReportCriteria.Builder reportCriteria = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
185         reportCriteria.setTargetPrincipalIds(Collections.singletonList(user1PrincipalId));
186         String actionToTakeNode = "Node1";
187         reportCriteria.setActionsToTake(Collections.singletonList(RoutingReportActionToTake.Builder.create(
188                 KewApiConstants.ACTION_TAKEN_APPROVED_CD, user1PrincipalId, actionToTakeNode)));
189         assertTrue("User " + user1PrincipalId + " should have approval requests on the document",
190                 actionService.documentWillHaveAtLeastOneActionRequest(reportCriteria.build(),
191                         Collections.singletonList(KewApiConstants.ACTION_REQUEST_APPROVE_REQ), false));
192 
193         reportCriteria = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
194         reportCriteria.setTargetPrincipalIds(Collections.singletonList(user1PrincipalId));
195         actionToTakeNode = "Node1";
196         reportCriteria.setActionsToTake(Collections.singletonList(RoutingReportActionToTake.Builder.create(KewApiConstants.ACTION_TAKEN_APPROVED_CD, user1PrincipalId, actionToTakeNode)));
197         DocumentDetail documentVO = KewApiServiceLocator.getWorkflowDocumentActionsService().executeSimulation(reportCriteria.build());
198         assertTrue("User " + user1PrincipalId + " should have one or more approval requests on the document", documentVO.getActionRequests().size() > 0);
199 
200         reportCriteria = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
201         String delyeaPrincipalId = getPrincipalIdForName("delyea");
202         reportCriteria.setTargetPrincipalIds(Collections.singletonList(user1PrincipalId));
203         actionToTakeNode = "Node1";
204         reportCriteria.setActionsToTake(Collections.singletonList(RoutingReportActionToTake.Builder.create(KewApiConstants.ACTION_TAKEN_APPROVED_CD, user1PrincipalId, actionToTakeNode)));
205         documentVO = actionService.executeSimulation(reportCriteria.build());
206         assertTrue("User " + delyeaPrincipalId + " should not have any requests on the document but executeSimulation() method should return all action requests anyway", documentVO.getActionRequests().size() > 0);
207 
208         document = WorkflowDocumentFactory.createDocument(user1PrincipalId, "FutureRequestsDoc");
209         document.setDoNotReceiveFutureRequests();
210         document.route("");
211 
212         document = WorkflowDocumentFactory.loadDocument(user1PrincipalId, document.getDocumentId());
213         assertFalse(document.isApprovalRequested());
214 
215         // user1 should not have approval requested
216         reportCriteria = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
217         reportCriteria.setTargetPrincipalIds(Collections.singletonList(user1PrincipalId));
218         assertFalse("User " + user1PrincipalId + " should not have any approval request on the document", actionService.documentWillHaveAtLeastOneActionRequest(reportCriteria.build(), Collections.singletonList(KewApiConstants.ACTION_REQUEST_APPROVE_REQ), false));
219 
220         // user2 should have approval requested
221         reportCriteria = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
222         reportCriteria.setTargetPrincipalIds(Collections.singletonList(user2PrincipalId));
223         assertTrue("User " + user2PrincipalId + " should have any approval request on the document", actionService.documentWillHaveAtLeastOneActionRequest(reportCriteria.build(), Collections.singletonList(KewApiConstants.ACTION_REQUEST_APPROVE_REQ), false));
224 
225     }
226     
227     /**
228      * 
229      * This method tests future action request with duplicate nodes. Both on a straight path
230      * and a split path.  
231      * 
232      * This test was written because of KULRICE-4074.  Branch data was not being save when we
233      * call saveRoutingData.
234      * 
235      * @throws Exception
236      */
237     @Test
238     public void testFutureRequestsWithDuplicateNodesSplit() throws Exception {
239     	// This file has the split node that mimmics KC
240     	testFutureRequestsWithDuplicateNodesImpl("FutureRequestsConfig2.xml");    	    	    
241     }
242     
243     @Test
244     public void testFutureRequestsWithDuplicateNodesStraight() throws Exception {
245     	// This file has no split node
246     	testFutureRequestsWithDuplicateNodesImpl("FutureRequestsConfig3.xml");
247     }
248     
249     private void testFutureRequestsWithDuplicateNodesImpl(String fileName) throws Exception{    	
250     	this.loadXmlFile(this.getClass(), fileName);
251     	
252 
253         String user1PrincipalId = getPrincipalIdForName("user1");
254         String user2PrincipalId = getPrincipalIdForName("user2");
255         String user3PrincipalId = getPrincipalIdForName("earl");
256 
257         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user1PrincipalId, "FutureRequestsDoc");
258         document.route("");
259        
260 
261         // Node1
262         //user1 should have approval requested
263         document = WorkflowDocumentFactory.loadDocument(user3PrincipalId, document.getDocumentId());
264         assertTrue("should have approval status", document.isApprovalRequested());
265 
266         document.setReceiveFutureRequests();
267         
268         /*
269          *  Uncomment the following line to duplicate the error in KC
270          */        
271         document.saveDocumentData();
272         
273         document.approve("route node 1");
274 
275         document =WorkflowDocumentFactory.loadDocument(user1PrincipalId, document.getDocumentId());
276         assertFalse("should not have approval status 1", document.isApprovalRequested());
277 
278         document = WorkflowDocumentFactory.loadDocument(user2PrincipalId, document.getDocumentId());
279         assertTrue("should have approval status 2", document.isApprovalRequested());
280         document.approve("routing node 2");
281         
282         // Node3
283         //user1 should have approval requested bc of future action requests
284         document = WorkflowDocumentFactory.loadDocument(user3PrincipalId, document.getDocumentId());
285         assertTrue("should have approval status 3", document.isApprovalRequested());
286         document.approve("routing node 3");
287 
288     }
289 }