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.impl.peopleflow;
17  
18  import org.joda.time.DateTime;
19  import org.junit.Before;
20  import org.junit.Test;
21  import org.kuali.rice.core.api.delegation.DelegationType;
22  import org.kuali.rice.core.api.membership.MemberType;
23  import org.kuali.rice.kew.api.KewApiServiceLocator;
24  import org.kuali.rice.kew.api.WorkflowDocument;
25  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
26  import org.kuali.rice.kew.api.action.ActionRequest;
27  import org.kuali.rice.kew.api.action.ActionRequestPolicy;
28  import org.kuali.rice.kew.api.action.ActionRequestStatus;
29  import org.kuali.rice.kew.api.action.RecipientType;
30  import org.kuali.rice.kew.api.peopleflow.PeopleFlowDefinition;
31  import org.kuali.rice.kew.api.peopleflow.PeopleFlowDelegate;
32  import org.kuali.rice.kew.api.peopleflow.PeopleFlowMember;
33  import org.kuali.rice.kew.api.peopleflow.PeopleFlowService;
34  import org.kuali.rice.kew.test.KEWTestCase;
35  import org.kuali.rice.kim.api.common.delegate.DelegateMember;
36  import org.kuali.rice.kim.api.common.delegate.DelegateType;
37  import org.kuali.rice.kim.api.group.Group;
38  import org.kuali.rice.kim.api.group.GroupService;
39  import org.kuali.rice.kim.api.role.Role;
40  import org.kuali.rice.kim.api.role.RoleMember;
41  import org.kuali.rice.kim.api.role.RoleService;
42  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
43  import org.kuali.rice.test.BaselineTestCase;
44  
45  import java.util.Collections;
46  import java.util.HashMap;
47  import java.util.List;
48  
49  import static org.junit.Assert.*;
50  
51  /**
52   * An integration test which tests document types with nodes on them which route to PeopleFlows in various configurations.
53   *
54   * @author Kuali Rice Team (rice.collab@kuali.org)
55   */
56  @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.CLEAR_DB)
57  public class PeopleFlowRoutingTest extends KEWTestCase {
58  
59      private static final String NAMESPACE_CODE = "TEST";
60      private static final String PEOPLE_FLOW_1 = "PeopleFlow1";
61      private static final String PEOPLE_FLOW_2 = "PeopleFlow2";
62      private static final String PEOPLE_FLOW_3 = "PeopleFlow3";
63      private static final String PEOPLE_FLOW_4 = "PeopleFlow4";
64      private static final String PEOPLE_FLOW_5 = "PeopleFlow5";
65      private static final String PEOPLE_FLOW_6 = "PeopleFlow6";
66      private static final String PEOPLE_FLOW_7 = "PeopleFlow7";
67      private static final String PEOPLE_FLOW_8 = "PeopleFlow8";
68      private static final String PEOPLE_FLOW_9 = "PeopleFlow9";
69      private static final String PEOPLE_FLOW_10 = "PeopleFlow10";
70      private static final String PEOPLE_FLOW_11 = "PeopleFlow11";
71      private static final String PEOPLE_FLOW_12 = "PeopleFlow12";
72      private static final String PEOPLE_FLOW_13 = "PeopleFlow13";
73  
74      private static final String SINGLE_PEOPLE_FLOW_PARALLEL_APPROVE = "SinglePeopleFlow-Parallel-Approve";
75      private static final String SINGLE_PEOPLE_FLOW_SEQUENTIAL_APPROVE = "SinglePeopleFlow-Sequential-Approve";
76      private static final String SINGLE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE = "SinglePeopleFlow-PriorityParallel-Approve";
77      private static final String MULTIPLE_PEOPLE_FLOW_PRIORITY_PARALLEL = "MultiplePeopleFlow-PriorityParallel";
78      private static final String DELEGATE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE = "DelegatePeopleFlow-PriorityParallel-Approve";
79      private static final String RULESENGINE_PEOPLEFLOW_PRIORITYPARALLEL_APPROVE = "RulesEngine-PeopleFlow-PriorityParallel-Approve";
80  
81      private static final String ROLE_DELEGATE_PEOPLE_FLOW_JUST_KIM_DELEGATE = "RoleDelegatePeopleFlow-JustKimDelegate";
82      private static final String ROLE_DELEGATE_PEOPLE_FLOW_PRIMARY_DELEGATE = "RoleDelegatePeopleFlow-PrimaryDelegate";
83      private static final String ROLE_DELEGATE_PEOPLE_FLOW_SECONDARY_DELEGATE = "RoleDelegatePeopleFlow-SecondaryDelegate";
84      private static final String ROLE_DELEGATE_PEOPLE_FLOW_DELEGATE_ROLE_HAS_KIM_DELEGATE = "RoleDelegatePeopleFlow-DelegateRoleHasKimDelegate";
85  
86      private static final String ROLE_DELEGATE_PEOPLE_FLOW_PRINCIPAL_MEMBER_HAS_ROLE_DELEGATE = "RoleDelegatePeopleFlow-PrincipalMemberHasRoleDelegate";
87      private static final String ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MEMBER_HAS_PRINCIPAL_DELEGATE = "RoleDelegatePeopleFlow-RoleMemberHasPrincipalDelegate";
88      private static final String ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS = "RoleDelegatePeopleFlow-MultipleRoleMembers";
89  
90      private static final String ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_FIRST_APPROVE = "RoleDelegatePeopleFlow-MultipleRoleMembers-FirstApprove";
91      private static final String ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_DELEGATE_FIRST_APPROVE = "RoleDelegatePeopleFlow-MultipleRoleMembers-DelegateFirstApprove";
92      private static final String GROUP_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS = "GroupDelegatePeopleFlow-MultipleRoleMembers";
93  
94      private PeopleFlowService peopleFlowService;
95  
96      private String user1;
97      private String user2;
98      private String user3;
99      private String testuser1;
100     private String testuser2;
101     private String testuser3;
102     private String ewestfal;
103     private String fran;
104     private String earl;
105     private String testWorkgroup;
106     private String ppfTestRole1;
107     private String ppfTestRole2;
108     private String ppfTestRole3;
109     private String ppfTestRole4;
110     private String ppfTestGroup1;
111 
112     protected void loadTestData() throws Exception {
113         loadXmlFile("PeopleFlowRoutingTest.xml");
114     }
115 
116     @Before
117     public void setupServiceUnderTest() {
118         setPeopleFlowService(KewApiServiceLocator.getPeopleFlowService());
119 
120         // setup principal and group ids
121         user1 = getPrincipalIdForName("user1");
122         user2 = getPrincipalIdForName("user2");
123         user3 = getPrincipalIdForName("user3");
124         testuser1 = getPrincipalIdForName("testuser1");
125         testuser2 = getPrincipalIdForName("testuser2");
126         testuser3 = getPrincipalIdForName("testuser3");
127         ewestfal = getPrincipalIdForName("ewestfal");
128         fran = getPrincipalIdForName("fran");
129         earl = getPrincipalIdForName("earl");
130         testWorkgroup = getGroupIdForName("KR-WKFLW", "TestWorkgroup");
131 
132         // Create roles and groups, then get IDs for test verification
133         createTestRolesAndGroupsIfNotExists();
134 
135         ppfTestRole1 = getRoleIdForName(NAMESPACE_CODE, "ppfTestRole1");
136         ppfTestRole2 = getRoleIdForName(NAMESPACE_CODE, "ppfTestRole2");
137         ppfTestRole3 = getRoleIdForName(NAMESPACE_CODE, "ppfTestRole3");
138         ppfTestRole4 = getRoleIdForName(NAMESPACE_CODE, "ppfTestRole4");
139 
140         ppfTestGroup1 = getGroupIdForName(NAMESPACE_CODE, "ppfTestGroup1");
141     }
142 
143     protected void setPeopleFlowService(PeopleFlowService peopleFlowService) {
144         this.peopleFlowService = peopleFlowService;
145     }
146 
147     protected PeopleFlowService getPeopleFlowService() {
148         return peopleFlowService;
149     }
150 
151     private void createTestRolesAndGroupsIfNotExists() {
152         RoleService roleService = KimApiServiceLocator.getRoleService();
153         GroupService groupService = KimApiServiceLocator.getGroupService();
154 
155         if (groupService.getGroupByNamespaceCodeAndName(NAMESPACE_CODE, "ppfTestGroup1") == null) {
156             Group.Builder testgroup1Builder = Group.Builder.create(NAMESPACE_CODE, "ppfTestGroup1", "1");
157             testgroup1Builder.setActive(true);
158             Group testgroup1Group = groupService.createGroup(testgroup1Builder.build());
159 
160             groupService.addPrincipalToGroup("earl", testgroup1Group.getId());
161             groupService.addPrincipalToGroup("fran", testgroup1Group.getId());
162         }
163 
164         if (getRoleIdForName(NAMESPACE_CODE, "ppfTestRole1") == null) {
165 
166             // build ppfTestRole1 which has one member, user1.  user1 has a primary delegate, ewestfal.
167 
168             Role.Builder testRole1Builder = Role.Builder.create(null, "ppfTestRole1", NAMESPACE_CODE, "test role 1",
169                     "1" /* default role type */);
170 
171             Role roleTestRole1 = roleService.createRole(testRole1Builder.build());
172             RoleMember user1RoleMember = roleService.assignPrincipalToRole(user1, NAMESPACE_CODE, "ppfTestRole1", Collections.<String, String>emptyMap());
173 
174             DelegateType.Builder delegateTypeBuilder =
175                     DelegateType.Builder.create(roleTestRole1.getId(), DelegationType.PRIMARY,
176                             Collections.<DelegateMember.Builder>emptyList());
177             delegateTypeBuilder.setKimTypeId("1");
178 
179             DelegateType delegateType = roleService.createDelegateType(delegateTypeBuilder.build());
180 
181             DelegateMember.Builder testRole1DelegateBuilder = DelegateMember.Builder.create();
182             testRole1DelegateBuilder.setActiveFromDate(DateTime.now());
183             testRole1DelegateBuilder.setDelegationId(delegateType.getDelegationId());
184             testRole1DelegateBuilder.setRoleMemberId(user1RoleMember.getId());
185             testRole1DelegateBuilder.setMemberId(ewestfal);
186             testRole1DelegateBuilder.setType(MemberType.PRINCIPAL);
187 
188             DelegateMember testRole1Delegate = roleService.createDelegateMember(testRole1DelegateBuilder.build());
189         }
190 
191         if (getRoleIdForName(NAMESPACE_CODE, "ppfTestRole2") == null) {
192             // build ppfTestRole2 which has one member, user2
193 
194             Role.Builder testRole2Builder = Role.Builder.create(null, "ppfTestRole2", NAMESPACE_CODE, "test role 2",
195                     "1" /* default role type */);
196 
197             Role roleTestRole2 = roleService.createRole(testRole2Builder.build());
198             RoleMember user2RoleMember = roleService.assignPrincipalToRole(user2, NAMESPACE_CODE, "ppfTestRole2", Collections.<String, String>emptyMap());
199         }
200 
201         if (getRoleIdForName(NAMESPACE_CODE, "ppfTestRole3") == null) {
202             // build ppfTestRole2 which has one member, user2
203 
204             Role.Builder testRole3Builder = Role.Builder.create(null, "ppfTestRole3", NAMESPACE_CODE, "test role 3",
205                     "1" /* default role type */);
206 
207             Role roleTestRole3 = roleService.createRole(testRole3Builder.build());
208             RoleMember user1RoleMember = roleService.assignPrincipalToRole(user1, NAMESPACE_CODE, "ppfTestRole3", Collections.<String, String>emptyMap());
209             RoleMember user2RoleMember = roleService.assignPrincipalToRole(user2, NAMESPACE_CODE, "ppfTestRole3", Collections.<String, String>emptyMap());
210         }
211 
212         if (getRoleIdForName(NAMESPACE_CODE, "ppfTestRole4") == null) {
213             // build ppfTestRole2 which has one member, user2
214 
215             Role.Builder testRole4Builder = Role.Builder.create(null, "ppfTestRole4", NAMESPACE_CODE, "test role 4",
216                     "1" /* default role type */);
217 
218             Role roleTestRole4 = roleService.createRole(testRole4Builder.build());
219             RoleMember testuser1RoleMember = roleService.assignPrincipalToRole(testuser1, NAMESPACE_CODE, "ppfTestRole4", Collections.<String, String>emptyMap());
220             RoleMember testuser2RoleMember = roleService.assignPrincipalToRole(testuser2, NAMESPACE_CODE, "ppfTestRole4", Collections.<String, String>emptyMap());
221         }
222     }
223 
224     /**
225      * Defines a PeopleFlow as follows:
226      *
227      * <pre>
228      *
229      * Priority 1:
230      *   -> user1
231      * Priority 2:
232      *   -> user2
233      * Priority 3:
234      *   -> TestWorkgroup
235      *
236      * </pre>
237      */
238     private void createSimplePeopleFlow() {
239         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_1);
240         peopleFlow.addPrincipal(user1).setPriority(1);
241         peopleFlow.addPrincipal(user2).setPriority(2);
242         peopleFlow.addGroup(testWorkgroup).setPriority(3);
243         peopleFlowService.createPeopleFlow(peopleFlow.build());
244     }
245 
246     @Test
247     public void test_SinglePeopleFlow_Parallel_Approve() throws Exception {
248         createSimplePeopleFlow();
249 
250         // now route a document to it
251         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_PARALLEL_APPROVE);
252         document.route("");
253         assertTrue("Document should be enroute.", document.isEnroute());
254 
255         // user3 should not have an approval request since they initiated the document
256         document.switchPrincipal(user3);
257 
258         // user1, user2, and TestWorkgroup (of which ewestfal is a member) should have the request
259         assertApproveRequested(document, user1, user2, ewestfal);
260 
261         // now approve as each, the document should be FINAL at the end
262         document.switchPrincipal(ewestfal);
263         document.approve("approving as ewestfal");
264         assertTrue("Document should still be enroute.", document.isEnroute());
265         document.switchPrincipal(user1);
266         document.approve("approving as user1");
267         assertTrue("Document should still be enroute.", document.isEnroute());
268         document.switchPrincipal(user2);
269         document.approve("approving as user2");
270         assertTrue("Document should now be FINAL.", document.isFinal());
271     }
272 
273     @Test
274     public void test_SinglePeopleFlow_Sequential_Approve() throws Exception {
275         createSimplePeopleFlow();
276 
277         // now route a document to it
278         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_SEQUENTIAL_APPROVE);
279         document.route("");
280         assertTrue("Document should be enroute.", document.isEnroute());
281 
282         // user3 should not have an approval request since they initiated the document
283         document.switchPrincipal(user3);
284 
285         // document should be routed to user1, user2, and TestWorkgroup (of which "ewestfal" is a member) but only
286         // user1 request should be activated
287 
288         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
289         assertEquals("Should have 3 root action requests", 3, rootActionRequests.size());
290         ActionRequest user1Request = null;
291         ActionRequest user2Request = null;
292         ActionRequest testWorkgroupRequest = null;
293         for (ActionRequest actionRequest : rootActionRequests) {
294             RecipientType recipientType = actionRequest.getRecipientType();
295             if (recipientType == RecipientType.PRINCIPAL) {
296                 if (user1.equals(actionRequest.getPrincipalId())) {
297                     user1Request = actionRequest;
298                 } else if (user2.equals(actionRequest.getPrincipalId())) {
299                     user2Request = actionRequest;
300                 }
301             } else if (recipientType == RecipientType.GROUP) {
302                 if (testWorkgroup.equals(actionRequest.getGroupId())) {
303                     testWorkgroupRequest = actionRequest;
304                 }
305             }
306         }
307         // now let's ensure we got the requests we wanted
308         assertNotNull(user1Request);
309         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
310         assertNotNull(user2Request);
311         assertEquals(ActionRequestStatus.INITIALIZED, user2Request.getStatus());
312         assertNotNull(testWorkgroupRequest);
313         assertEquals(ActionRequestStatus.INITIALIZED, testWorkgroupRequest.getStatus());
314 
315         // let's double-check that before we start approving
316         assertApproveNotRequested(document, user2, ewestfal);
317 
318         // user1 should have the request for approval, however
319         assertApproveRequested(document, user1);
320 
321         // approve as user1
322         document.switchPrincipal(user1);
323         document.approve("");
324 
325         // should still be enroute
326         assertTrue(document.isEnroute());
327 
328         // now user1 should no longer have it, it should be activated approve to user2 with TestWorkgroup still initialized but not activated
329         assertApproveNotRequested(document, user1, ewestfal);
330         assertApproveRequested(document, user2);
331 
332         // approve as user2
333         document.switchPrincipal(user2);
334         document.approve("");
335         // should still be enroute
336         assertTrue(document.isEnroute());
337 
338         // now user1 and user2 have approved, should be activated to TestWorkgroup of which ewestfal is a member
339         assertApproveNotRequested(document, user2, user1);
340 
341         // ewestfal should have an approve request because he is a member of TestWorkgroup
342         assertApproveRequested(document, ewestfal);
343         document.switchPrincipal(ewestfal);
344         document.approve("");
345 
346         // now document should be final!
347         assertTrue(document.isFinal());
348     }
349 
350     /**
351      * Defines a PeopleFlow as follows:
352      *
353      * <pre>
354      *
355      * Priority 1:
356      *   -> user1
357      *   -> user2
358      * Priority 2:
359      *   -> testuser1
360      *   -> testuser2
361      * Priority 10:
362      *   -> TestWorkgroup
363      *   -> testuser3
364      *
365      * </pre>
366      */
367     private void createPriorityParallelPeopleFlow() {
368         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_2);
369         peopleFlow.addPrincipal(user1).setPriority(1);
370         peopleFlow.addPrincipal(user2).setPriority(1);
371         peopleFlow.addPrincipal(testuser1).setPriority(2);
372         peopleFlow.addPrincipal(testuser2).setPriority(2);
373         // add the last two at a priority which is not contiguous, should still work as expected
374         peopleFlow.addGroup(testWorkgroup).setPriority(10);
375         peopleFlow.addPrincipal(testuser3).setPriority(10);
376         peopleFlowService.createPeopleFlow(peopleFlow.build());
377     }
378 
379     @Test
380     public void test_SinglePeopleFlow_PriorityParallel_Approve() throws Exception {
381         createPriorityParallelPeopleFlow();
382 
383         // now route a document to it
384         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
385         document.route("");
386         assertTrue("Document should be enroute.", document.isEnroute());
387 
388         // user3 should not have an approval request since they initiated the document
389         document.switchPrincipal(user3);
390 
391         // document should be routed to user1, user2, testuser1, testuser2, TestWorkgroup, and testuser3
392         // But only user1 and user2 requests should be activated since those are at priority 1
393 
394         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
395         assertEquals("Should have 6 root action requests", 6, rootActionRequests.size());
396         ActionRequest user1Request = null;
397         ActionRequest user2Request = null;
398         ActionRequest testuser1Request = null;
399         ActionRequest testuser2Request = null;
400         ActionRequest testWorkgroupRequest = null;
401         ActionRequest testuser3Request = null;
402         for (ActionRequest actionRequest : rootActionRequests) {
403             RecipientType recipientType = actionRequest.getRecipientType();
404             if (recipientType == RecipientType.PRINCIPAL) {
405                 if (user1.equals(actionRequest.getPrincipalId())) {
406                     user1Request = actionRequest;
407                 } else if (user2.equals(actionRequest.getPrincipalId())) {
408                     user2Request = actionRequest;
409                 } else if (testuser1.equals(actionRequest.getPrincipalId())) {
410                     testuser1Request = actionRequest;
411                 } else if (testuser2.equals(actionRequest.getPrincipalId())) {
412                     testuser2Request = actionRequest;
413                 } else if (testuser3.equals(actionRequest.getPrincipalId())) {
414                     testuser3Request = actionRequest;
415                 }
416             } else if (recipientType == RecipientType.GROUP) {
417                 if (testWorkgroup.equals(actionRequest.getGroupId())) {
418                     testWorkgroupRequest = actionRequest;
419                 }
420             }
421         }
422         // now let's ensure we got the requests we wanted
423         assertNotNull(user1Request);
424         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
425         assertNotNull(user2Request);
426         assertEquals(ActionRequestStatus.ACTIVATED, user2Request.getStatus());
427         assertNotNull(testuser1Request);
428         assertEquals(ActionRequestStatus.INITIALIZED, testuser1Request.getStatus());
429         assertNotNull(testuser2Request);
430         assertEquals(ActionRequestStatus.INITIALIZED, testuser2Request.getStatus());
431         assertNotNull(testWorkgroupRequest);
432         assertEquals(ActionRequestStatus.INITIALIZED, testWorkgroupRequest.getStatus());
433         assertNotNull(testuser3Request);
434         assertEquals(ActionRequestStatus.INITIALIZED, testuser3Request.getStatus());
435 
436         // let's double-check that before we start approving
437 
438         assertApproveRequested(document, user1, user2);
439         assertApproveNotRequested(document, testuser1, testuser2, testuser3, ewestfal);
440 
441         // approve as user1 and user2
442         document.switchPrincipal(user1);
443         document.approve("");
444         assertApproveRequested(document, user2);
445         assertApproveNotRequested(document, user1);
446         document.switchPrincipal(user2);
447         document.approve("");
448         assertTrue(document.isEnroute());
449 
450         assertApproveRequested(document, testuser1, testuser2);
451         assertApproveNotRequested(document, user1, user2, testuser3, ewestfal);
452 
453         // approve as testuser1 and testuser2
454         document.switchPrincipal(testuser1);
455         document.approve("");
456         document.switchPrincipal(testuser2);
457         document.approve("");
458         assertTrue(document.isEnroute());
459 
460         assertApproveRequested(document, testuser3, ewestfal);
461         assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
462 
463         // now approve as ewestfal and testuser3, then doc should be final
464         document.switchPrincipal(testuser3);
465         document.approve("");
466         document.switchPrincipal(ewestfal);
467         document.approve("");
468         assertTrue(document.isFinal());
469     }
470 
471     /**
472      * Test to verify that when forceAction=true for a PeopleFlow member, even if they've already approved this
473      * workflow, they still get an approval request.
474      *
475      * <p>Simple PeopleFlow with the same member at 2 stops - </p>
476      *
477      * <pre>
478      *
479      * Priority 1:
480      *   -> user1
481      * Priority 2:
482      *   -> user2
483      * Priority3:
484      *   -> user1 (forceAction = true)
485      *
486      * </pre>
487      */
488     @Test
489     public void test_SinglePeopleFlow_forceActionTrue() throws Exception {
490 
491         PeopleFlowDefinition.Builder peopleFlowBuilder = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_2);
492         peopleFlowBuilder.addPrincipal(user1).setPriority(1);
493         peopleFlowBuilder.addPrincipal(user2).setPriority(2);
494         peopleFlowBuilder.addPrincipal(user1).setPriority(3);
495         PeopleFlowDefinition peopleFlow = peopleFlowService.createPeopleFlow(peopleFlowBuilder.build());
496 
497         RulesEngineExecutorMock.setPeopleFlowId(peopleFlow.getId());
498 
499         // now route a document to it
500         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, RULESENGINE_PEOPLEFLOW_PRIORITYPARALLEL_APPROVE);
501 
502         document.route("");
503         assertTrue("Document should be enroute.", document.isEnroute());
504 
505         assertApproveRequested(document, user1);
506         assertApproveNotRequested(document, user2, user3);
507 
508         // approve as user1
509         document.switchPrincipal(user1);
510         document.approve("");
511         assertApproveRequested(document, user2);
512         assertApproveNotRequested(document, user1, user3);
513 
514         document.switchPrincipal(user2);
515         document.approve("");
516         assertTrue(document.isEnroute());
517 
518         // now user1 should have an approve request since forceAction is true
519         assertApproveRequested(document, user1);
520         assertApproveNotRequested(document, user2, user2);
521 
522         // approve as user1
523         document.switchPrincipal(user1);
524         document.approve("");
525         assertTrue(document.isFinal());
526     }
527 
528     /**
529      * Test to verify that when forceAction=false for a PeopleFlow member, if they've already approved this
530      * workflow previously, they won't get another approval request.
531      *
532      * <p>Simple PeopleFlow with the same member at 2 stops - </p>
533      *
534      * <pre>
535      *
536      * Priority 1:
537      *   -> user1
538      * Priority 2:
539      *   -> user2
540      * Priority3:
541      *   -> user1 (forceAction = false)
542      *
543      * </pre>
544      */
545     @Test
546     public void test_SinglePeopleFlow_forceActionFalse() throws Exception {
547 
548         PeopleFlowDefinition.Builder peopleFlowBuilder = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_2);
549         PeopleFlowMember.Builder member1 = peopleFlowBuilder.addPrincipal(user1);
550         member1.setPriority(1);
551         member1.setForceAction(false);
552 
553         PeopleFlowMember.Builder member2 = peopleFlowBuilder.addPrincipal(user2);
554         member2.setPriority(2);
555         member2.setForceAction(false);
556 
557         PeopleFlowMember.Builder member3 = peopleFlowBuilder.addPrincipal(user1);
558         member3.setPriority(3);
559         member3.setForceAction(false);
560 
561         PeopleFlowDefinition peopleFlow = peopleFlowService.createPeopleFlow(peopleFlowBuilder.build());
562 
563         RulesEngineExecutorMock.setPeopleFlowId(peopleFlow.getId());
564 
565         // now route a document to it
566         //        WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
567         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, RULESENGINE_PEOPLEFLOW_PRIORITYPARALLEL_APPROVE);
568 
569         document.route("");
570         assertTrue("Document should be enroute.", document.isEnroute());
571 
572         assertApproveRequested(document, user1);
573         assertApproveNotRequested(document, user2, user3);
574 
575         // approve as user1
576         document.switchPrincipal(user1);
577         document.approve("");
578         assertApproveRequested(document, user2);
579         assertApproveNotRequested(document, user1, user3);
580 
581         document.switchPrincipal(user2);
582         document.approve("");
583 
584         // Since user1 already approved, and forceAction=false, the doc should go right to final
585         assertTrue(document.isFinal());
586     }
587 
588     /**
589      * Defines PeopleFlow as follows:
590      *
591      * <pre>
592      *
593      * 1 - PeopleFlow - TEST:PeopleFlow1
594      *   -> Priority 1
595      *   ----> user1
596      *   -> Priority 2
597      *   ----> user2
598      * 2 - PeopleFlow - TEST:PeopleFlow2
599      *   -> Priority 1
600      *   ----> testuser1
601      *   -> Priority 2
602      *   ----> testuser2
603      * 3 - PeopleFlow - TEST:PeopleFlow3
604      *   -> Priority 1
605      *   ----> TestWorkgroup
606      *   -> Priority 10
607      *   ----> testuser3
608      *
609      * </pre>
610      */
611     private void createMultiplePeopleFlows() {
612         PeopleFlowDefinition.Builder peopleFlow1 = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_1);
613         peopleFlow1.addPrincipal(user1).setPriority(1);
614         peopleFlow1.addPrincipal(user2).setPriority(2);
615         peopleFlowService.createPeopleFlow(peopleFlow1.build());
616 
617         PeopleFlowDefinition.Builder peopleFlow2 = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_2);
618         peopleFlow2.addPrincipal(testuser1).setPriority(1);
619         peopleFlow2.addPrincipal(testuser2).setPriority(2);
620         peopleFlowService.createPeopleFlow(peopleFlow2.build());
621 
622         PeopleFlowDefinition.Builder peopleFlow3 = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_3);
623         peopleFlow3.addGroup(testWorkgroup).setPriority(1);
624         peopleFlow3.addPrincipal(testuser3).setPriority(10);
625         peopleFlowService.createPeopleFlow(peopleFlow3.build());
626     }
627 
628 
629     @Test
630     public void test_MultiplePeopleFlow_PriorityParallel() throws Exception {
631         createMultiplePeopleFlows();
632 
633         // now route a document to it
634         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, MULTIPLE_PEOPLE_FLOW_PRIORITY_PARALLEL);
635         document.route("");
636         assertTrue("Document should be enroute.", document.isEnroute());
637 
638         // user3 should not have an approval request since they initiated the document
639         document.switchPrincipal(user3);
640 
641         // document should only send requests to the first people flow which should be user1 and user2
642         // But only user1 request should be activated
643 
644         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
645         assertEquals("Should have 2 root action requests", 2, rootActionRequests.size());
646         ActionRequest user1Request = null;
647         ActionRequest user2Request = null;
648         for (ActionRequest actionRequest : rootActionRequests) {
649             RecipientType recipientType = actionRequest.getRecipientType();
650             if (recipientType == RecipientType.PRINCIPAL) {
651                 if (user1.equals(actionRequest.getPrincipalId())) {
652                     user1Request = actionRequest;
653                 } else if (user2.equals(actionRequest.getPrincipalId())) {
654                     user2Request = actionRequest;
655                 }
656             }
657         }
658         // now let's ensure we got the requests we wanted
659         assertNotNull(user1Request);
660         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
661         assertNotNull(user2Request);
662         assertEquals(ActionRequestStatus.INITIALIZED, user2Request.getStatus());
663 
664         // now approve as user1
665         document.switchPrincipal(user1);
666         document.approve("");
667         document.switchPrincipal(user2);
668         assertTrue(document.isApprovalRequested());
669         document.approve("");
670 
671         // at this point, it should transition to the next people flow and generate Acknowledge requests to testuser1 and testuser2,
672         // and then generate an activated approve request to TestWorkgroup (of which "ewestfal" is a member) and then an
673         // initialized approve request to testuser3
674         assertTrue(document.isEnroute());
675         assertApproveRequested(document, ewestfal);
676         assertApproveNotRequested(document, user1, user2, testuser1, testuser2, testuser3);
677         assertAcknowledgeRequested(document, testuser1, testuser2);
678 
679         // now load as ewestfal (member of TestWorkgroup) and approve
680         document.switchPrincipal(ewestfal);
681         assertTrue(document.isApprovalRequested());
682         document.approve("");
683         assertTrue(document.isEnroute());
684 
685         // now the only remaining approval request should be to testuser3
686         assertApproveRequested(document, testuser3);
687         // just for fun, let's take testuser2's acknowledge action
688         document.switchPrincipal(testuser2);
689         assertTrue(document.isAcknowledgeRequested());
690         document.acknowledge("");
691         assertTrue(document.isEnroute());
692 
693         // testuser3 should still have an approve request, let's take it
694         assertApproveRequested(document, testuser3);
695         document.switchPrincipal(testuser3);
696         document.approve("");
697 
698         // document should now be in the processed state
699         assertTrue(document.isProcessed());
700         // load the last ack to testuser1 and take it
701         document.switchPrincipal(testuser1);
702         assertTrue(document.isAcknowledgeRequested());
703         document.acknowledge("");
704 
705         // now the document should be final!
706         assertTrue(document.isFinal());
707     }
708 
709     /**
710      * Defines a PeopleFlow as follows:
711      *
712      * <pre>
713      *
714      * Priority 1:
715      *   -> testuser3
716      *   ----> ppfTestRole2 - primary delegate
717      *
718      * </pre>
719      *
720      * this test will ensure that the delegate, a role, is properly delegated to when the primary responsible party is
721      * a principal.
722      */
723     @Test
724     public void test_PrincipalMember_roleDelegate() throws Exception {
725         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(testuser3, MemberType.PRINCIPAL);
726         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(ppfTestRole2, MemberType.ROLE);
727         delegate.setDelegationType(DelegationType.PRIMARY);
728         delegate.setActionRequestPolicy(ActionRequestPolicy.FIRST);
729 
730         createSimplePeopleFlow(PEOPLE_FLOW_8, member, delegate);
731 
732         // now route a document to it
733         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_PRINCIPAL_MEMBER_HAS_ROLE_DELEGATE);
734         document.route("");
735         assertTrue("Document should be enroute.", document.isEnroute());
736 
737         // testuser3 and delegate user2 (as member of ppfTestRole2) should have
738         // activated requests, make sure the requests look correct
739 
740         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
741         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
742         ActionRequest testuser3Request = null;
743         for (ActionRequest actionRequest : rootActionRequests) {
744             RecipientType recipientType = actionRequest.getRecipientType();
745             if (recipientType == RecipientType.PRINCIPAL) {
746                 if (testuser3.equals(actionRequest.getPrincipalId())) {
747                     testuser3Request = actionRequest;
748                 }
749             }
750         }
751 
752         // now let's ensure we got the requests we wanted
753         assertNotNull(testuser3Request);
754         assertEquals(ActionRequestStatus.ACTIVATED, testuser3Request.getStatus());
755 
756         // check delegate requests on testuser3Request now
757         assertEquals(1, testuser3Request.getChildRequests().size());
758         ActionRequest user2Request = testuser3Request.getChildRequests().get(0);
759         assertEquals(user2, user2Request.getPrincipalId());
760         assertEquals(DelegationType.PRIMARY, user2Request.getDelegationType());
761         assertEquals(ActionRequestStatus.ACTIVATED, user2Request.getStatus());
762 
763         // let's run through the approvals for this peopleflow
764         assertApproveRequested(document, user2, testuser3);
765         assertApproveNotRequested(document, user1, user3, testuser1, testuser2, ewestfal);
766 
767         // approve as user2 who is the lone member of testrole2
768         document.switchPrincipal(user2);
769         document.approve("");
770 
771         // at this point all priorty1 folks should have approvals
772         assertApproveNotRequested(document, user2, testuser3);
773 
774         // document should now be FINAL!
775         assertTrue(document.isFinal());
776     }
777 
778     /**
779      * Defines a PeopleFlow as follows:
780      *
781      * <pre>
782      *
783      * Priority 1:
784      *   -> ppfTestRole2
785      *   ----> testuser3 - primary delegate
786      *
787      * </pre>
788      *
789      * ensure that the delegate, a principal, gets the requests when the member is a role
790      */
791     @Test
792     public void test_RoleMember_principalDelegate() throws Exception {
793         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestRole2, MemberType.ROLE);
794         member.setActionRequestPolicy(ActionRequestPolicy.FIRST);
795         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(testuser3, MemberType.PRINCIPAL);
796         delegate.setDelegationType(DelegationType.PRIMARY);
797 
798         createSimplePeopleFlow(PEOPLE_FLOW_9, member, delegate);
799 
800         // now route a document to it
801         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MEMBER_HAS_PRINCIPAL_DELEGATE);
802         document.route("");
803         assertTrue("Document should be enroute.", document.isEnroute());
804 
805         // user2 (as member of ppfTestRole2) and delegate testuser3 should have
806         // activated requests, make sure the requests look correct
807 
808         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
809         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
810         ActionRequest user2Request = null;
811         for (ActionRequest actionRequest : rootActionRequests) {
812             RecipientType recipientType = actionRequest.getRecipientType();
813             if (recipientType == RecipientType.PRINCIPAL) {
814                 if (user2.equals(actionRequest.getPrincipalId())) {
815                     user2Request = actionRequest;
816                 }
817             }
818         }
819 
820         // now let's ensure we got the requests we wanted
821         assertNotNull(user2Request);
822         assertEquals(ActionRequestStatus.ACTIVATED, user2Request.getStatus());
823 
824         // check delegate requests on testuser3Request now
825         assertEquals(1, user2Request.getChildRequests().size());
826         ActionRequest testuser3Request = user2Request.getChildRequests().get(0);
827         assertEquals(testuser3, testuser3Request.getPrincipalId());
828         assertEquals(DelegationType.PRIMARY, testuser3Request.getDelegationType());
829         assertEquals(ActionRequestStatus.ACTIVATED, testuser3Request.getStatus());
830 
831         // let's run through the approvals for this peopleflow
832         assertApproveRequested(document, user2, testuser3);
833         assertApproveNotRequested(document, user1, user3, testuser1, testuser2, ewestfal);
834 
835         // approve as testuser3, the delegate
836         document.switchPrincipal(testuser3);
837         document.approve("");
838 
839         // at this point all priorty1 folks should have approvals
840         assertApproveNotRequested(document, user2, testuser3);
841 
842         // document should now be FINAL!
843         assertTrue(document.isFinal());
844 
845     }
846 
847     /**
848      * Defines a PeopleFlow as follows:
849      *
850      * <pre>
851      *
852      * Priority 1:
853      *   -> ppfTestRole1 (has delegate ewestfal defined in KIM)
854      *
855      * </pre>
856      *
857      * The desired behavior is that the KIM delegate gets requests
858      */
859     @Test
860     public void test_RoleDelegate_justKimDelegate() throws Exception {
861         createSimpleRoleDelegatePeopleFlow(PEOPLE_FLOW_4, // PeopleFlow name
862                 ppfTestRole1,  // member role ID
863                 null,          // no delegate
864                 null           // ^^ so no DelegationType
865         );
866 
867         // now route a document to it
868         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_JUST_KIM_DELEGATE);
869         document.route("");
870         assertTrue("Document should be enroute.", document.isEnroute());
871 
872         // user1 (as member of ppfTestRole1) and ewestfal (as user1's primary KIM delegate for ppfTestRole1) should have
873         // activated requests, make sure the requests look correct
874 
875         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
876         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
877         ActionRequest user1Request = null;
878         for (ActionRequest actionRequest : rootActionRequests) {
879             RecipientType recipientType = actionRequest.getRecipientType();
880             if (recipientType == RecipientType.PRINCIPAL) {
881                 if (user1.equals(actionRequest.getPrincipalId())) {
882                     user1Request = actionRequest;
883                 }
884             }
885         }
886 
887         // now let's ensure we got the requests we wanted
888         assertNotNull(user1Request);
889         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
890 
891         // check delegate requests on user1Request now
892         assertEquals(1, user1Request.getChildRequests().size());
893         ActionRequest ewestfalDelegateRequest = user1Request.getChildRequests().get(0);
894         assertEquals(ewestfal, ewestfalDelegateRequest.getPrincipalId());
895         assertEquals(DelegationType.PRIMARY, ewestfalDelegateRequest.getDelegationType());
896         assertEquals(ActionRequestStatus.ACTIVATED, ewestfalDelegateRequest.getStatus());
897 
898         // let's run through the approvals for this peopleflow
899         assertApproveRequested(document, user1, ewestfal);
900         assertApproveNotRequested(document, user2, user3, testuser1, testuser2, testuser3);
901 
902         // approve as ewestfal who is user1's primary KIM delegate for testrole1
903         document.switchPrincipal(ewestfal);
904         document.approve("");
905 
906         // at this point all priorty1 folks should have approvals
907         assertApproveNotRequested(document, user1, ewestfal);
908 
909         // document should now be FINAL!
910         assertTrue(document.isFinal());
911     }
912 
913 
914 
915     /**
916      * Defines a PeopleFlow as follows:
917      *
918      * <pre>
919      *
920      * Priority 1:
921      *   -> ppfTestRole1 (has delegate ewestfal defined in KIM)
922      *   ----> ppfTestRole2 - primary delegate
923      *
924      * </pre>
925      *
926      * The desired behavior is that the delegate defined in the PeopleFlow gets the requests, overriding the KIM
927      * delegate which gets ignored.  Since the delegation type is 'primary', only ppfTestRole2's member gets requests.
928      */
929     @Test
930     public void test_RoleDelegate_primaryDelegateRole() throws Exception {
931         createSimpleRoleDelegatePeopleFlow(PEOPLE_FLOW_5,    // PeopleFlow name
932                 ppfTestRole1,     // member role ID
933                 ppfTestRole2,     // delegate role ID
934                 DelegationType.PRIMARY);
935 
936         // now route a document to it
937         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_PRIMARY_DELEGATE);
938         document.route("");
939         assertTrue("Document should be enroute.", document.isEnroute());
940 
941         // user1 (as member of ppfTestRole1) and user2 (as a member of user1's primary delegate role for ppfTestRole1)
942         // should have activated requests, make sure the requests look correct
943 
944         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
945         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
946         ActionRequest user1Request = null;
947         for (ActionRequest actionRequest : rootActionRequests) {
948             RecipientType recipientType = actionRequest.getRecipientType();
949             if (recipientType == RecipientType.PRINCIPAL) {
950                 if (user1.equals(actionRequest.getPrincipalId())) {
951                     user1Request = actionRequest;
952                 }
953             }
954         }
955 
956         // now let's ensure we got the requests we wanted
957         assertNotNull(user1Request);
958         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
959 
960         // check delegate requests on user1Request now
961         assertEquals(1, user1Request.getChildRequests().size());
962         ActionRequest user2DelegateRequest = user1Request.getChildRequests().get(0);
963         assertEquals(user2, user2DelegateRequest.getPrincipalId());
964         assertEquals(DelegationType.PRIMARY, user2DelegateRequest.getDelegationType());
965         assertEquals(ActionRequestStatus.ACTIVATED, user2DelegateRequest.getStatus());
966 
967         // let's run through the approvals for this peopleflow
968         assertApproveRequested(document, user1, user2);
969         assertApproveNotRequested(document, user3, testuser1, testuser2, testuser3, ewestfal);
970 
971         // approve as user2 who is user1's primary PPF delegate for testrole1
972         document.switchPrincipal(user2);
973         document.approve("");
974 
975         // at this point all priorty1 folks should have approvals
976         assertApproveNotRequested(document, user1, user2);
977 
978         // document should now be FINAL!
979         assertTrue(document.isFinal());
980     }
981 
982     /**
983      * Defines a PeopleFlow as follows:
984      *
985      * <pre>
986      *
987      * Priority 1:
988      *   -> ppfTestRole1 (has delegate ewestfal defined in KIM)
989      *   ----> ppfTestRole2 - secondary delegate
990      *
991      * </pre>
992      *
993      * The desired behavior is that the delegate defined in the PeopleFlow gets the requests, overriding the KIM
994      * delegate which gets ignored.  Since the delegation type is 'secondary', both ppfTestRole1 and ppfTestRole2 get
995      * requests.
996      */
997     @Test
998     public void test_RoleDelegate_secondaryDelegateRole() throws Exception {
999         createSimpleRoleDelegatePeopleFlow(
1000                 PEOPLE_FLOW_6,    // PeopleFlow name
1001                 ppfTestRole1,     // member role ID
1002                 ppfTestRole2,     // delegate role ID
1003                 DelegationType.SECONDARY
1004         );
1005 
1006         // now route a document to it
1007         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_SECONDARY_DELEGATE);
1008         document.route("");
1009         assertTrue("Document should be enroute.", document.isEnroute());
1010 
1011         // user1 (as member of ppfTestRole1) and user2 (as a member of user1's primary delegate role for ppfTestRole1)
1012         // should have activated requests, make sure the requests look correct
1013 
1014         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
1015         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
1016         ActionRequest user1Request = null;
1017         for (ActionRequest actionRequest : rootActionRequests) {
1018             RecipientType recipientType = actionRequest.getRecipientType();
1019             if (recipientType == RecipientType.PRINCIPAL) {
1020                 if (user1.equals(actionRequest.getPrincipalId())) {
1021                     user1Request = actionRequest;
1022                 }
1023             }
1024         }
1025 
1026         // now let's ensure we got the requests we wanted
1027         assertNotNull(user1Request);
1028         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
1029 
1030         // check delegate requests on user1Request now
1031         assertEquals(1, user1Request.getChildRequests().size());
1032         ActionRequest user2DelegateRequest = user1Request.getChildRequests().get(0);
1033         assertEquals(user2, user2DelegateRequest.getPrincipalId());
1034         assertEquals(DelegationType.SECONDARY, user2DelegateRequest.getDelegationType());
1035         assertEquals(ActionRequestStatus.ACTIVATED, user2DelegateRequest.getStatus());
1036 
1037         // let's run through the approvals for this peopleflow
1038         assertApproveRequested(document, user1, user2);
1039         assertApproveNotRequested(document, user3, testuser1, testuser2, testuser3, ewestfal);
1040 
1041         // approve as user2 who is user1's primary PPF delegate for testrole1
1042         document.switchPrincipal(user2);
1043         document.approve("");
1044 
1045         // at this point all priorty1 folks should have approvals
1046         assertApproveNotRequested(document, user1, user2);
1047 
1048         // document should now be FINAL!
1049         assertTrue(document.isFinal());
1050     }
1051 
1052     /**
1053      * Defines a PeopleFlow as follows:
1054      *
1055      * <pre>
1056      *
1057      * Priority 1:
1058      *   -> ppfTestRole2
1059      *   ----> ppfTestRole1 - primary delegate (+ has delegate ewestfal defined in KIM)
1060      *
1061      * </pre>
1062      *
1063      * KEW is limited to only one level of delegation, so the behavior will be to respect the delegate defined in the
1064      * PeopleFlow, but ignore the KIM delegate otherwise we'd have to add support for multi-level delegation.  Since
1065      * the PeopleFlow delegation is 'primary', ppfTestRole1 will get the requests.
1066      */
1067     @Test
1068     public void test_RoleDelegate_delegateRoleHasKimDelegate() throws Exception {
1069         createSimpleRoleDelegatePeopleFlow(PEOPLE_FLOW_7,    // PeopleFlow name
1070                 ppfTestRole2,     // member role ID
1071                 ppfTestRole1,     // delegate role ID
1072                 DelegationType.PRIMARY);
1073 
1074         // now route a document to it
1075         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_DELEGATE_ROLE_HAS_KIM_DELEGATE);
1076         document.route("");
1077         assertTrue("Document should be enroute.", document.isEnroute());
1078 
1079         // user2 (as member of ppfTestRole2) and user1 (as a member of user1's primary delegate role for ppfTestRole2)
1080         // should have activated requests, make sure the requests look correct
1081 
1082         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
1083         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
1084         ActionRequest user2Request = null;
1085         for (ActionRequest actionRequest : rootActionRequests) {
1086             RecipientType recipientType = actionRequest.getRecipientType();
1087             if (recipientType == RecipientType.PRINCIPAL) {
1088                 if (user2.equals(actionRequest.getPrincipalId())) {
1089                     user2Request = actionRequest;
1090                 }
1091             }
1092         }
1093 
1094         // now let's ensure we got the requests we wanted
1095         assertNotNull(user2Request);
1096         assertEquals(ActionRequestStatus.ACTIVATED, user2Request.getStatus());
1097 
1098         // check delegate requests on user1Request now
1099         assertEquals(1, user2Request.getChildRequests().size());
1100         ActionRequest user1DelegateRequest = user2Request.getChildRequests().get(0);
1101         assertEquals(user1, user1DelegateRequest.getPrincipalId());
1102         assertEquals(DelegationType.PRIMARY, user1DelegateRequest.getDelegationType());
1103         assertEquals(ActionRequestStatus.ACTIVATED, user1DelegateRequest.getStatus());
1104 
1105         // let's run through the approvals for this peopleflow
1106         assertApproveRequested(document, user1, user2);
1107         assertApproveNotRequested(document, user3, testuser1, testuser2, testuser3, ewestfal);
1108 
1109         // approve as user1 who is user2's primary PPF delegate for testrole2
1110         document.switchPrincipal(user1);
1111         document.approve("");
1112 
1113         // at this point all priorty1 folks should have approvals
1114         assertApproveNotRequested(document, user1, user2);
1115 
1116         // document should now be FINAL!
1117         assertTrue(document.isFinal());
1118     }
1119 
1120     /**
1121      * Defines a PeopleFlow as follows:
1122      *
1123      * <pre>
1124      *
1125      * Priority 1:
1126      *   -> ppfTestRole3
1127      *   ----> ppfTestRole4 - primary delegate
1128      *
1129      * </pre>
1130      *
1131      * this test will ensure that approvals work as expected when a role delegates to a role and both have
1132      * the action request policy ALL
1133      */
1134     @Test
1135     public void test_RoleDelegate_RoleMemberWithMultiplePrincipals_AllApprove() throws Exception {
1136         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestRole3, MemberType.ROLE);
1137         member.setActionRequestPolicy(ActionRequestPolicy.ALL);
1138         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(ppfTestRole4, MemberType.ROLE);
1139         delegate.setDelegationType(DelegationType.PRIMARY);
1140         delegate.setActionRequestPolicy(ActionRequestPolicy.ALL);
1141         createSimplePeopleFlow(PEOPLE_FLOW_10, member, delegate);
1142 
1143         // prove that if both members approve, the doc goes final
1144         {
1145             // route a document to the peopleflow
1146             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1147                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1148             document.route("");
1149             assertTrue("Document should be enroute.", document.isEnroute());
1150 
1151             // ppfTestRole3 members (user1, user2) delegate role ppfTestRole4 members (testuser1, testuser2) should have
1152             // activated requests
1153 
1154             // let's run through the approvals for this peopleflow
1155             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1156             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1157 
1158             // approve as user1 who a member of ppfTestRole3
1159             document.switchPrincipal(user1);
1160             document.approve("");
1161 
1162             // approve as user2 who is the second member of ppfTestRole3
1163             document.switchPrincipal(user2);
1164             document.approve("");
1165 
1166             // at this point all priorty1 folks should have approvals
1167             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1168 
1169             // document should now be FINAL!
1170             assertTrue(document.isFinal());
1171         }
1172 
1173         // prove that if both delegates approve, the doc goes final
1174         {
1175             // route a document to the peopleflow
1176             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1177                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1178             document.route("");
1179             assertTrue("Document should be enroute.", document.isEnroute());
1180 
1181             // ppfTestRole3 members (user1, user2) delegate role ppfTestRole4 members (testuser1, testuser2) should have
1182             // activated requests
1183 
1184             // let's run through the approvals for this peopleflow
1185             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1186             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1187 
1188             // approve as testuser1 who a member of ppfTestRole4
1189             document.switchPrincipal(testuser1);
1190             document.approve("");
1191 
1192             // approve as testuser2 who is the second member of ppfTestRole4
1193             document.switchPrincipal(testuser2);
1194             document.approve("");
1195 
1196             // at this point all priorty1 folks should have approvals
1197             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1198 
1199             // document should now be FINAL!
1200             assertTrue(document.isFinal());
1201         }
1202 
1203         // Prove that if a member approves, then both delegates need to approve due to the action request policy of
1204         // ALL for the doc to go final
1205         {
1206             // route a document to the peopleflow
1207             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1208                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1209             document.route("");
1210             assertTrue("Document should be enroute.", document.isEnroute());
1211 
1212             // ppfTestRole3 members (user1, user2) delegate role ppfTestRole4 members (testuser1, testuser2) should have
1213             // activated requests
1214 
1215             // let's run through the approvals for this peopleflow
1216             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1217             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1218 
1219             // approve as user1 who a member of ppfTestRole3
1220             document.switchPrincipal(user1);
1221             document.approve("");
1222 
1223             assertApproveNotRequested(document, user1);
1224 
1225             // approve as testuser1 who a member of ppfTestRole4
1226             document.switchPrincipal(testuser1);
1227             document.approve("");
1228 
1229             // approve as testuser2 who is the second member of ppfTestRole4
1230             document.switchPrincipal(testuser2);
1231             document.approve("");
1232 
1233             // at this point all priorty1 folks should have approvals
1234             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1235 
1236             // document should now be FINAL!
1237             assertTrue(document.isFinal());
1238         }
1239     }
1240 
1241     /**
1242      * Defines a PeopleFlow as follows:
1243      *
1244      * <pre>
1245      *
1246      * Priority 1:
1247      *   -> ppfTestRole3
1248      *   ----> ppfTestRole4 - primary delegate
1249      *
1250      * </pre>
1251      *
1252      * The action request policy for each role is set to FIRST.
1253      * this test will verify that when one delegate approves, the document goes final.
1254      */
1255     @Test
1256     public void test_RoleDelegate_RoleMemberWithMultiplePrincipals_FirstApprove() throws Exception {
1257         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestRole3, MemberType.ROLE);
1258         member.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1259         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(ppfTestRole4, MemberType.ROLE);
1260         delegate.setDelegationType(DelegationType.PRIMARY);
1261         delegate.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1262 
1263         createSimplePeopleFlow(PEOPLE_FLOW_11, member, delegate);
1264 
1265         // First, prove that just one of the delegates needs to approve for the doc to go final:
1266         {
1267             // route a document to it
1268             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1269                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_FIRST_APPROVE);
1270             document.route("");
1271             assertTrue("Document should be enroute.", document.isEnroute());
1272 
1273             // verify the expected initial state
1274             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1275             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1276 
1277             // approve as testuser1 who a member of ppfTestRole4
1278             document.switchPrincipal(testuser1);
1279             document.approve("");
1280 
1281             assertApproveNotRequested(document, user1, user2, testuser1, testuser2, user3, ewestfal);
1282 
1283             assertTrue(document.isFinal());
1284         }
1285 
1286         // prove that just one of the members needs to approve for the doc to go final:
1287         {
1288             // route a document to it
1289             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1290                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_FIRST_APPROVE);
1291             document.route("");
1292             assertTrue("Document should be enroute.", document.isEnroute());
1293 
1294             // verify the expected initial state
1295             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1296             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1297 
1298             // approve as user1 who a member of ppfTestRole3
1299             document.switchPrincipal(user1);
1300             document.approve("");
1301 
1302             assertApproveNotRequested(document, user1, user2, testuser1, testuser2, user3, ewestfal);
1303 
1304             assertTrue(document.isFinal());
1305         }
1306 
1307     }
1308 
1309     /**
1310      * Defines a PeopleFlow as follows:
1311      *
1312      * <pre>
1313      *
1314      * Priority 1:
1315      *   -> ppfTestRole3
1316      *   ----> ppfTestRole4 - primary delegate
1317      *
1318      * </pre>
1319      *
1320      * this test will ensure that the delegate, a role is properly delegated to when the member is a principal
1321      */
1322     @Test
1323     public void test_RoleDelegate_RoleMemberWithMultiplePrincipals_DelegateFirstApprove() throws Exception {
1324         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestRole3, MemberType.ROLE);
1325         member.setActionRequestPolicy(ActionRequestPolicy.ALL);
1326         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(ppfTestRole4, MemberType.ROLE);
1327         delegate.setDelegationType(DelegationType.PRIMARY);
1328         delegate.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1329         createSimplePeopleFlow(PEOPLE_FLOW_12, member, delegate);
1330 
1331         // prove that both members need to approve before the doc goes final (due to the
1332         // ALL action request policy on the member role).
1333         {
1334             // now route a document to it
1335             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_DELEGATE_FIRST_APPROVE);
1336             document.route("");
1337             assertTrue("Document should be enroute.", document.isEnroute());
1338 
1339 
1340             // verify initial state
1341             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1342             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1343 
1344             // approve as user1 who is a member of ppfTestRole3
1345             document.switchPrincipal(user1);
1346             document.approve("");
1347 
1348             assertApproveRequested(document, user2, testuser1, testuser2);
1349             assertApproveNotRequested(document, user1);
1350 
1351             // approve as user2 who is a member of ppfTestRole3
1352             document.switchPrincipal(user2);
1353             document.approve("");
1354 
1355             // at this point all priorty1 folks should have approvals
1356             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1357 
1358             // document should now be FINAL!
1359             assertTrue(document.isFinal());
1360         }
1361 
1362         // prove that only one delegate needs to approve due to action request policy FIRST on the delegate role
1363         {
1364             // now route a document to it
1365             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_DELEGATE_FIRST_APPROVE);
1366             document.route("");
1367             assertTrue("Document should be enroute.", document.isEnroute());
1368 
1369 
1370             // let's run through the approvals for this peopleflow
1371             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1372             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1373 
1374             // approve as testuser1 who is a member of ppfTestRole4
1375             document.switchPrincipal(testuser1);
1376             document.approve("");
1377 
1378             // at this point all priorty1 folks should have approvals
1379             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1380 
1381             // document should now be FINAL!
1382             assertTrue(document.isFinal());
1383         }
1384 
1385         // prove that if one member approves and then one delegate approves, the doc goes final (due to the
1386         // ALL action request policy on the member role).
1387         {
1388             // now route a document to it
1389             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_DELEGATE_FIRST_APPROVE);
1390             document.route("");
1391             assertTrue("Document should be enroute.", document.isEnroute());
1392 
1393 
1394             // verify initial state
1395             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1396             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1397 
1398             // approve as user1 who is a member of ppfTestRole3
1399             document.switchPrincipal(user1);
1400             document.approve("");
1401 
1402             assertApproveRequested(document, user2, testuser1, testuser2);
1403             assertApproveNotRequested(document, user1);
1404 
1405             // approve as testuser1 who is a member of ppfTestRole4
1406             document.switchPrincipal(testuser1);
1407             document.approve("");
1408 
1409             // at this point all priorty1 folks should have approvals
1410             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1411 
1412             // document should now be FINAL!
1413             assertTrue(document.isFinal());
1414         }
1415     }
1416 
1417     /**
1418      * Defines a PeopleFlow as follows:
1419      *
1420      * <pre>
1421      *
1422      * Priority 1:
1423      *   -> ppfTestGroup1
1424      *   ----> ppfTestRole4 - primary delegate
1425      *
1426      * </pre>
1427      *
1428      * this test will verify that groups can delegate to roles, and that the ALL approval logic will hold for the
1429      * delegate
1430      */
1431     @Test
1432     public void test_GroupDelegate_RoleMemberWithMultiplePrincipals_AllApprove() throws Exception {
1433         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestGroup1, MemberType.GROUP);
1434         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(ppfTestRole4, MemberType.ROLE);
1435         delegate.setDelegationType(DelegationType.PRIMARY);
1436         delegate.setActionRequestPolicy(ActionRequestPolicy.ALL);
1437         createSimplePeopleFlow(PEOPLE_FLOW_13, member, delegate);
1438 
1439         // prove that one group member approving makes the doc go final
1440         {
1441             // now route a document to it
1442             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1443                     GROUP_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1444             document.route("");
1445             assertTrue("Document should be enroute.", document.isEnroute());
1446 
1447             // let's run through the approvals for this peopleflow
1448             assertApproveRequested(document, earl, fran, testuser1, testuser2);
1449             assertApproveNotRequested(document, user1, user2, user3, testuser3, ewestfal);
1450 
1451             // approve as earl who a member of ppfTestGroup1
1452             document.switchPrincipal(earl);
1453             document.approve("");
1454 
1455             // at this point all priorty1 folks should have approvals
1456             assertApproveNotRequested(document, user1, user2, earl, fran, testuser1, testuser2);
1457 
1458             // document should now be FINAL!
1459             assertTrue(document.isFinal());
1460         }
1461 
1462         // prove that both delegates need to approve (due to action request policy ALL) before the doc goes final
1463         {
1464             // now route a document to it
1465             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1466                     GROUP_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1467             document.route("");
1468             assertTrue("Document should be enroute.", document.isEnroute());
1469 
1470             assertApproveRequested(document, earl, fran, testuser1, testuser2);
1471             assertApproveNotRequested(document, user1, user2, user3, testuser3, ewestfal);
1472 
1473             // approve as testuser1 who a member of ppfTestRole4
1474             document.switchPrincipal(testuser1);
1475             document.approve("");
1476 
1477             assertFalse(document.isFinal());
1478 
1479             // approve as testuser2 who a member of ppfTestRole4
1480             document.switchPrincipal(testuser2);
1481             document.approve("");
1482 
1483             // at this point all priorty1 folks should have approvals
1484             assertApproveNotRequested(document, user1, user2, earl, fran, testuser1, testuser2);
1485 
1486             // document should now be FINAL!
1487             assertTrue(document.isFinal());
1488         }
1489     }
1490 
1491     /**
1492      * creates a simple PeopleFlow in the TEST namespace with (by default) a member of type role having a delegate of
1493      * type role as follows:
1494      *
1495      * <pre>
1496      *
1497      * Priority 1:
1498      *   -> memberRole
1499      *   ----> delegateRole
1500      *
1501      * </pre>
1502      *
1503      * The member and delegate roles are specified by ID as memberRoleId and delegateRoleId.
1504      * The type of the delegate (primary or secondary) is specified by delegationType.
1505      * If the delegate ID is null, no delegate will be added.
1506      *
1507      * @param peopleFlowName the name to give the new PeopleFlow (the namespace will always be TEST)
1508      * @param memberRoleId the ID of the role for the PeopleFlow member
1509      * @param delegateRoleId the ID of the role for the PeopleFlow member's delegate
1510      * @param delegationType the delegate's type (primary or secondary)
1511      * @return the PeopleFlowDefinition created
1512      */
1513     private PeopleFlowDefinition createSimpleRoleDelegatePeopleFlow(String peopleFlowName, String memberRoleId, String delegateRoleId,
1514             DelegationType delegationType) {
1515         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, peopleFlowName);
1516 
1517         // build stop 1
1518         // build role member
1519         PeopleFlowMember.Builder memberBuilder = peopleFlow.addRole(memberRoleId);
1520         memberBuilder.setPriority(1);
1521         memberBuilder.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1522 
1523         if (delegateRoleId != null) {
1524             // build primary delegate role1
1525             PeopleFlowDelegate.Builder delegateBuilder =
1526                     PeopleFlowDelegate.Builder.create(delegateRoleId, MemberType.ROLE);
1527             delegateBuilder.setDelegationType(delegationType);
1528             delegateBuilder.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1529 
1530             memberBuilder.getDelegates().add(delegateBuilder);
1531         }
1532 
1533         return peopleFlowService.createPeopleFlow(peopleFlow.build());
1534     }
1535 
1536     /**
1537      * creates a simple PeopleFlow in the TEST namespace with a member having a delegate, like so:
1538      *
1539      * <pre>
1540      *
1541      * Priority 1:
1542      *   -> member
1543      *   ----> delegate
1544      *
1545      * </pre>
1546      *
1547      * @return the PeopleFlowDefinition created
1548      */
1549     private PeopleFlowDefinition createSimplePeopleFlow(String peopleFlowName, PeopleFlowMember.Builder member, PeopleFlowDelegate.Builder delegate) {
1550         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, peopleFlowName);
1551 
1552         member.setPriority(1);
1553 
1554         if (delegate != null) {
1555             // link delegate to member
1556             member.getDelegates().add(delegate);
1557         }
1558 
1559         peopleFlow.getMembers().add(member);
1560 
1561         return peopleFlowService.createPeopleFlow(peopleFlow.build());
1562     }
1563 
1564     /**
1565      * Defines a PeopleFlow as follows:
1566      *
1567      * <pre>
1568      *
1569      * Priority 1:
1570      *   -> user1
1571      *   -> user2
1572      *   ----> testuser2 - primary delegate
1573      * Priority 2:
1574      *   -> testuser1
1575      *   ----> TestWorkgroup - secondary delegate
1576      *   ----> testuser3 - primary delegate
1577      *   -> user3
1578      *
1579      * </pre>
1580      */
1581     private void createDelegatePeopleFlow() {
1582         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_1);
1583         peopleFlow.addPrincipal(user1).setPriority(1);
1584 
1585         PeopleFlowMember.Builder user2Builder = peopleFlow.addPrincipal(user2);
1586         user2Builder.setPriority(1);
1587         PeopleFlowDelegate.Builder user2PrimaryDelegateBuilder = PeopleFlowDelegate.Builder.create(testuser2,
1588                 MemberType.PRINCIPAL);
1589         user2PrimaryDelegateBuilder.setDelegationType(DelegationType.PRIMARY);
1590         user2Builder.getDelegates().add(user2PrimaryDelegateBuilder);
1591 
1592         PeopleFlowMember.Builder testuser1Builder = peopleFlow.addPrincipal(testuser1);
1593         testuser1Builder.setPriority(2);
1594         PeopleFlowDelegate.Builder testWorkgroupSecondaryDelegateBuilder = PeopleFlowDelegate.Builder.create(testWorkgroup, MemberType.GROUP);
1595         testWorkgroupSecondaryDelegateBuilder.setDelegationType(DelegationType.SECONDARY);
1596         testuser1Builder.getDelegates().add(testWorkgroupSecondaryDelegateBuilder);
1597         PeopleFlowDelegate.Builder testuser3PrimaryDelegateBuilder = PeopleFlowDelegate.Builder.create(testuser3, MemberType.PRINCIPAL);
1598         testuser3PrimaryDelegateBuilder.setDelegationType(DelegationType.PRIMARY);
1599         testuser1Builder.getDelegates().add(testuser3PrimaryDelegateBuilder);
1600 
1601         peopleFlow.addPrincipal(user3).setPriority(2);
1602 
1603         peopleFlowService.createPeopleFlow(peopleFlow.build());
1604     }
1605 
1606     @Test
1607     public void test_DelegatePeopleFlow_PriorityParallel_Approve() throws Exception {
1608         createDelegatePeopleFlow();
1609 
1610         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, DELEGATE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
1611         document.route("");
1612         assertTrue("Document should be enroute.", document.isEnroute());
1613 
1614         // user3 should not have an approval request since they initiated the document
1615         document.switchPrincipal(user3);
1616 
1617         // user1, user2, and testuser2 (as user2's primary delegate) should all have activated requests, make sure the requests look correct
1618         // user3 and testuser1 should have root requests as well, TestWorkgroup and testuser3 should be delegates of testuser1
1619 
1620         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
1621         assertEquals("Should have 4 root action requests", 4, rootActionRequests.size());
1622         ActionRequest user1Request = null;
1623         ActionRequest user2Request = null;
1624         ActionRequest user3Request = null;
1625         ActionRequest testuser1Request = null;
1626         for (ActionRequest actionRequest : rootActionRequests) {
1627             RecipientType recipientType = actionRequest.getRecipientType();
1628             if (recipientType == RecipientType.PRINCIPAL) {
1629                 if (user1.equals(actionRequest.getPrincipalId())) {
1630                     user1Request = actionRequest;
1631                 } else if (user2.equals(actionRequest.getPrincipalId())) {
1632                     user2Request = actionRequest;
1633                 } else if (user3.equals(actionRequest.getPrincipalId())) {
1634                     user3Request = actionRequest;
1635                 } else if (testuser1.equals(actionRequest.getPrincipalId())) {
1636                     testuser1Request = actionRequest;
1637                 }
1638             }
1639         }
1640         // now let's ensure we got the requests we wanted
1641         assertNotNull(user1Request);
1642         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
1643         assertNotNull(user2Request);
1644         assertEquals(ActionRequestStatus.ACTIVATED, user2Request.getStatus());
1645         assertNotNull(user3Request);
1646         assertEquals(ActionRequestStatus.INITIALIZED, user3Request.getStatus());
1647         assertNotNull(testuser1Request);
1648         assertEquals(ActionRequestStatus.INITIALIZED, testuser1Request.getStatus());
1649 
1650         // check delegate requests on user2Request now
1651         assertEquals(1, user2Request.getChildRequests().size());
1652         ActionRequest testuser2DelegateRequest = user2Request.getChildRequests().get(0);
1653         assertEquals(testuser2, testuser2DelegateRequest.getPrincipalId());
1654         assertEquals(DelegationType.PRIMARY, testuser2DelegateRequest.getDelegationType());
1655         assertEquals(ActionRequestStatus.ACTIVATED, testuser2DelegateRequest.getStatus());
1656 
1657         // check delegate requests on testuser1Request now
1658         assertEquals(2, testuser1Request.getChildRequests().size());
1659         ActionRequest testWorkgroupRequest = null;
1660         ActionRequest testuser3Request = null;
1661         for (ActionRequest childActionRequest : testuser1Request.getChildRequests()) {
1662             RecipientType recipientType = childActionRequest.getRecipientType();
1663             if (recipientType == RecipientType.PRINCIPAL) {
1664                 if (testuser3.equals(childActionRequest.getPrincipalId())) {
1665                     testuser3Request = childActionRequest;
1666                 }
1667             } else if (recipientType == RecipientType.GROUP) {
1668                 if (testWorkgroup.equals(childActionRequest.getGroupId())) {
1669                     testWorkgroupRequest = childActionRequest;
1670                 }
1671             }
1672         }
1673         assertNotNull(testWorkgroupRequest);
1674         assertEquals(ActionRequestStatus.INITIALIZED, testWorkgroupRequest.getStatus());
1675         assertEquals(DelegationType.SECONDARY, testWorkgroupRequest.getDelegationType());
1676         assertNotNull(testuser3Request);
1677         assertEquals(ActionRequestStatus.INITIALIZED, testuser3Request.getStatus());
1678         assertEquals(DelegationType.PRIMARY, testuser3Request.getDelegationType());
1679 
1680         // whew! now that that's done, let's run through the approvals for this peopleflow
1681         assertApproveRequested(document, user1, user2, testuser2);
1682         assertApproveNotRequested(document, testuser1, user3, ewestfal, testuser3);
1683         // approve as testuser2 who is user2's primary delegate
1684         document.switchPrincipal(testuser2);
1685         document.approve("");
1686 
1687         // now approve as user1, this should push it to priority 2 in the peopleflow
1688         assertApproveRequested(document, user1);
1689         assertApproveNotRequested(document, user2, testuser2, testuser1, user3, ewestfal, testuser3);
1690         document.switchPrincipal(user1);
1691         document.approve("");
1692 
1693         // at this point all priorty2 folks should have approvals
1694         assertApproveRequested(document, testuser1, user3, ewestfal, testuser3);
1695         assertApproveNotRequested(document, user1, user2, testuser2);
1696         // approve as ewestfal, a member of TestWorkgroup which is a delegate of testuser1
1697         document.switchPrincipal(ewestfal);
1698         document.approve("");
1699 
1700         // the only remaining approval at this point should be to user3, note that user3 initiated the document, but forceAction should = true by default on peopleflows
1701         assertApproveRequested(document, user3);
1702         assertApproveNotRequested(document, user1, user2, testuser2, testuser1, ewestfal, testuser3);
1703         document.switchPrincipal(user3);
1704         document.approve("");
1705 
1706         // document should now be FINAL!
1707         assertTrue(document.isFinal());
1708 
1709     }
1710 
1711     private String roleId = null;
1712     /**
1713      * Defines a PeopleFlow with a single first approve role, that role has two members, one principal and one group.
1714      */
1715     private void createFirstApproveRolePeopleFlow() {
1716         RoleService roleService = KimApiServiceLocator.getRoleService();
1717         Role role = roleService.getRoleByNamespaceCodeAndName("KR-SYS", "Technical Administrator");
1718         assertNotNull("Technical Administrator role should exist!", role);
1719         assertEquals(2, roleService.getRoleMembers(Collections.singletonList(role.getId()),
1720                 new HashMap<String, String>()).size());
1721         roleId = role.getId();
1722 
1723         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_2);
1724         PeopleFlowMember.Builder memberBuilder = peopleFlow.addRole(role.getId());
1725         memberBuilder.setPriority(1);
1726         memberBuilder.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1727         peopleFlowService.createPeopleFlow(peopleFlow.build());
1728     }
1729 
1730     @Test
1731     public void test_FirstApproveRolePeopleFlow() throws Exception {
1732         createFirstApproveRolePeopleFlow();
1733 
1734         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
1735         document.route("");
1736         assertTrue("Document should be enroute.", document.isEnroute());
1737 
1738         // should have 1 root requests which is a role request with 2 children, one a principal request to the "admin"
1739         // principal, and one a group request to the WorkflowAdmin group
1740         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
1741         assertEquals(1, rootActionRequests.size());
1742         ActionRequest roleRequest = rootActionRequests.get(0);
1743         assertEquals(ActionRequestPolicy.FIRST, roleRequest.getRequestPolicy());
1744         assertEquals(roleId, roleRequest.getRoleName());
1745         assertEquals(RecipientType.ROLE, roleRequest.getRecipientType());
1746         assertEquals(2, roleRequest.getChildRequests().size());
1747         for (ActionRequest childRequest : roleRequest.getChildRequests()) {
1748             if (RecipientType.PRINCIPAL.equals(childRequest.getRecipientType())) {
1749                 assertEquals(getPrincipalIdForName("admin"), childRequest.getPrincipalId());
1750             } else if (RecipientType.GROUP.equals(childRequest.getRecipientType())) {
1751                 assertEquals(getGroupIdForName("KR-WKFLW", "WorkflowAdmin"), childRequest.getGroupId());
1752             } else {
1753                 fail("Found a child request i didn't expect with a recipient type of: " + childRequest.getRecipientType());
1754             }
1755         }
1756 
1757         // should be able to approve as a member of the group on Technical Administrator role (which is WorkflowAdmin) as
1758         // well as the 'admin' principal
1759         document.switchPrincipal(getPrincipalNameForId("admin"));
1760         assertTrue(document.isApprovalRequested());
1761         document.switchPrincipal(getPrincipalIdForName("bmcgough"));
1762         assertTrue(document.isApprovalRequested());
1763 
1764         // now approve as a member of WorkflowAdmin
1765         document.approve("");
1766 
1767         // document should now be final because it's first approve
1768         assertTrue(document.isFinal());
1769 
1770         // now try it by approving as admin, and ensure that the first approval works as well in that case
1771         document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
1772         document.route("");
1773         assertTrue("Document should be enroute.", document.isEnroute());
1774         document.switchPrincipal(getPrincipalIdForName("bmcgough"));
1775         assertTrue(document.isApprovalRequested());
1776         document.switchPrincipal(getPrincipalNameForId("admin"));
1777         assertTrue(document.isApprovalRequested());
1778         // now approve as admin
1779         document.approve("");
1780         // document should now be final because it's first approve
1781         assertTrue(document.isFinal());
1782     }
1783 
1784     /**
1785      * Defines a PeopleFlow with a single all approve role, that role has two members, one principal and one group.
1786      */
1787     private void createAllApproveRolePeopleFlow() {
1788         RoleService roleService = KimApiServiceLocator.getRoleService();
1789         Role role = roleService.getRoleByNamespaceCodeAndName("KR-SYS", "Technical Administrator");
1790         assertNotNull("Technical Administrator role should exist!", role);
1791         assertEquals(2, roleService.getRoleMembers(Collections.singletonList(role.getId()),
1792                 new HashMap<String, String>()).size());
1793         roleId = role.getId();
1794 
1795         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_2);
1796         PeopleFlowMember.Builder memberBuilder = peopleFlow.addRole(role.getId());
1797         memberBuilder.setPriority(1);
1798         memberBuilder.setActionRequestPolicy(ActionRequestPolicy.ALL);
1799         peopleFlowService.createPeopleFlow(peopleFlow.build());
1800     }
1801 
1802     @Test
1803     public void test_AllApproveRolePeopleFlow() throws Exception {
1804         createAllApproveRolePeopleFlow();
1805 
1806         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
1807         document.route("");
1808         assertTrue("Document should be enroute.", document.isEnroute());
1809 
1810         // should have 1 root requests which is a role request with 2 children, one a principal request to the "admin"
1811         // principal, and one a group request to the WorkflowAdmin group
1812         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
1813         assertEquals(1, rootActionRequests.size());
1814         ActionRequest roleRequest = rootActionRequests.get(0);
1815         assertEquals(ActionRequestPolicy.ALL, roleRequest.getRequestPolicy());
1816         assertEquals(roleId, roleRequest.getRoleName());
1817         assertEquals(RecipientType.ROLE, roleRequest.getRecipientType());
1818         assertEquals(2, roleRequest.getChildRequests().size());
1819         for (ActionRequest childRequest : roleRequest.getChildRequests()) {
1820             if (RecipientType.PRINCIPAL.equals(childRequest.getRecipientType())) {
1821                 assertEquals(getPrincipalIdForName("admin"), childRequest.getPrincipalId());
1822             } else if (RecipientType.GROUP.equals(childRequest.getRecipientType())) {
1823                 assertEquals(getGroupIdForName("KR-WKFLW", "WorkflowAdmin"), childRequest.getGroupId());
1824             } else {
1825                 fail("Found a child request i didn't expect with a recipient type of: " + childRequest.getRecipientType());
1826             }
1827         }
1828 
1829         // should be able to approve as a member of the group on Technical Administrator role (which is WorkflowAdmin) as
1830         // well as the 'admin' principal
1831         document.switchPrincipal(getPrincipalNameForId("admin"));
1832         assertTrue(document.isApprovalRequested());
1833         document.switchPrincipal(getPrincipalIdForName("bmcgough"));
1834         assertTrue(document.isApprovalRequested());
1835 
1836         // now approve as a member of WorkflowAdmin
1837         document.approve("");
1838 
1839         // document should still be enroute because this is an all approve situation and both the group and admin need to approve
1840         assertTrue(document.isEnroute());
1841         assertFalse(document.isApprovalRequested());
1842 
1843         document.switchPrincipal(getPrincipalNameForId("admin"));
1844         assertTrue(document.isApprovalRequested());
1845         document.approve("");
1846         // after approving as admin, the last of the two role requests have been completed, document should be final
1847         assertTrue(document.isFinal());
1848     }
1849     
1850     private void assertApproveRequested(WorkflowDocument document, String... principalIds) {
1851         for (String principalId : principalIds) {
1852             document.switchPrincipal(principalId);
1853             assertTrue("Approve should have been requested for '" + principalId + "'", document.isApprovalRequested());
1854         }
1855     }
1856 
1857     private void assertAcknowledgeRequested(WorkflowDocument document, String... principalIds) {
1858         for (String principalId : principalIds) {
1859             document.switchPrincipal(principalId);
1860             assertTrue("Acknowledge should have been requested for '" + principalId + "'", document.isAcknowledgeRequested());
1861         }
1862     }
1863 
1864     private void assertApproveNotRequested(WorkflowDocument document, String... principalIds) {
1865         for (String principalId : principalIds) {
1866             document.switchPrincipal(principalId);
1867             assertFalse("Approve should *NOT* have been requested for '" + principalId + "'", document.isApprovalRequested());
1868         }
1869     }
1870 
1871 }