View Javadoc

1   /**
2    * Copyright 2005-2013 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         delegate.setActionRequestPolicy(ActionRequestPolicy.FIRST);
608 
609         createSimplePeopleFlow(PEOPLE_FLOW_8, member, delegate);
610 
611         // now route a document to it
612         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_PRINCIPAL_MEMBER_HAS_ROLE_DELEGATE);
613         document.route("");
614         assertTrue("Document should be enroute.", document.isEnroute());
615 
616         // testuser3 and delegate user2 (as member of ppfTestRole2) should have
617         // activated requests, make sure the requests look correct
618 
619         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
620         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
621         ActionRequest testuser3Request = null;
622         for (ActionRequest actionRequest : rootActionRequests) {
623             RecipientType recipientType = actionRequest.getRecipientType();
624             if (recipientType == RecipientType.PRINCIPAL) {
625                 if (testuser3.equals(actionRequest.getPrincipalId())) {
626                     testuser3Request = actionRequest;
627                 }
628             }
629         }
630 
631         // now let's ensure we got the requests we wanted
632         assertNotNull(testuser3Request);
633         assertEquals(ActionRequestStatus.ACTIVATED, testuser3Request.getStatus());
634 
635         // check delegate requests on testuser3Request now
636         assertEquals(1, testuser3Request.getChildRequests().size());
637         ActionRequest user2Request = testuser3Request.getChildRequests().get(0);
638         assertEquals(user2, user2Request.getPrincipalId());
639         assertEquals(DelegationType.PRIMARY, user2Request.getDelegationType());
640         assertEquals(ActionRequestStatus.ACTIVATED, user2Request.getStatus());
641 
642         // let's run through the approvals for this peopleflow
643         assertApproveRequested(document, user2, testuser3);
644         assertApproveNotRequested(document, user1, user3, testuser1, testuser2, ewestfal);
645 
646         // approve as user2 who is the lone member of testrole2
647         document.switchPrincipal(user2);
648         document.approve("");
649 
650         // at this point all priorty1 folks should have approvals
651         assertApproveNotRequested(document, user2, testuser3);
652 
653         // document should now be FINAL!
654         assertTrue(document.isFinal());
655     }
656 
657     /**
658      * Defines a PeopleFlow as follows:
659      *
660      * <pre>
661      *
662      * Priority 1:
663      *   -> ppfTestRole2
664      *   ----> testuser3 - primary delegate
665      *
666      * </pre>
667      *
668      * ensure that the delegate, a principal, gets the requests when the member is a role
669      */
670     @Test
671     public void test_RoleMember_principalDelegate() throws Exception {
672         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestRole2, MemberType.ROLE);
673         member.setActionRequestPolicy(ActionRequestPolicy.FIRST);
674         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(testuser3, MemberType.PRINCIPAL);
675         delegate.setDelegationType(DelegationType.PRIMARY);
676 
677         createSimplePeopleFlow(PEOPLE_FLOW_9, member, delegate);
678 
679         // now route a document to it
680         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MEMBER_HAS_PRINCIPAL_DELEGATE);
681         document.route("");
682         assertTrue("Document should be enroute.", document.isEnroute());
683 
684         // user2 (as member of ppfTestRole2) and delegate testuser3 should have
685         // activated requests, make sure the requests look correct
686 
687         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
688         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
689         ActionRequest user2Request = null;
690         for (ActionRequest actionRequest : rootActionRequests) {
691             RecipientType recipientType = actionRequest.getRecipientType();
692             if (recipientType == RecipientType.PRINCIPAL) {
693                 if (user2.equals(actionRequest.getPrincipalId())) {
694                     user2Request = actionRequest;
695                 }
696             }
697         }
698 
699         // now let's ensure we got the requests we wanted
700         assertNotNull(user2Request);
701         assertEquals(ActionRequestStatus.ACTIVATED, user2Request.getStatus());
702 
703         // check delegate requests on testuser3Request now
704         assertEquals(1, user2Request.getChildRequests().size());
705         ActionRequest testuser3Request = user2Request.getChildRequests().get(0);
706         assertEquals(testuser3, testuser3Request.getPrincipalId());
707         assertEquals(DelegationType.PRIMARY, testuser3Request.getDelegationType());
708         assertEquals(ActionRequestStatus.ACTIVATED, testuser3Request.getStatus());
709 
710         // let's run through the approvals for this peopleflow
711         assertApproveRequested(document, user2, testuser3);
712         assertApproveNotRequested(document, user1, user3, testuser1, testuser2, ewestfal);
713 
714         // approve as testuser3, the delegate
715         document.switchPrincipal(testuser3);
716         document.approve("");
717 
718         // at this point all priorty1 folks should have approvals
719         assertApproveNotRequested(document, user2, testuser3);
720 
721         // document should now be FINAL!
722         assertTrue(document.isFinal());
723 
724     }
725 
726     /**
727      * Defines a PeopleFlow as follows:
728      *
729      * <pre>
730      *
731      * Priority 1:
732      *   -> ppfTestRole1 (has delegate ewestfal defined in KIM)
733      *
734      * </pre>
735      *
736      * The desired behavior is that the KIM delegate gets requests
737      */
738     @Test
739     public void test_RoleDelegate_justKimDelegate() throws Exception {
740         createSimpleRoleDelegatePeopleFlow(PEOPLE_FLOW_4, // PeopleFlow name
741                 ppfTestRole1,  // member role ID
742                 null,          // no delegate
743                 null           // ^^ so no DelegationType
744         );
745 
746         // now route a document to it
747         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_JUST_KIM_DELEGATE);
748         document.route("");
749         assertTrue("Document should be enroute.", document.isEnroute());
750 
751         // user1 (as member of ppfTestRole1) and ewestfal (as user1's primary KIM delegate for ppfTestRole1) should have
752         // activated requests, make sure the requests look correct
753 
754         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
755         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
756         ActionRequest user1Request = null;
757         for (ActionRequest actionRequest : rootActionRequests) {
758             RecipientType recipientType = actionRequest.getRecipientType();
759             if (recipientType == RecipientType.PRINCIPAL) {
760                 if (user1.equals(actionRequest.getPrincipalId())) {
761                     user1Request = actionRequest;
762                 }
763             }
764         }
765 
766         // now let's ensure we got the requests we wanted
767         assertNotNull(user1Request);
768         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
769 
770         // check delegate requests on user1Request now
771         assertEquals(1, user1Request.getChildRequests().size());
772         ActionRequest ewestfalDelegateRequest = user1Request.getChildRequests().get(0);
773         assertEquals(ewestfal, ewestfalDelegateRequest.getPrincipalId());
774         assertEquals(DelegationType.PRIMARY, ewestfalDelegateRequest.getDelegationType());
775         assertEquals(ActionRequestStatus.ACTIVATED, ewestfalDelegateRequest.getStatus());
776 
777         // let's run through the approvals for this peopleflow
778         assertApproveRequested(document, user1, ewestfal);
779         assertApproveNotRequested(document, user2, user3, testuser1, testuser2, testuser3);
780 
781         // approve as ewestfal who is user1's primary KIM delegate for testrole1
782         document.switchPrincipal(ewestfal);
783         document.approve("");
784 
785         // at this point all priorty1 folks should have approvals
786         assertApproveNotRequested(document, user1, ewestfal);
787 
788         // document should now be FINAL!
789         assertTrue(document.isFinal());
790     }
791 
792 
793 
794     /**
795      * Defines a PeopleFlow as follows:
796      *
797      * <pre>
798      *
799      * Priority 1:
800      *   -> ppfTestRole1 (has delegate ewestfal defined in KIM)
801      *   ----> ppfTestRole2 - primary delegate
802      *
803      * </pre>
804      *
805      * The desired behavior is that the delegate defined in the PeopleFlow gets the requests, overriding the KIM
806      * delegate which gets ignored.  Since the delegation type is 'primary', only ppfTestRole2's member gets requests.
807      */
808     @Test
809     public void test_RoleDelegate_primaryDelegateRole() throws Exception {
810         createSimpleRoleDelegatePeopleFlow(PEOPLE_FLOW_5,    // PeopleFlow name
811                 ppfTestRole1,     // member role ID
812                 ppfTestRole2,     // delegate role ID
813                 DelegationType.PRIMARY);
814 
815         // now route a document to it
816         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_PRIMARY_DELEGATE);
817         document.route("");
818         assertTrue("Document should be enroute.", document.isEnroute());
819 
820         // user1 (as member of ppfTestRole1) and user2 (as a member of user1's primary delegate role for ppfTestRole1)
821         // should have activated requests, make sure the requests look correct
822 
823         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
824         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
825         ActionRequest user1Request = null;
826         for (ActionRequest actionRequest : rootActionRequests) {
827             RecipientType recipientType = actionRequest.getRecipientType();
828             if (recipientType == RecipientType.PRINCIPAL) {
829                 if (user1.equals(actionRequest.getPrincipalId())) {
830                     user1Request = actionRequest;
831                 }
832             }
833         }
834 
835         // now let's ensure we got the requests we wanted
836         assertNotNull(user1Request);
837         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
838 
839         // check delegate requests on user1Request now
840         assertEquals(1, user1Request.getChildRequests().size());
841         ActionRequest user2DelegateRequest = user1Request.getChildRequests().get(0);
842         assertEquals(user2, user2DelegateRequest.getPrincipalId());
843         assertEquals(DelegationType.PRIMARY, user2DelegateRequest.getDelegationType());
844         assertEquals(ActionRequestStatus.ACTIVATED, user2DelegateRequest.getStatus());
845 
846         // let's run through the approvals for this peopleflow
847         assertApproveRequested(document, user1, user2);
848         assertApproveNotRequested(document, user3, testuser1, testuser2, testuser3, ewestfal);
849 
850         // approve as user2 who is user1's primary PPF delegate for testrole1
851         document.switchPrincipal(user2);
852         document.approve("");
853 
854         // at this point all priorty1 folks should have approvals
855         assertApproveNotRequested(document, user1, user2);
856 
857         // document should now be FINAL!
858         assertTrue(document.isFinal());
859     }
860 
861     /**
862      * Defines a PeopleFlow as follows:
863      *
864      * <pre>
865      *
866      * Priority 1:
867      *   -> ppfTestRole1 (has delegate ewestfal defined in KIM)
868      *   ----> ppfTestRole2 - secondary delegate
869      *
870      * </pre>
871      *
872      * The desired behavior is that the delegate defined in the PeopleFlow gets the requests, overriding the KIM
873      * delegate which gets ignored.  Since the delegation type is 'secondary', both ppfTestRole2 and ppfTestRole2 get
874      * requests.
875      */
876     @Test
877     public void test_RoleDelegate_secondaryDelegateRole() throws Exception {
878         createSimpleRoleDelegatePeopleFlow(
879                 PEOPLE_FLOW_6,    // PeopleFlow name
880                 ppfTestRole1,     // member role ID
881                 ppfTestRole2,     // delegate role ID
882                 DelegationType.SECONDARY
883         );
884 
885         // now route a document to it
886         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_SECONDARY_DELEGATE);
887         document.route("");
888         assertTrue("Document should be enroute.", document.isEnroute());
889 
890         // user1 (as member of ppfTestRole1) and user2 (as a member of user1's primary delegate role for ppfTestRole1)
891         // should have activated requests, make sure the requests look correct
892 
893         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
894         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
895         ActionRequest user1Request = null;
896         for (ActionRequest actionRequest : rootActionRequests) {
897             RecipientType recipientType = actionRequest.getRecipientType();
898             if (recipientType == RecipientType.PRINCIPAL) {
899                 if (user1.equals(actionRequest.getPrincipalId())) {
900                     user1Request = actionRequest;
901                 }
902             }
903         }
904 
905         // now let's ensure we got the requests we wanted
906         assertNotNull(user1Request);
907         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
908 
909         // check delegate requests on user1Request now
910         assertEquals(1, user1Request.getChildRequests().size());
911         ActionRequest user2DelegateRequest = user1Request.getChildRequests().get(0);
912         assertEquals(user2, user2DelegateRequest.getPrincipalId());
913         assertEquals(DelegationType.SECONDARY, user2DelegateRequest.getDelegationType());
914         assertEquals(ActionRequestStatus.ACTIVATED, user2DelegateRequest.getStatus());
915 
916         // let's run through the approvals for this peopleflow
917         assertApproveRequested(document, user1, user2);
918         assertApproveNotRequested(document, user3, testuser1, testuser2, testuser3, ewestfal);
919 
920         // approve as user2 who is user1's primary PPF delegate for testrole1
921         document.switchPrincipal(user2);
922         document.approve("");
923 
924         // at this point all priorty1 folks should have approvals
925         assertApproveNotRequested(document, user1, user2);
926 
927         // document should now be FINAL!
928         assertTrue(document.isFinal());
929     }
930 
931     /**
932      * Defines a PeopleFlow as follows:
933      *
934      * <pre>
935      *
936      * Priority 1:
937      *   -> ppfTestRole2
938      *   ----> ppfTestRole1 - primary delegate (+ has delegate ewestfal defined in KIM)
939      *
940      * </pre>
941      *
942      * KEW is limited to only one level of delegation, so the behavior will be to respect the delegate defined in the
943      * PeopleFlow, but ignore the KIM delegate otherwise we'd have to add support for multi-level delegation.  Since
944      * the PeopleFlow delegation is 'primary', ppfTestRole1 will get the requests.
945      */
946     @Test
947     public void test_RoleDelegate_delegateRoleHasKimDelegate() throws Exception {
948         createSimpleRoleDelegatePeopleFlow(PEOPLE_FLOW_7,    // PeopleFlow name
949                 ppfTestRole2,     // member role ID
950                 ppfTestRole1,     // delegate role ID
951                 DelegationType.PRIMARY);
952 
953         // now route a document to it
954         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_DELEGATE_ROLE_HAS_KIM_DELEGATE);
955         document.route("");
956         assertTrue("Document should be enroute.", document.isEnroute());
957 
958         // user2 (as member of ppfTestRole2) and user1 (as a member of user1's primary delegate role for ppfTestRole2)
959         // should have activated requests, make sure the requests look correct
960 
961         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
962         assertEquals("Should have 1 root action requests", 1, rootActionRequests.size());
963         ActionRequest user2Request = null;
964         for (ActionRequest actionRequest : rootActionRequests) {
965             RecipientType recipientType = actionRequest.getRecipientType();
966             if (recipientType == RecipientType.PRINCIPAL) {
967                 if (user2.equals(actionRequest.getPrincipalId())) {
968                     user2Request = actionRequest;
969                 }
970             }
971         }
972 
973         // now let's ensure we got the requests we wanted
974         assertNotNull(user2Request);
975         assertEquals(ActionRequestStatus.ACTIVATED, user2Request.getStatus());
976 
977         // check delegate requests on user1Request now
978         assertEquals(1, user2Request.getChildRequests().size());
979         ActionRequest user1DelegateRequest = user2Request.getChildRequests().get(0);
980         assertEquals(user1, user1DelegateRequest.getPrincipalId());
981         assertEquals(DelegationType.PRIMARY, user1DelegateRequest.getDelegationType());
982         assertEquals(ActionRequestStatus.ACTIVATED, user1DelegateRequest.getStatus());
983 
984         // let's run through the approvals for this peopleflow
985         assertApproveRequested(document, user1, user2);
986         assertApproveNotRequested(document, user3, testuser1, testuser2, testuser3, ewestfal);
987 
988         // approve as user1 who is user2's primary PPF delegate for testrole2
989         document.switchPrincipal(user1);
990         document.approve("");
991 
992         // at this point all priorty1 folks should have approvals
993         assertApproveNotRequested(document, user1, user2);
994 
995         // document should now be FINAL!
996         assertTrue(document.isFinal());
997     }
998 
999     /**
1000      * Defines a PeopleFlow as follows:
1001      *
1002      * <pre>
1003      *
1004      * Priority 1:
1005      *   -> ppfTestRole3
1006      *   ----> ppfTestRole4 - primary delegate
1007      *
1008      * </pre>
1009      *
1010      * this test will ensure that approvals work as expected when a role delegates to a role and both have
1011      * the action request policy ALL
1012      */
1013     @Test
1014     public void test_RoleDelegate_RoleMemberWithMultiplePrincipals_AllApprove() throws Exception {
1015         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestRole3, MemberType.ROLE);
1016         member.setActionRequestPolicy(ActionRequestPolicy.ALL);
1017         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(ppfTestRole4, MemberType.ROLE);
1018         delegate.setDelegationType(DelegationType.PRIMARY);
1019         delegate.setActionRequestPolicy(ActionRequestPolicy.ALL);
1020         createSimplePeopleFlow(PEOPLE_FLOW_10, member, delegate);
1021 
1022         // prove that if both members approve, the doc goes final
1023         {
1024             // route a document to the peopleflow
1025             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1026                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1027             document.route("");
1028             assertTrue("Document should be enroute.", document.isEnroute());
1029 
1030             // ppfTestRole3 members (user1, user2) delegate role ppfTestRole4 members (testuser1, testuser2) should have
1031             // activated requests
1032 
1033             // let's run through the approvals for this peopleflow
1034             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1035             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1036 
1037             // approve as testuser1 who a member of ppfTestRole3
1038             document.switchPrincipal(user1);
1039             document.approve("");
1040 
1041             // approve as testuser2 who is the second member of ppfTestRole3
1042             document.switchPrincipal(user2);
1043             document.approve("");
1044 
1045             // at this point all priorty1 folks should have approvals
1046             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1047 
1048             // document should now be FINAL!
1049             assertTrue(document.isFinal());
1050         }
1051 
1052         // prove that if both delegates approve, the doc goes final
1053         {
1054             // route a document to the peopleflow
1055             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1056                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1057             document.route("");
1058             assertTrue("Document should be enroute.", document.isEnroute());
1059 
1060             // ppfTestRole3 members (user1, user2) delegate role ppfTestRole4 members (testuser1, testuser2) should have
1061             // activated requests
1062 
1063             // let's run through the approvals for this peopleflow
1064             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1065             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1066 
1067             // approve as testuser1 who a member of ppfTestRole4
1068             document.switchPrincipal(testuser1);
1069             document.approve("");
1070 
1071             // approve as testuser2 who is the second member of ppfTestRole4
1072             document.switchPrincipal(testuser2);
1073             document.approve("");
1074 
1075             // at this point all priorty1 folks should have approvals
1076             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1077 
1078             // document should now be FINAL!
1079             assertTrue(document.isFinal());
1080         }
1081 
1082         // Prove that if a member approves, then both delegates need to approve due to the action request policy of
1083         // ALL for the doc to go final
1084         {
1085             // route a document to the peopleflow
1086             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1087                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1088             document.route("");
1089             assertTrue("Document should be enroute.", document.isEnroute());
1090 
1091             // ppfTestRole3 members (user1, user2) delegate role ppfTestRole4 members (testuser1, testuser2) should have
1092             // activated requests
1093 
1094             // let's run through the approvals for this peopleflow
1095             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1096             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1097 
1098             // approve as user1 who a member of ppfTestRole3
1099             document.switchPrincipal(user1);
1100             document.approve("");
1101 
1102             assertApproveNotRequested(document, user1);
1103 
1104             // approve as testuser1 who a member of ppfTestRole4
1105             document.switchPrincipal(testuser1);
1106             document.approve("");
1107 
1108             // approve as testuser2 who is the second member of ppfTestRole4
1109             document.switchPrincipal(testuser2);
1110             document.approve("");
1111 
1112             // at this point all priorty1 folks should have approvals
1113             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1114 
1115             // document should now be FINAL!
1116             assertTrue(document.isFinal());
1117         }
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      * The action request policy for each role is set to FIRST.
1132      * this test will verify that when one delegate approves, the document goes final.
1133      */
1134     @Test
1135     public void test_RoleDelegate_RoleMemberWithMultiplePrincipals_FirstApprove() throws Exception {
1136         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestRole3, MemberType.ROLE);
1137         member.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1138         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(ppfTestRole4, MemberType.ROLE);
1139         delegate.setDelegationType(DelegationType.PRIMARY);
1140         delegate.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1141 
1142         createSimplePeopleFlow(PEOPLE_FLOW_11, member, delegate);
1143 
1144         // First, prove that just one of the delegates needs to approve for the doc to go final:
1145         {
1146             // route a document to it
1147             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1148                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_FIRST_APPROVE);
1149             document.route("");
1150             assertTrue("Document should be enroute.", document.isEnroute());
1151 
1152             // verify the expected initial state
1153             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1154             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1155 
1156             // approve as testuser1 who a member of ppfTestRole4
1157             document.switchPrincipal(testuser1);
1158             document.approve("");
1159 
1160             assertApproveNotRequested(document, user1, user2, testuser1, testuser2, user3, ewestfal);
1161 
1162             assertTrue(document.isFinal());
1163         }
1164 
1165         // prove that just one of the members needs to approve for the doc to go final:
1166         {
1167             // route a document to it
1168             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1169                     ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_FIRST_APPROVE);
1170             document.route("");
1171             assertTrue("Document should be enroute.", document.isEnroute());
1172 
1173             // verify the expected initial state
1174             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1175             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1176 
1177             // approve as testuser1 who a member of ppfTestRole4
1178             document.switchPrincipal(user1);
1179             document.approve("");
1180 
1181             assertApproveNotRequested(document, user1, user2, testuser1, testuser2, user3, ewestfal);
1182 
1183             assertTrue(document.isFinal());
1184         }
1185 
1186     }
1187 
1188     /**
1189      * Defines a PeopleFlow as follows:
1190      *
1191      * <pre>
1192      *
1193      * Priority 1:
1194      *   -> ppfTestRole3
1195      *   ----> ppfTestRole4 - primary delegate
1196      *
1197      * </pre>
1198      *
1199      * this test will ensure that the delegate, a role is properly delegated to when the member is a principal
1200      */
1201     @Test
1202     public void test_RoleDelegate_RoleMemberWithMultiplePrincipals_DelegateFirstApprove() throws Exception {
1203         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestRole3, MemberType.ROLE);
1204         member.setActionRequestPolicy(ActionRequestPolicy.ALL);
1205         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(ppfTestRole4, MemberType.ROLE);
1206         delegate.setDelegationType(DelegationType.PRIMARY);
1207         delegate.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1208         createSimplePeopleFlow(PEOPLE_FLOW_12, member, delegate);
1209 
1210         // prove that both members need to approve before the doc goes final (due to the
1211         // ALL action request policy on the member role).
1212         {
1213             // now route a document to it
1214             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_DELEGATE_FIRST_APPROVE);
1215             document.route("");
1216             assertTrue("Document should be enroute.", document.isEnroute());
1217 
1218 
1219             // verify initial state
1220             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1221             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1222 
1223             // approve as user1 who is a member of ppfTestRole3
1224             document.switchPrincipal(user1);
1225             document.approve("");
1226 
1227             assertApproveRequested(document, user2, testuser1, testuser2);
1228             assertApproveNotRequested(document, user1);
1229 
1230             // approve as testuser1 who is a member of ppfTestRole3
1231             document.switchPrincipal(user2);
1232             document.approve("");
1233 
1234             // at this point all priorty1 folks should have approvals
1235             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1236 
1237             // document should now be FINAL!
1238             assertTrue(document.isFinal());
1239         }
1240 
1241         // prove that only one delegate needs to approve due to action request policy FIRST on the delegate role
1242         {
1243             // now route a document to it
1244             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_DELEGATE_FIRST_APPROVE);
1245             document.route("");
1246             assertTrue("Document should be enroute.", document.isEnroute());
1247 
1248 
1249             // let's run through the approvals for this peopleflow
1250             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1251             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1252 
1253             // approve as testuser1 who is a member of ppfTestRole4
1254             document.switchPrincipal(testuser1);
1255             document.approve("");
1256 
1257             // at this point all priorty1 folks should have approvals
1258             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1259 
1260             // document should now be FINAL!
1261             assertTrue(document.isFinal());
1262         }
1263 
1264         // prove that if one member approves and then one delegate approves, the doc goes final (due to the
1265         // ALL action request policy on the member role).
1266         {
1267             // now route a document to it
1268             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, ROLE_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS_DELEGATE_FIRST_APPROVE);
1269             document.route("");
1270             assertTrue("Document should be enroute.", document.isEnroute());
1271 
1272 
1273             // verify initial state
1274             assertApproveRequested(document, user1, user2, testuser1, testuser2);
1275             assertApproveNotRequested(document, user3, testuser3, ewestfal);
1276 
1277             // approve as user1 who is a member of ppfTestRole3
1278             document.switchPrincipal(user1);
1279             document.approve("");
1280 
1281             assertApproveRequested(document, user2, testuser1, testuser2);
1282             assertApproveNotRequested(document, user1);
1283 
1284             // approve as testuser1 who is a member of ppfTestRole4
1285             document.switchPrincipal(testuser1);
1286             document.approve("");
1287 
1288             // at this point all priorty1 folks should have approvals
1289             assertApproveNotRequested(document, user1, user2, testuser1, testuser2);
1290 
1291             // document should now be FINAL!
1292             assertTrue(document.isFinal());
1293         }
1294     }
1295 
1296     /**
1297      * Defines a PeopleFlow as follows:
1298      *
1299      * <pre>
1300      *
1301      * Priority 1:
1302      *   -> ppfTestGroup1
1303      *   ----> ppfTestRole4 - primary delegate
1304      *
1305      * </pre>
1306      *
1307      * this test will verify that groups can delegate to roles, and that the ALL approval logic will hold for the
1308      * delegate
1309      */
1310     @Test
1311     public void test_GroupDelegate_RoleMemberWithMultiplePrincipals_AllApprove() throws Exception {
1312         PeopleFlowMember.Builder member = PeopleFlowMember.Builder.create(ppfTestGroup1, MemberType.GROUP);
1313         PeopleFlowDelegate.Builder delegate = PeopleFlowDelegate.Builder.create(ppfTestRole4, MemberType.ROLE);
1314         delegate.setDelegationType(DelegationType.PRIMARY);
1315         delegate.setActionRequestPolicy(ActionRequestPolicy.ALL);
1316         createSimplePeopleFlow(PEOPLE_FLOW_13, member, delegate);
1317 
1318         // prove that one group member approving makes the doc go final
1319         {
1320             // now route a document to it
1321             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1322                     GROUP_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1323             document.route("");
1324             assertTrue("Document should be enroute.", document.isEnroute());
1325 
1326             // let's run through the approvals for this peopleflow
1327             assertApproveRequested(document, earl, fran, testuser1, testuser2);
1328             assertApproveNotRequested(document, user1, user2, user3, testuser3, ewestfal);
1329 
1330             // approve as earl who a member of ppfTestGroup1
1331             document.switchPrincipal(earl);
1332             document.approve("");
1333 
1334             // at this point all priorty1 folks should have approvals
1335             assertApproveNotRequested(document, user1, user2, earl, fran, testuser1, testuser2);
1336 
1337             // document should now be FINAL!
1338             assertTrue(document.isFinal());
1339         }
1340 
1341         // prove that both delegates need to approve (due to action request policy ALL) before the doc goes final
1342         {
1343             // now route a document to it
1344             WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3,
1345                     GROUP_DELEGATE_PEOPLE_FLOW_ROLE_MULTIPLE_MEMBERS);
1346             document.route("");
1347             assertTrue("Document should be enroute.", document.isEnroute());
1348 
1349             assertApproveRequested(document, earl, fran, testuser1, testuser2);
1350             assertApproveNotRequested(document, user1, user2, user3, testuser3, ewestfal);
1351 
1352             // approve as testuser1 who a member of ppfTestRole4
1353             document.switchPrincipal(testuser1);
1354             document.approve("");
1355 
1356             assertFalse(document.isFinal());
1357 
1358             // approve as testuser2 who a member of ppfTestRole4
1359             document.switchPrincipal(testuser2);
1360             document.approve("");
1361 
1362             // at this point all priorty1 folks should have approvals
1363             assertApproveNotRequested(document, user1, user2, earl, fran, testuser1, testuser2);
1364 
1365             // document should now be FINAL!
1366             assertTrue(document.isFinal());
1367         }
1368     }
1369 
1370     /**
1371      * creates a simple PeopleFlow in the TEST namespace with (by default) a member of type role having a delegate of
1372      * type role as follows:
1373      *
1374      * <pre>
1375      *
1376      * Priority 1:
1377      *   -> memberRole
1378      *   ----> delegateRole
1379      *
1380      * </pre>
1381      *
1382      * The member and delegate roles are specified by ID as memberRoleId and delegateRoleId.
1383      * The type of the delegate (primary or secondary) is specified by delegationType.
1384      * If the delegate ID is null, no delegate will be added.
1385      *
1386      * @param peopleFlowName the name to give the new PeopleFlow (the namespace will always be TEST)
1387      * @param memberRoleId the ID of the role for the PeopleFlow member
1388      * @param delegateRoleId the ID of the role for the PeopleFlow member's delegate
1389      * @param delegationType the delegate's type (primary or secondary)
1390      * @return the PeopleFlowDefinition created
1391      */
1392     private PeopleFlowDefinition createSimpleRoleDelegatePeopleFlow(String peopleFlowName, String memberRoleId, String delegateRoleId,
1393             DelegationType delegationType) {
1394         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, peopleFlowName);
1395 
1396         // build stop 1
1397         // build role member
1398         PeopleFlowMember.Builder memberBuilder = peopleFlow.addRole(memberRoleId);
1399         memberBuilder.setPriority(1);
1400         memberBuilder.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1401 
1402         if (delegateRoleId != null) {
1403             // build primary delegate role1
1404             PeopleFlowDelegate.Builder delegateBuilder =
1405                     PeopleFlowDelegate.Builder.create(delegateRoleId, MemberType.ROLE);
1406             delegateBuilder.setDelegationType(delegationType);
1407             delegateBuilder.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1408 
1409             memberBuilder.getDelegates().add(delegateBuilder);
1410         }
1411 
1412         return peopleFlowService.createPeopleFlow(peopleFlow.build());
1413     }
1414 
1415     /**
1416      * creates a simple PeopleFlow in the TEST namespace with a member having a delegate, like so:
1417      *
1418      * <pre>
1419      *
1420      * Priority 1:
1421      *   -> member
1422      *   ----> delegate
1423      *
1424      * </pre>
1425      *
1426      * @return the PeopleFlowDefinition created
1427      */
1428     private PeopleFlowDefinition createSimplePeopleFlow(String peopleFlowName, PeopleFlowMember.Builder member, PeopleFlowDelegate.Builder delegate) {
1429         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, peopleFlowName);
1430 
1431         member.setPriority(1);
1432 
1433         if (delegate != null) {
1434             // link delegate to member
1435             member.getDelegates().add(delegate);
1436         }
1437 
1438         peopleFlow.getMembers().add(member);
1439 
1440         return peopleFlowService.createPeopleFlow(peopleFlow.build());
1441     }
1442 
1443     /**
1444      * Defines a PeopleFlow as follows:
1445      *
1446      * <pre>
1447      *
1448      * Priority 1:
1449      *   -> user1
1450      *   -> user2
1451      *   ----> testuser2 - primary delegate
1452      * Priority 2:
1453      *   -> testuser1
1454      *   ----> TestWorkgroup - secondary delegate
1455      *   ----> testuser3 - primary delegate
1456      *   -> user3
1457      *
1458      * </pre>
1459      */
1460     private void createDelegatePeopleFlow() {
1461         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_1);
1462         peopleFlow.addPrincipal(user1).setPriority(1);
1463 
1464         PeopleFlowMember.Builder user2Builder = peopleFlow.addPrincipal(user2);
1465         user2Builder.setPriority(1);
1466         PeopleFlowDelegate.Builder user2PrimaryDelegateBuilder = PeopleFlowDelegate.Builder.create(testuser2,
1467                 MemberType.PRINCIPAL);
1468         user2PrimaryDelegateBuilder.setDelegationType(DelegationType.PRIMARY);
1469         user2Builder.getDelegates().add(user2PrimaryDelegateBuilder);
1470 
1471         PeopleFlowMember.Builder testuser1Builder = peopleFlow.addPrincipal(testuser1);
1472         testuser1Builder.setPriority(2);
1473         PeopleFlowDelegate.Builder testWorkgroupSecondaryDelegateBuilder = PeopleFlowDelegate.Builder.create(testWorkgroup, MemberType.GROUP);
1474         testWorkgroupSecondaryDelegateBuilder.setDelegationType(DelegationType.SECONDARY);
1475         testuser1Builder.getDelegates().add(testWorkgroupSecondaryDelegateBuilder);
1476         PeopleFlowDelegate.Builder testuser3PrimaryDelegateBuilder = PeopleFlowDelegate.Builder.create(testuser3, MemberType.PRINCIPAL);
1477         testuser3PrimaryDelegateBuilder.setDelegationType(DelegationType.PRIMARY);
1478         testuser1Builder.getDelegates().add(testuser3PrimaryDelegateBuilder);
1479 
1480         peopleFlow.addPrincipal(user3).setPriority(2);
1481 
1482         peopleFlowService.createPeopleFlow(peopleFlow.build());
1483     }
1484 
1485     @Test
1486     public void test_DelegatePeopleFlow_PriorityParallel_Approve() throws Exception {
1487         createDelegatePeopleFlow();
1488 
1489         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, DELEGATE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
1490         document.route("");
1491         assertTrue("Document should be enroute.", document.isEnroute());
1492 
1493         // user3 should not have an approval request since they initiated the document
1494         document.switchPrincipal(user3);
1495 
1496         // user1, user2, and testuser2 (as user2's primary delegate) should all have activated requests, make sure the requests look correct
1497         // user3 and testuser1 should have root requests as well, TestWorkgroup and testuser3 should be delegates of testuser1
1498 
1499         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
1500         assertEquals("Should have 4 root action requests", 4, rootActionRequests.size());
1501         ActionRequest user1Request = null;
1502         ActionRequest user2Request = null;
1503         ActionRequest user3Request = null;
1504         ActionRequest testuser1Request = null;
1505         for (ActionRequest actionRequest : rootActionRequests) {
1506             RecipientType recipientType = actionRequest.getRecipientType();
1507             if (recipientType == RecipientType.PRINCIPAL) {
1508                 if (user1.equals(actionRequest.getPrincipalId())) {
1509                     user1Request = actionRequest;
1510                 } else if (user2.equals(actionRequest.getPrincipalId())) {
1511                     user2Request = actionRequest;
1512                 } else if (user3.equals(actionRequest.getPrincipalId())) {
1513                     user3Request = actionRequest;
1514                 } else if (testuser1.equals(actionRequest.getPrincipalId())) {
1515                     testuser1Request = actionRequest;
1516                 }
1517             }
1518         }
1519         // now let's ensure we got the requests we wanted
1520         assertNotNull(user1Request);
1521         assertEquals(ActionRequestStatus.ACTIVATED, user1Request.getStatus());
1522         assertNotNull(user2Request);
1523         assertEquals(ActionRequestStatus.ACTIVATED, user2Request.getStatus());
1524         assertNotNull(user3Request);
1525         assertEquals(ActionRequestStatus.INITIALIZED, user3Request.getStatus());
1526         assertNotNull(testuser1Request);
1527         assertEquals(ActionRequestStatus.INITIALIZED, testuser1Request.getStatus());
1528 
1529         // check delegate requests on user2Request now
1530         assertEquals(1, user2Request.getChildRequests().size());
1531         ActionRequest testuser2DelegateRequest = user2Request.getChildRequests().get(0);
1532         assertEquals(testuser2, testuser2DelegateRequest.getPrincipalId());
1533         assertEquals(DelegationType.PRIMARY, testuser2DelegateRequest.getDelegationType());
1534         assertEquals(ActionRequestStatus.ACTIVATED, testuser2DelegateRequest.getStatus());
1535 
1536         // check delegate requests on testuser1Request now
1537         assertEquals(2, testuser1Request.getChildRequests().size());
1538         ActionRequest testWorkgroupRequest = null;
1539         ActionRequest testuser3Request = null;
1540         for (ActionRequest childActionRequest : testuser1Request.getChildRequests()) {
1541             RecipientType recipientType = childActionRequest.getRecipientType();
1542             if (recipientType == RecipientType.PRINCIPAL) {
1543                 if (testuser3.equals(childActionRequest.getPrincipalId())) {
1544                     testuser3Request = childActionRequest;
1545                 }
1546             } else if (recipientType == RecipientType.GROUP) {
1547                 if (testWorkgroup.equals(childActionRequest.getGroupId())) {
1548                     testWorkgroupRequest = childActionRequest;
1549                 }
1550             }
1551         }
1552         assertNotNull(testWorkgroupRequest);
1553         assertEquals(ActionRequestStatus.INITIALIZED, testWorkgroupRequest.getStatus());
1554         assertEquals(DelegationType.SECONDARY, testWorkgroupRequest.getDelegationType());
1555         assertNotNull(testuser3Request);
1556         assertEquals(ActionRequestStatus.INITIALIZED, testuser3Request.getStatus());
1557         assertEquals(DelegationType.PRIMARY, testuser3Request.getDelegationType());
1558 
1559         // whew! now that that's done, let's run through the approvals for this peopleflow
1560         assertApproveRequested(document, user1, user2, testuser2);
1561         assertApproveNotRequested(document, testuser1, user3, ewestfal, testuser3);
1562         // approve as testuser2 who is user2's primary delegate
1563         document.switchPrincipal(testuser2);
1564         document.approve("");
1565 
1566         // now approve as user1, this should push it to priority 2 in the peopleflow
1567         assertApproveRequested(document, user1);
1568         assertApproveNotRequested(document, user2, testuser2, testuser1, user3, ewestfal, testuser3);
1569         document.switchPrincipal(user1);
1570         document.approve("");
1571 
1572         // at this point all priorty2 folks should have approvals
1573         assertApproveRequested(document, testuser1, user3, ewestfal, testuser3);
1574         assertApproveNotRequested(document, user1, user2, testuser2);
1575         // approve as ewestfal, a member of TestWorkgroup which is a delegate of testuser1
1576         document.switchPrincipal(ewestfal);
1577         document.approve("");
1578 
1579         // 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
1580         assertApproveRequested(document, user3);
1581         assertApproveNotRequested(document, user1, user2, testuser2, testuser1, ewestfal, testuser3);
1582         document.switchPrincipal(user3);
1583         document.approve("");
1584 
1585         // document should now be FINAL!
1586         assertTrue(document.isFinal());
1587 
1588     }
1589 
1590     private String roleId = null;
1591     /**
1592      * Defines a PeopleFlow with a single first approve role, that role has two members, one principal and one group.
1593      */
1594     private void createFirstApproveRolePeopleFlow() {
1595         RoleService roleService = KimApiServiceLocator.getRoleService();
1596         Role role = roleService.getRoleByNamespaceCodeAndName("KR-SYS", "Technical Administrator");
1597         assertNotNull("Technical Administrator role should exist!", role);
1598         assertEquals(2, roleService.getRoleMembers(Collections.singletonList(role.getId()),
1599                 new HashMap<String, String>()).size());
1600         roleId = role.getId();
1601 
1602         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_2);
1603         PeopleFlowMember.Builder memberBuilder = peopleFlow.addRole(role.getId());
1604         memberBuilder.setPriority(1);
1605         memberBuilder.setActionRequestPolicy(ActionRequestPolicy.FIRST);
1606         peopleFlowService.createPeopleFlow(peopleFlow.build());
1607     }
1608 
1609     @Test
1610     public void test_FirstApproveRolePeopleFlow() throws Exception {
1611         createFirstApproveRolePeopleFlow();
1612 
1613         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
1614         document.route("");
1615         assertTrue("Document should be enroute.", document.isEnroute());
1616 
1617         // should have 1 root requests which is a role request with 2 children, one a principal request to the "admin"
1618         // prinicipal, and one a group request to the WorkflowAdmin group
1619         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
1620         assertEquals(1, rootActionRequests.size());
1621         ActionRequest roleRequest = rootActionRequests.get(0);
1622         assertEquals(ActionRequestPolicy.FIRST, roleRequest.getRequestPolicy());
1623         assertEquals(roleId, roleRequest.getRoleName());
1624         assertEquals(RecipientType.ROLE, roleRequest.getRecipientType());
1625         assertEquals(2, roleRequest.getChildRequests().size());
1626         for (ActionRequest childRequest : roleRequest.getChildRequests()) {
1627             if (RecipientType.PRINCIPAL.equals(childRequest.getRecipientType())) {
1628                 assertEquals(getPrincipalIdForName("admin"), childRequest.getPrincipalId());
1629             } else if (RecipientType.GROUP.equals(childRequest.getRecipientType())) {
1630                 assertEquals(getGroupIdForName("KR-WKFLW", "WorkflowAdmin"), childRequest.getGroupId());
1631             } else {
1632                 fail("Found a child request i didn't expect with a recipient type of: " + childRequest.getRecipientType());
1633             }
1634         }
1635 
1636         // should be able to approve as a member of the group on Technical Administrator role (which is WorkflowAdmin) as
1637         // well as the 'admin' principal
1638         document.switchPrincipal(getPrincipalNameForId("admin"));
1639         assertTrue(document.isApprovalRequested());
1640         document.switchPrincipal(getPrincipalIdForName("bmcgough"));
1641         assertTrue(document.isApprovalRequested());
1642 
1643         // now approve as a member of WorkflowAdmin
1644         document.approve("");
1645 
1646         // document should now be final because it's first approve
1647         assertTrue(document.isFinal());
1648 
1649         // now try it by approving as admin, and ensure that the first approval works as well in that case
1650         document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
1651         document.route("");
1652         assertTrue("Document should be enroute.", document.isEnroute());
1653         document.switchPrincipal(getPrincipalIdForName("bmcgough"));
1654         assertTrue(document.isApprovalRequested());
1655         document.switchPrincipal(getPrincipalNameForId("admin"));
1656         assertTrue(document.isApprovalRequested());
1657         // now approve as admin
1658         document.approve("");
1659         // document should now be final because it's first approve
1660         assertTrue(document.isFinal());
1661     }
1662 
1663     /**
1664      * Defines a PeopleFlow with a single all approve role, that role has two members, one principal and one group.
1665      */
1666     private void createAllApproveRolePeopleFlow() {
1667         RoleService roleService = KimApiServiceLocator.getRoleService();
1668         Role role = roleService.getRoleByNamespaceCodeAndName("KR-SYS", "Technical Administrator");
1669         assertNotNull("Technical Administrator role should exist!", role);
1670         assertEquals(2, roleService.getRoleMembers(Collections.singletonList(role.getId()),
1671                 new HashMap<String, String>()).size());
1672         roleId = role.getId();
1673 
1674         PeopleFlowDefinition.Builder peopleFlow = PeopleFlowDefinition.Builder.create(NAMESPACE_CODE, PEOPLE_FLOW_2);
1675         PeopleFlowMember.Builder memberBuilder = peopleFlow.addRole(role.getId());
1676         memberBuilder.setPriority(1);
1677         memberBuilder.setActionRequestPolicy(ActionRequestPolicy.ALL);
1678         peopleFlowService.createPeopleFlow(peopleFlow.build());
1679     }
1680 
1681     @Test
1682     public void test_AllApproveRolePeopleFlow() throws Exception {
1683         createAllApproveRolePeopleFlow();
1684 
1685         WorkflowDocument document = WorkflowDocumentFactory.createDocument(user3, SINGLE_PEOPLE_FLOW_PRIORITY_PARALLEL_APPROVE);
1686         document.route("");
1687         assertTrue("Document should be enroute.", document.isEnroute());
1688 
1689         // should have 1 root requests which is a role request with 2 children, one a principal request to the "admin"
1690         // prinicipal, and one a group request to the WorkflowAdmin group
1691         List<ActionRequest> rootActionRequests = document.getRootActionRequests();
1692         assertEquals(1, rootActionRequests.size());
1693         ActionRequest roleRequest = rootActionRequests.get(0);
1694         assertEquals(ActionRequestPolicy.ALL, roleRequest.getRequestPolicy());
1695         assertEquals(roleId, roleRequest.getRoleName());
1696         assertEquals(RecipientType.ROLE, roleRequest.getRecipientType());
1697         assertEquals(2, roleRequest.getChildRequests().size());
1698         for (ActionRequest childRequest : roleRequest.getChildRequests()) {
1699             if (RecipientType.PRINCIPAL.equals(childRequest.getRecipientType())) {
1700                 assertEquals(getPrincipalIdForName("admin"), childRequest.getPrincipalId());
1701             } else if (RecipientType.GROUP.equals(childRequest.getRecipientType())) {
1702                 assertEquals(getGroupIdForName("KR-WKFLW", "WorkflowAdmin"), childRequest.getGroupId());
1703             } else {
1704                 fail("Found a child request i didn't expect with a recipient type of: " + childRequest.getRecipientType());
1705             }
1706         }
1707 
1708         // should be able to approve as a member of the group on Technical Administrator role (which is WorkflowAdmin) as
1709         // well as the 'admin' principal
1710         document.switchPrincipal(getPrincipalNameForId("admin"));
1711         assertTrue(document.isApprovalRequested());
1712         document.switchPrincipal(getPrincipalIdForName("bmcgough"));
1713         assertTrue(document.isApprovalRequested());
1714 
1715         // now approve as a member of WorkflowAdmin
1716         document.approve("");
1717 
1718         // document should still be enroute because this is an all approve situation and both the group and admin need to approve
1719         assertTrue(document.isEnroute());
1720         assertFalse(document.isApprovalRequested());
1721 
1722         document.switchPrincipal(getPrincipalNameForId("admin"));
1723         assertTrue(document.isApprovalRequested());
1724         document.approve("");
1725         // after approving as admin, the last of the two role requests have been completed, document should be final
1726         assertTrue(document.isFinal());
1727     }
1728     
1729     private void assertApproveRequested(WorkflowDocument document, String... principalIds) {
1730         for (String principalId : principalIds) {
1731             document.switchPrincipal(principalId);
1732             assertTrue("Approve should have been requested for '" + principalId + "'", document.isApprovalRequested());
1733         }
1734     }
1735 
1736     private void assertAcknowledgeRequested(WorkflowDocument document, String... principalIds) {
1737         for (String principalId : principalIds) {
1738             document.switchPrincipal(principalId);
1739             assertTrue("Acknowledge should have been requested for '" + principalId + "'", document.isAcknowledgeRequested());
1740         }
1741     }
1742 
1743     private void assertApproveNotRequested(WorkflowDocument document, String... principalIds) {
1744         for (String principalId : principalIds) {
1745             document.switchPrincipal(principalId);
1746             assertFalse("Approve should *NOT* have been requested for '" + principalId + "'", document.isApprovalRequested());
1747         }
1748     }
1749 
1750 }