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