001/**
002 * Copyright 2005-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kew.role;
017
018import static org.junit.Assert.assertEquals;
019import static org.junit.Assert.assertFalse;
020import static org.junit.Assert.assertNotNull;
021import static org.junit.Assert.assertTrue;
022
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.HashMap;
026import java.util.List;
027import java.util.Map;
028
029import org.junit.FixMethodOrder;
030import org.junit.Test;
031import org.junit.runners.MethodSorters;
032import org.kuali.rice.core.api.criteria.QueryByCriteria;
033import org.kuali.rice.core.api.delegation.DelegationType;
034import org.kuali.rice.core.api.membership.MemberType;
035import org.kuali.rice.kew.api.KewApiConstants;
036import org.kuali.rice.kew.api.KewApiServiceLocator;
037import org.kuali.rice.kew.api.WorkflowDocument;
038import org.kuali.rice.kew.api.WorkflowDocumentFactory;
039import org.kuali.rice.kew.api.action.ActionRequest;
040import org.kuali.rice.kew.api.action.ActionRequestPolicy;
041import org.kuali.rice.kew.api.action.ActionType;
042import org.kuali.rice.kew.api.document.node.RouteNodeInstance;
043import org.kuali.rice.kew.test.KEWTestCase;
044import org.kuali.rice.kim.api.identity.principal.Principal;
045import org.kuali.rice.kim.api.role.Role;
046import org.kuali.rice.kim.api.role.RoleMembership;
047import org.kuali.rice.kim.api.role.RoleResponsibilityAction;
048import org.kuali.rice.kim.api.role.RoleService;
049import org.kuali.rice.kim.api.services.KimApiServiceLocator;
050import org.kuali.rice.kim.impl.common.attribute.KimAttributeBo;
051import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo;
052import org.kuali.rice.kim.impl.common.delegate.DelegateTypeBo;
053import org.kuali.rice.kim.impl.responsibility.ResponsibilityAttributeBo;
054import org.kuali.rice.kim.impl.responsibility.ResponsibilityBo;
055import org.kuali.rice.kim.impl.responsibility.ResponsibilityTemplateBo;
056import org.kuali.rice.kim.impl.role.RoleBo;
057import org.kuali.rice.kim.impl.role.RoleMemberAttributeDataBo;
058import org.kuali.rice.kim.impl.role.RoleMemberBo;
059import org.kuali.rice.kim.impl.role.RoleResponsibilityActionBo;
060import org.kuali.rice.kim.impl.role.RoleResponsibilityBo;
061import org.kuali.rice.kim.impl.type.KimTypeAttributeBo;
062import org.kuali.rice.kim.impl.type.KimTypeBo;
063import org.kuali.rice.krad.data.KradDataServiceLocator;
064import org.kuali.rice.test.BaselineTestCase;
065import org.springframework.transaction.TransactionStatus;
066import org.springframework.transaction.support.TransactionCallback;
067
068/**
069 * Tests Role-based routing integration between KEW and KIM.
070 *
071 * @author Kuali Rice Team (rice.collab@kuali.org)
072 *
073 */
074// FixMethodOrder will run tests in alphabetical order by test name
075//                to ensure testing of forceAction by each user for
076//                the case of an existing delegate being the initiator.
077@FixMethodOrder(MethodSorters.NAME_ASCENDING)
078@BaselineTestCase.BaselineMode(BaselineTestCase.Mode.CLEAR_DB)
079public class RoleRouteModuleTest extends KEWTestCase {
080
081    private static final String NAMESPACE = KewApiConstants.KEW_NAMESPACE;
082    private static final String ROLE_NAME = "RoleRouteModuleTestRole";
083
084    private static boolean suiteDataInitialized = false;
085    private static boolean suiteCreateDelegateInitialized = false;
086
087    @Override
088    protected void loadTestData() throws Exception {
089        loadXmlFile("RoleRouteModuleTestConfig.xml");
090
091        // only create this data once per suite!
092        if (suiteDataInitialized) {
093            return;
094        }
095
096        /**
097         * First we need to set up:
098         *
099         * 1) KimAttributes for both chart and org
100         * 2) The KimType for "chart/org"
101         * 3) The KimTypeAttributes for chart and org to define relationship between KimType and it's KimAttributes
102         */
103
104        // create "chart" KimAttribute
105        Long chartAttributeId = getNextSequenceLongValue("KRIM_ATTR_DEFN_ID_S");
106        KimAttributeBo chartAttribute = new KimAttributeBo();
107        chartAttribute.setId("" + chartAttributeId);
108        chartAttribute.setAttributeName("chart");
109        chartAttribute.setComponentName("org.kuali.rice.kim.bo.impl.KimAttributes");
110        chartAttribute.setNamespaceCode(NAMESPACE);
111        chartAttribute.setAttributeLabel("chart");
112        chartAttribute.setActive(true);
113        chartAttribute = KradDataServiceLocator.getDataObjectService().save(chartAttribute);
114
115        // create "org" KimAttribute
116        Long orgAttributeId = getNextSequenceLongValue("KRIM_ATTR_DEFN_ID_S");
117        KimAttributeBo orgAttribute = new KimAttributeBo();
118        orgAttribute.setId("" + orgAttributeId);
119        orgAttribute.setComponentName("org.kuali.rice.kim.bo.impl.KimAttributes");
120        orgAttribute.setAttributeName("org");
121        orgAttribute.setNamespaceCode(NAMESPACE);
122        orgAttribute.setAttributeLabel("org");
123        orgAttribute.setActive(true);
124        orgAttribute = KradDataServiceLocator.getDataObjectService().save(orgAttribute);
125
126        // create KimType
127        Long kimTypeId = getNextSequenceLongValue("KRIM_TYP_ID_S");
128        KimTypeBo kimType = new KimTypeBo();
129        kimType.setId("" + kimTypeId);
130        kimType.setName("ChartOrg");
131        kimType.setNamespaceCode(NAMESPACE);
132        kimType.setServiceName("testBaseRoleTypeService"); // do we need to set the kim type service yet? we shall see...
133        kimType.setActive(true);
134        kimType = KradDataServiceLocator.getDataObjectService().save(kimType);
135
136        // create chart KimTypeAttribute
137        Long chartTypeAttributeId = getNextSequenceLongValue("KRIM_TYP_ATTR_ID_S");
138        KimTypeAttributeBo chartTypeAttribute = new KimTypeAttributeBo();
139        chartTypeAttribute.setId("" + chartTypeAttributeId);
140        chartTypeAttribute.setActive(true);
141        chartTypeAttribute.setKimAttributeId(chartAttribute.getId());
142        chartTypeAttribute.setKimTypeId(kimType.getId());
143        chartTypeAttribute = KradDataServiceLocator.getDataObjectService().save(chartTypeAttribute);
144
145        // create org KimTypeAttribute
146        Long orgTypeAttributeId = getNextSequenceLongValue("KRIM_TYP_ATTR_ID_S");
147        KimTypeAttributeBo orgTypeAttribute = new KimTypeAttributeBo();
148        orgTypeAttribute.setId("" + orgTypeAttributeId);
149        orgTypeAttribute.setActive(true);
150        orgTypeAttribute.setKimAttributeId(orgAttribute.getId());
151        orgTypeAttribute.setKimTypeId(kimType.getId());
152        orgTypeAttribute = KradDataServiceLocator.getDataObjectService().save(orgTypeAttribute);
153
154        /**
155         * New let's create the Role
156         */
157
158        String roleId = "" + getNextSequenceLongValue("KRIM_ROLE_ID_S");
159        RoleBo role = new RoleBo();
160        role.setId(roleId);
161        role.setNamespaceCode(NAMESPACE);
162        role.setDescription("");
163        role.setName(ROLE_NAME);
164        role.setActive(true);
165        role.setKimTypeId(kimType.getId());
166
167        String roleMemberId1 = "" + getNextSequenceLongValue("KRIM_ROLE_ID_S");
168        RoleMemberBo adminRolePrincipal = new RoleMemberBo();
169        adminRolePrincipal.setId(roleMemberId1);
170        adminRolePrincipal.setRoleId(roleId);
171        Principal adminPrincipal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName("admin");
172        assertNotNull(adminPrincipal);
173        adminRolePrincipal.setMemberId(adminPrincipal.getPrincipalId());
174        adminRolePrincipal.setType( MemberType.PRINCIPAL );
175
176        String roleMemberId2 = "" + getNextSequenceLongValue("KRIM_ROLE_ID_S");
177        RoleMemberBo user2RolePrincipal = new RoleMemberBo();
178        user2RolePrincipal.setId(roleMemberId2);
179        user2RolePrincipal.setRoleId(roleId);
180        Principal user2Principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName("user2");
181        assertNotNull(user2Principal);
182        user2RolePrincipal.setMemberId(user2Principal.getPrincipalId());
183        user2RolePrincipal.setType( MemberType.PRINCIPAL );
184
185        String roleMemberId3 = "" + getNextSequenceLongValue("KRIM_ROLE_ID_S");
186        RoleMemberBo user1RolePrincipal = new RoleMemberBo();
187        user1RolePrincipal.setId(roleMemberId3);
188        user1RolePrincipal.setRoleId(roleId);
189        Principal user1Principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName("user1");
190        assertNotNull(user1Principal);
191        user1RolePrincipal.setMemberId(user1Principal.getPrincipalId());
192        user1RolePrincipal.setType( MemberType.PRINCIPAL );
193
194        List<RoleMemberBo> memberPrincipals = new ArrayList<RoleMemberBo>();
195        memberPrincipals.add(adminRolePrincipal);
196        memberPrincipals.add(user2RolePrincipal);
197        memberPrincipals.add(user1RolePrincipal);
198
199        role.setMembers(memberPrincipals);
200
201        /**
202         * Let's create qualifiers for chart and org for our role members
203         */
204
205        String dataId = "" + getNextSequenceLongValue("KRIM_GRP_ATTR_DATA_ID_S");
206        RoleMemberAttributeDataBo chartDataBL = new RoleMemberAttributeDataBo();
207        chartDataBL.setId(dataId);
208        chartDataBL.setAttributeValue("BL");
209        chartDataBL.setKimAttribute(chartAttribute);
210        chartDataBL.setKimAttributeId(chartAttribute.getId());
211        chartDataBL.setKimTypeId(kimType.getId());
212        chartDataBL.setAssignedToId(adminRolePrincipal.getId());
213
214        dataId = "" + getNextSequenceLongValue("KRIM_GRP_ATTR_DATA_ID_S");
215        RoleMemberAttributeDataBo chartDataBL2 = new RoleMemberAttributeDataBo();
216        chartDataBL2.setId(dataId);
217        chartDataBL2.setAttributeValue("BL");
218        chartDataBL2.setKimAttribute(chartAttribute);
219        chartDataBL2.setKimAttributeId(chartAttribute.getId());
220        chartDataBL2.setKimTypeId(kimType.getId());
221        chartDataBL2.setAssignedToId(user2RolePrincipal.getId());
222
223        dataId = "" + getNextSequenceLongValue("KRIM_GRP_ATTR_DATA_ID_S");
224        RoleMemberAttributeDataBo orgDataBUS = new RoleMemberAttributeDataBo();
225        orgDataBUS.setId(dataId);
226        orgDataBUS.setAttributeValue("BUS");
227        orgDataBUS.setKimAttribute(orgAttribute);
228        orgDataBUS.setKimAttributeId(orgAttribute.getId());
229        orgDataBUS.setKimTypeId(kimType.getId());
230        orgDataBUS.setAssignedToId(adminRolePrincipal.getId());
231
232        dataId = "" + getNextSequenceLongValue("KRIM_GRP_ATTR_DATA_ID_S");
233        RoleMemberAttributeDataBo orgDataBUS2 = new RoleMemberAttributeDataBo();
234        orgDataBUS2.setId(dataId);
235        orgDataBUS2.setAttributeValue("BUS");
236        orgDataBUS2.setKimAttribute(orgAttribute);
237        orgDataBUS2.setKimAttributeId(orgAttribute.getId());
238        orgDataBUS2.setKimTypeId(kimType.getId());
239        orgDataBUS2.setAssignedToId(user2RolePrincipal.getId());
240
241
242        dataId = "" + getNextSequenceLongValue("KRIM_GRP_ATTR_DATA_ID_S");
243        RoleMemberAttributeDataBo chartDataIN = new RoleMemberAttributeDataBo();
244        chartDataIN.setId(dataId);
245        chartDataIN.setAttributeValue("IN");
246        chartDataIN.setKimAttribute(chartAttribute);
247        chartDataIN.setKimAttributeId(chartAttribute.getId());
248        chartDataIN.setKimTypeId(kimType.getId());
249        chartDataIN.setAssignedToId(user1RolePrincipal.getId());
250
251        dataId = "" + getNextSequenceLongValue("KRIM_GRP_ATTR_DATA_ID_S");
252        RoleMemberAttributeDataBo orgDataMED = new RoleMemberAttributeDataBo();
253        orgDataMED.setId(dataId);
254        orgDataMED.setAttributeValue("MED");
255        orgDataMED.setKimAttribute(orgAttribute);
256        orgDataMED.setKimAttributeId(orgAttribute.getId());
257        orgDataMED.setKimTypeId(kimType.getId());
258        orgDataMED.setAssignedToId(user1RolePrincipal.getId());
259
260        List<RoleMemberAttributeDataBo> user1Attributes = new ArrayList<RoleMemberAttributeDataBo>();
261        user1Attributes.add(chartDataIN);
262        user1Attributes.add(orgDataMED);
263        user1RolePrincipal.setAttributeDetails(user1Attributes);
264
265        List<RoleMemberAttributeDataBo> user2Attributes = new ArrayList<RoleMemberAttributeDataBo>();
266        user2Attributes.add(chartDataBL2);
267        user2Attributes.add(orgDataBUS2);
268        user2RolePrincipal.setAttributeDetails(user2Attributes);
269
270        List<RoleMemberAttributeDataBo> adminAttributes = new ArrayList<RoleMemberAttributeDataBo>();
271        adminAttributes.add(chartDataBL);
272        adminAttributes.add(orgDataBUS);
273        adminRolePrincipal.setAttributeDetails(adminAttributes);
274
275
276        /**
277         * Now we can save the role!
278         */
279
280        role = KradDataServiceLocator.getDataObjectService().save(role);
281
282
283        /**
284         * Let's set up attributes for responsibility details
285         */
286
287        // create "documentType" KimAttribute
288        Long documentTypeAttributeId = getNextSequenceLongValue("KRIM_ATTR_DEFN_ID_S");
289        KimAttributeBo documentTypeAttribute = new KimAttributeBo();
290        documentTypeAttribute.setId("" + documentTypeAttributeId);
291        documentTypeAttribute.setAttributeName(KewApiConstants.DOCUMENT_TYPE_NAME_DETAIL);
292        documentTypeAttribute.setNamespaceCode(NAMESPACE);
293        documentTypeAttribute.setAttributeLabel("documentType");
294        documentTypeAttribute.setActive(true);
295        documentTypeAttribute = KradDataServiceLocator.getDataObjectService().save(documentTypeAttribute);
296
297        // create "node name" KimAttribute
298        Long nodeNameAttributeId = getNextSequenceLongValue("KRIM_ATTR_DEFN_ID_S");
299        KimAttributeBo nodeNameAttribute = new KimAttributeBo();
300        nodeNameAttribute.setId("" + nodeNameAttributeId);
301        nodeNameAttribute.setAttributeName(KewApiConstants.ROUTE_NODE_NAME_DETAIL);
302        nodeNameAttribute.setNamespaceCode(NAMESPACE);
303        nodeNameAttribute.setAttributeLabel("nodeName");
304        nodeNameAttribute.setActive(true);
305        nodeNameAttribute = KradDataServiceLocator.getDataObjectService().save(nodeNameAttribute);
306
307        // create KimType for responsibility details
308        Long kimRespTypeId = getNextSequenceLongValue("KRIM_TYP_ID_S");
309        KimTypeBo kimRespType = new KimTypeBo();
310        kimRespType.setId("" + kimRespTypeId);
311        kimRespType.setName("RespDetails");
312        kimRespType.setNamespaceCode(NAMESPACE);
313        kimRespType.setServiceName("testBaseResponsibilityTypeService");
314        kimRespType.setActive(true);
315        kimRespType = KradDataServiceLocator.getDataObjectService().save(kimRespType);
316
317        // create document type KimTypeAttribute
318        Long documentTypeTypeAttributeId = getNextSequenceLongValue("KRIM_TYP_ATTR_ID_S");
319        KimTypeAttributeBo documentTypeTypeAttribute = new KimTypeAttributeBo();
320        documentTypeTypeAttribute.setId("" + documentTypeTypeAttributeId);
321        documentTypeTypeAttribute.setActive(true);
322        documentTypeTypeAttribute.setKimAttributeId(chartAttribute.getId());
323        documentTypeTypeAttribute.setKimTypeId(kimType.getId());
324        documentTypeTypeAttribute.setSortCode("a");
325        documentTypeTypeAttribute = KradDataServiceLocator.getDataObjectService().save(documentTypeTypeAttribute);
326
327        // create nodeNameType KimTypeAttribute
328        Long nodeNameTypeAttributeId = getNextSequenceLongValue("KRIM_TYP_ATTR_ID_S");
329        KimTypeAttributeBo nodeNameTypeAttribute = new KimTypeAttributeBo();
330        nodeNameTypeAttribute.setId("" + nodeNameTypeAttributeId);
331        nodeNameTypeAttribute.setActive(true);
332        nodeNameTypeAttribute.setKimAttributeId(orgAttribute.getId());
333        nodeNameTypeAttribute.setKimTypeId(kimType.getId());
334        nodeNameTypeAttribute.setSortCode("a");
335        nodeNameTypeAttribute = KradDataServiceLocator.getDataObjectService().save(nodeNameTypeAttribute);
336
337        createResponsibilityForRoleRouteModuleTest(role, documentTypeAttribute, nodeNameAttribute, kimRespType, user1RolePrincipal, user2RolePrincipal, adminRolePrincipal,
338                                                   "FirstApproveReview", "RoleRouteModuleTest1", "resp1", "VoluntaryReview1", ActionRequestPolicy.FIRST);
339        //createResponsibilityForRoleRouteModuleTest1(role, documentTypeAttribute, nodeNameAttribute, kimRespType, user1RolePrincipal, user2RolePrincipal, adminRolePrincipal);
340        createResponsibilityForRoleRouteModuleTest(role, documentTypeAttribute, nodeNameAttribute, kimRespType, user1RolePrincipal, user2RolePrincipal, adminRolePrincipal,
341                                                   "AllApproveReview", "RoleRouteModuleTest2", "resp2", "VoluntaryReview2", ActionRequestPolicy.ALL);
342        //createResponsibilityForRoleRouteModuleTest2(role, documentTypeAttribute, nodeNameAttribute, kimRespType, user1RolePrincipal, user2RolePrincipal, adminRolePrincipal);
343
344        suiteDataInitialized = true;
345    }
346
347    private void createResponsibilityForRoleRouteModuleTest(RoleBo role, KimAttributeBo documentTypeAttribute, KimAttributeBo nodeNameAttribute, KimTypeBo kimRespType, RoleMemberBo user1RolePrincipal, RoleMemberBo user2RolePrincipal, RoleMemberBo adminRolePrincipal,
348                                                            String templateName, String docTypeDetailValue, String responsibilityName, String responsibilityDesc, ActionRequestPolicy actionRequestPolicy) {
349
350        /**
351         * Create the responsibility template
352         */
353
354        String templateId = String.valueOf(getNextSequenceLongValue("KRIM_RSP_TMPL_ID_S"));
355        ResponsibilityTemplateBo template = new ResponsibilityTemplateBo();
356        template.setId(templateId);
357        template.setNamespaceCode(NAMESPACE);
358        template.setName(templateName);
359        template.setKimTypeId(kimRespType.getId());
360        template.setActive(true);
361        template.setDescription("description");
362
363        template = KradDataServiceLocator.getDataObjectService().save(template);
364
365
366        /**
367         * Create the responsibility details for RoleRouteModuleTest1
368         */
369
370        String responsibilityId = "" + getNextSequenceLongValue("KRIM_ROLE_RSP_ID_S");
371
372        String dataId = "" + getNextSequenceLongValue("KRIM_GRP_ATTR_DATA_ID_S");
373        ResponsibilityAttributeBo documentTypeDetail = new ResponsibilityAttributeBo();
374        documentTypeDetail.setId(dataId);
375        documentTypeDetail.setAttributeValue(docTypeDetailValue);
376        documentTypeDetail.setKimAttribute(documentTypeAttribute);
377        documentTypeDetail.setKimAttributeId(documentTypeAttribute.getId());
378        documentTypeDetail.setKimTypeId(kimRespType.getId());
379        documentTypeDetail.setAssignedToId(responsibilityId);
380
381        dataId = "" + getNextSequenceLongValue("KRIM_GRP_ATTR_DATA_ID_S");
382        ResponsibilityAttributeBo nodeNameDetail = new ResponsibilityAttributeBo();
383        nodeNameDetail.setId(dataId);
384        nodeNameDetail.setAttributeValue("Role1");
385        nodeNameDetail.setKimAttribute(nodeNameAttribute);
386        nodeNameDetail.setKimAttributeId(nodeNameAttribute.getId());
387        nodeNameDetail.setKimTypeId(kimRespType.getId());
388        nodeNameDetail.setAssignedToId(responsibilityId);
389
390
391
392        /**
393         * Create the responsibility
394         */
395
396        List<ResponsibilityAttributeBo> detailObjects = new ArrayList<ResponsibilityAttributeBo>();
397        detailObjects.add(documentTypeDetail);
398        detailObjects.add(nodeNameDetail);
399
400        ResponsibilityBo responsibility = new ResponsibilityBo();
401        responsibility.setActive(true);
402        responsibility.setDescription(responsibilityDesc);
403        responsibility.setAttributeDetails(detailObjects);
404        responsibility.setName(responsibilityName);
405        responsibility.setNamespaceCode(NAMESPACE);
406        responsibility.setId(responsibilityId);
407        responsibility.setTemplate(template);
408        responsibility.setTemplateId(template.getId());
409
410        responsibility = KradDataServiceLocator.getDataObjectService().save(responsibility);
411
412        /**
413         * Create the RoleResponsibility
414         */
415
416        String roleResponsibilityId = "" + getNextSequenceLongValue("KRIM_ROLE_RSP_ID_S");
417        RoleResponsibilityBo roleResponsibility = new RoleResponsibilityBo();
418        roleResponsibility.setRoleResponsibilityId(roleResponsibilityId);
419        roleResponsibility.setActive(true);
420        roleResponsibility.setResponsibilityId(responsibilityId);
421        roleResponsibility.setRoleId(role.getId());
422
423        roleResponsibility = KradDataServiceLocator.getDataObjectService().save(roleResponsibility);
424
425        /**
426         * Create the various responsibility actions
427         */
428        String roleResponsibilityActionId = "" + getNextSequenceLongValue("KRIM_ROLE_RSP_ACTN_ID_S");
429        RoleResponsibilityActionBo roleResponsibilityAction1 = new RoleResponsibilityActionBo();
430        roleResponsibilityAction1.setId(roleResponsibilityActionId);
431        roleResponsibilityAction1.setRoleResponsibilityId(roleResponsibilityId);
432        roleResponsibilityAction1.setRoleMemberId(user1RolePrincipal.getId());
433        roleResponsibilityAction1.setActionTypeCode(KewApiConstants.ACTION_REQUEST_APPROVE_REQ);
434        roleResponsibilityAction1.setActionPolicyCode(actionRequestPolicy.getCode());
435        roleResponsibilityAction1.setPriorityNumber(1);
436        roleResponsibilityAction1.setForceAction(true);
437        roleResponsibilityAction1 = KradDataServiceLocator.getDataObjectService().save(roleResponsibilityAction1);
438
439        roleResponsibilityActionId = "" + getNextSequenceLongValue("KRIM_ROLE_RSP_ACTN_ID_S");
440        RoleResponsibilityActionBo roleResponsibilityAction2 = new RoleResponsibilityActionBo();
441        roleResponsibilityAction2.setId(roleResponsibilityActionId);
442        roleResponsibilityAction2.setRoleResponsibilityId(roleResponsibilityId);
443        roleResponsibilityAction2.setRoleMemberId(user2RolePrincipal.getId());
444        roleResponsibilityAction2.setActionTypeCode(KewApiConstants.ACTION_REQUEST_APPROVE_REQ);
445        roleResponsibilityAction2.setActionPolicyCode(actionRequestPolicy.getCode());
446        roleResponsibilityAction2.setPriorityNumber(1);
447        roleResponsibilityAction2.setForceAction(true);
448        roleResponsibilityAction2 = KradDataServiceLocator.getDataObjectService().save(roleResponsibilityAction2);
449
450        roleResponsibilityActionId = "" + getNextSequenceLongValue("KRIM_ROLE_RSP_ACTN_ID_S");
451        RoleResponsibilityActionBo roleResponsibilityAction3 = new RoleResponsibilityActionBo();
452        roleResponsibilityAction3.setId(roleResponsibilityActionId);
453        roleResponsibilityAction3.setRoleResponsibilityId(roleResponsibilityId);
454        roleResponsibilityAction3.setRoleMemberId(adminRolePrincipal.getId());
455        roleResponsibilityAction3.setActionTypeCode(KewApiConstants.ACTION_REQUEST_APPROVE_REQ);
456        roleResponsibilityAction3.setActionPolicyCode(actionRequestPolicy.getCode());
457        roleResponsibilityAction3.setPriorityNumber(1);
458        roleResponsibilityAction3.setForceAction(true);
459        roleResponsibilityAction3 = KradDataServiceLocator.getDataObjectService().save(roleResponsibilityAction3);
460
461    }
462
463    private void createDelegate(){
464
465        if (suiteCreateDelegateInitialized) {
466            return;
467        }
468
469        // create delegation KimType
470        Long kimDlgnTypeId = getNextSequenceLongValue("KRIM_TYP_ID_S");
471        KimTypeBo kimDlgnType = new KimTypeBo();
472        kimDlgnType.setId("" + kimDlgnTypeId);
473        kimDlgnType.setName("TestBaseDelegationType");
474        kimDlgnType.setNamespaceCode(NAMESPACE);
475        kimDlgnType.setServiceName("testBaseDelegationTypeService");
476        kimDlgnType.setActive(true);
477        kimDlgnType = KradDataServiceLocator.getDataObjectService().save(kimDlgnType);
478
479        /*
480         * Manually create a delegate
481         */
482        String id = "" + getNextSequenceLongValue("KRIM_DLGN_MBR_ID_S");
483        DelegateTypeBo delegate = new DelegateTypeBo();
484
485        delegate.setDelegationId(id);
486        delegate.setDelegationType(DelegationType.PRIMARY);
487        delegate.setActive(true);
488        delegate.setKimTypeId("" + kimDlgnTypeId);
489        /*
490         * Assign it a role that was created above.  This should mean that every
491         * principle in the role can have the delegate added below as a delegate
492         */
493        Role role = KimApiServiceLocator.getRoleService().getRoleByNamespaceCodeAndName(NAMESPACE, ROLE_NAME);
494        assertNotNull("Role should exist.", role);
495        delegate.setRoleId(role.getId());
496        delegate = KradDataServiceLocator.getDataObjectService().save(delegate);
497
498        // BC of the way the jpa is handled we have to create the delagate, then the members
499        String delgMemberId = "" + getNextSequenceLongValue("KRIM_DLGN_MBR_ID_S");
500        DelegateMemberBo user1RoleDelegate = new DelegateMemberBo();
501        user1RoleDelegate.setDelegationMemberId(delgMemberId);
502        // This is the user the delegation requests should be sent to.
503        // Note: If initiator is same as delegate, forceAction is utilized in responsibilities of approvers.
504        Principal kPrincipal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName("ewestfal");
505        assertNotNull(kPrincipal);
506        user1RoleDelegate.setMemberId(kPrincipal.getPrincipalId());
507        /*
508         * this is checked when adding delegates in both the ActionRequestFactory
509         * and RoleServiceImpl
510         */
511        user1RoleDelegate.setType( MemberType.PRINCIPAL );
512
513        // attach it to the delegate we created above
514        user1RoleDelegate.setDelegationId(delegate.getDelegationId());
515
516        user1RoleDelegate = KradDataServiceLocator.getDataObjectService().save(user1RoleDelegate);
517
518        suiteCreateDelegateInitialized = true;
519
520    }
521
522
523    @Test
524    public void testRoleRouteModule_FirstApprove() throws Exception {
525
526        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "RoleRouteModuleTest1");
527        document.route("");
528
529        // in this case we should have a first approve role that contains admin and user2, we
530        // should also have a first approve role that contains just user1
531
532        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("admin"), document.getDocumentId());
533        assertTrue("Approval should be requested.", document.isApprovalRequested());
534        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user1"), document.getDocumentId());
535        assertTrue("Approval should be requested.", document.isApprovalRequested());
536        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), document.getDocumentId());
537        assertTrue("Approval should be requested.", document.isApprovalRequested());
538
539        // examine the action requests
540        List<ActionRequest> actionRequests = KewApiServiceLocator.getWorkflowDocumentService().getRootActionRequests(document.getDocumentId());
541        // there should be 2 root action requests returned here, 1 containing the 2 requests for "BL", and one containing the request for "IN"
542        assertEquals("Should have 3 action requests.", 3, actionRequests.size());
543        int numRoots = 0;
544        for (ActionRequest actionRequest : actionRequests) {
545            // each of these should be "first approve"
546            if (actionRequest.getRequestPolicy() != null) {
547                assertEquals(ActionRequestPolicy.FIRST, actionRequest.getRequestPolicy());
548            }
549            if (actionRequest.getParentActionRequestId() == null) {
550                numRoots++;
551            }
552        }
553        assertEquals("There should have been 3 root requests.", 3, numRoots);
554
555        // let's approve as "user1" and verify the document is still ENROUTE
556        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user1"), document.getDocumentId());
557        document.approve("");
558        assertTrue("Document should be ENROUTE.", document.isEnroute());
559
560        // verify that admin and user2 still have requests
561        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("admin"), document.getDocumentId());
562        assertTrue("Approval should be requested.", document.isApprovalRequested());
563        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), document.getDocumentId());
564        assertTrue("Approval should be requested.", document.isApprovalRequested());
565
566        // let's approve as "user2" and verify the document is still ENROUTE
567        document.approve("");
568        assertTrue("Document should be ENROUTE.", document.isEnroute());
569
570        // let's approve as "admin" and verify the document has gone FINAL
571        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("admin"), document.getDocumentId());
572        document.approve("");
573        assertTrue("Document should be FINAL.", document.isFinal());
574    }
575
576    @Test
577    public void testRoleRouteModule_AllApprove() throws Exception {
578
579        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "RoleRouteModuleTest2");
580        document.route("");
581
582        // in this case we should have all approve roles for admin, user1 and user2
583
584        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("admin"), document.getDocumentId());
585        assertTrue("Approval should be requested.", document.isApprovalRequested());
586        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user1"), document.getDocumentId());
587        assertTrue("Approval should be requested.", document.isApprovalRequested());
588        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), document.getDocumentId());
589        assertTrue("Approval should be requested.", document.isApprovalRequested());
590
591        // examine the action requests, because there was only 1 responsibility on each role, the KEW->KIM integration
592        // transitions the requests from all approve to first approve
593        List<ActionRequest> actionRequests = KewApiServiceLocator
594                .getWorkflowDocumentService().getRootActionRequests(document.getDocumentId());
595        assertEquals("Should have 3 action requests.", 3, actionRequests.size());
596        int numRoots = 0;
597        for (ActionRequest actionRequest : actionRequests) {
598            assertNotNull(actionRequest.getRequestPolicy());
599            assertEquals(ActionRequestPolicy.FIRST, actionRequest.getRequestPolicy());
600            if (actionRequest.getParentActionRequestId() == null) {
601                numRoots++;
602            }
603        }
604        assertEquals("There should have been 3 root requests.", 3, numRoots);
605
606        // let's approve as "user1" and verify the document does NOT go FINAL
607        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user1"), document.getDocumentId());
608        document.approve("");
609        assertTrue("Document should still be enroute.", document.isEnroute());
610
611        // verify that admin and user2 still have requests
612        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("admin"), document.getDocumentId());
613        assertTrue("Approval should be requested.", document.isApprovalRequested());
614        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), document.getDocumentId());
615        assertTrue("Approval should be requested.", document.isApprovalRequested());
616
617        // approve as "user2" and verify document is still ENROUTE
618        document.approve("");
619        assertTrue("Document should be ENROUTE.", document.isEnroute());
620
621        // now approve as "admin", coument should be FINAL
622        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("admin"), document.getDocumentId());
623        document.approve("");
624        assertTrue("Document should be FINAL.", document.isFinal());
625    }
626
627    /**
628     * Tests that ActionRequests are regenerated when RoleResponsibilityActions are programmatically changes via the RoleService
629     * (Must be run before tests which alter delegate configuration)
630     */
631    @Test
632    public void testRoleRouteModule_RoleResponsibilityActionUpdate() throws Exception {
633
634        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "RoleRouteModuleTest1");
635        document.route("");
636
637        // in this case we should have a first approve role that contains admin and user2, we
638        // should also have a first approve role that contains just user1
639
640        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("admin"), document.getDocumentId());
641        assertTrue("Approval should be requested.", document.isApprovalRequested());
642        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user1"), document.getDocumentId());
643        assertTrue("Approval should be requested.", document.isApprovalRequested());
644        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), document.getDocumentId());
645        assertTrue("Approval should be requested.", document.isApprovalRequested());
646
647        // examine the action requests
648        List<ActionRequest> actionRequests = KewApiServiceLocator.getWorkflowDocumentService().getRootActionRequests(document.getDocumentId());
649        // there should be 2 root action requests returned here, 1 containing the 2 requests for "BL", and one containing the request for "IN"
650        assertEquals("Should have 3 action requests.", 3, actionRequests.size());
651        int numRoots = 0;
652        for (ActionRequest actionRequest : actionRequests) {
653            // each of these should be "first approve"
654            if (actionRequest.getRequestPolicy() != null) {
655                assertEquals(ActionRequestPolicy.FIRST, actionRequest.getRequestPolicy());
656            }
657            if (actionRequest.getParentActionRequestId() == null) {
658                numRoots++;
659            }
660        }
661        assertEquals("There should have been 3 root requests.", 3, numRoots);
662
663        RoleService roleService = KimApiServiceLocator.getRoleService();
664        Role role = roleService.getRoleByNamespaceCodeAndName(NAMESPACE, ROLE_NAME);
665        assertNotNull(role);
666        Principal user1Principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName("user1");
667        List<RoleMembership> members = roleService.getRoleMembers(Collections.singletonList(role.getId()), null);
668        // find user1principal
669        RoleMembership m = null;
670        for (RoleMembership rm: members) {
671            if (user1Principal.getPrincipalId().equals(rm.getMemberId())) {
672                m = rm;
673                break;
674            }
675        }
676        assertNotNull("Failed to find user1Principal role membership", m);
677        assertEquals(user1Principal.getPrincipalId(), m.getMemberId());
678        List<RoleResponsibilityAction> rras = roleService.getRoleMemberResponsibilityActions(m.getId());
679        assertEquals(2, rras.size());
680        RoleResponsibilityAction rra = rras.get(0);
681        RoleResponsibilityAction.Builder b = RoleResponsibilityAction.Builder.create(rra);
682        b.setActionTypeCode(ActionType.ACKNOWLEDGE.getCode());
683
684        roleService.updateRoleResponsibilityAction(b.build());
685
686        // action request should have changed!
687        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user1"), document.getDocumentId());
688        assertFalse("Approval should NOT be requested.", document.isApprovalRequested());
689        assertTrue("Acknowledge should be requested.", document.isAcknowledgeRequested());
690        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("admin"), document.getDocumentId());
691        assertTrue("Approval should be requested.", document.isApprovalRequested());
692        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), document.getDocumentId());
693        assertTrue("Approval should be requested.", document.isApprovalRequested());
694
695        roleService.deleteRoleResponsibilityAction(rras.get(0).getId());
696
697        // no actions should be requested of user1 now
698        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user1"), document.getDocumentId());
699        assertTrue(document.getRequestedActions().getRequestedActions().isEmpty());
700
701        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("admin"), document.getDocumentId());
702        assertTrue("Approval should be requested.", document.isApprovalRequested());
703        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user2"), document.getDocumentId());
704        assertTrue("Approval should be requested.", document.isApprovalRequested());
705
706        // examine the action requests
707        actionRequests = KewApiServiceLocator.getWorkflowDocumentService().getRootActionRequests(document.getDocumentId());
708        // now should be only 2 requests
709        assertEquals("Should have 2 action requests.", 2, actionRequests.size());
710    }
711
712    @Test
713    public void testRoleDelegate() throws Exception{
714        this.createDelegate();
715
716        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), "RoleRouteModuleTest2");
717        document.route("");
718
719        String ewestfalPrincipalId = getPrincipalIdForName("ewestfal");
720
721        // now our fancy new delegate should have an action request
722        document = WorkflowDocumentFactory.loadDocument(ewestfalPrincipalId, document.getDocumentId());
723        assertTrue("ewestfal should be able to approve", document.isApprovalRequested());
724
725        // let's look at the action requests, there should be 3 root requests, each one should have a delegation to ewestfal
726        List<ActionRequest> actionRequests = document.getRootActionRequests();
727        assertEquals(3, actionRequests.size());
728
729        for (ActionRequest actionRequest : actionRequests) {
730            // none of the root requests should be to ewestfal
731            assertFalse(ewestfalPrincipalId.equals(actionRequest.getPrincipalId()));
732            // but all of the delegate requests should!
733            assertEquals(1, actionRequest.getChildRequests().size());
734            ActionRequest delegateRequest = actionRequest.getChildRequests().get(0);
735            assertEquals(ewestfalPrincipalId, delegateRequest.getPrincipalId());
736            assertEquals("Delegation type should been PRIMARY", DelegationType.PRIMARY, delegateRequest.getDelegationType());
737        }
738    }
739
740    @Test
741    public void testRoleDelegateApproval() throws Exception{
742        this.createDelegate();
743
744        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), "RoleRouteModuleTest2");
745        document.route("");
746
747        // See if the delegate can approve the document
748        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
749        assertTrue("ewestfal should have an approval request", document.isApprovalRequested());
750        document.approve("");
751
752        assertTrue("Document should have been approved by the delegate.", document.isFinal());
753    }
754
755    @Test
756    public void testRoleWithNoMembers() throws Exception {
757        getTransactionTemplate().execute(new TransactionCallback<Object>() {
758            @Override
759            public Object doInTransaction(TransactionStatus status) {
760
761                try {
762
763                    // first let's clear all of the members out of our role
764
765                    Role role = KimApiServiceLocator.getRoleService().getRoleByNamespaceCodeAndName(NAMESPACE,
766                            ROLE_NAME);
767                    Map<String, String> criteria = new HashMap<String, String>();
768                    criteria.put("roleId", role.getId());
769                    List<RoleMemberBo> roleMembers = KradDataServiceLocator.getDataObjectService().findMatching(RoleMemberBo.class, QueryByCriteria.Builder.forAttribute("roleId", role.getId()).build()).getResults();
770                    assertFalse("role member list should not currently be empty", roleMembers.isEmpty());
771                    for (RoleMemberBo roleMember : roleMembers) {
772                        //String roleMemberId = roleMember.getRoleMemberId();
773                        //RoleMemberImpl roleMemberImpl = KRADServiceLocatorInternal.getBusinessObjectService().findBySinglePrimaryKey(RoleMemberImpl.class, roleMemberId);
774                        assertNotNull("Role Member should exist.", roleMember);
775                        KradDataServiceLocator.getDataObjectService().delete(roleMember);
776                    }
777
778                    // flush deletes on DataObjectService
779                    KradDataServiceLocator.getDataObjectService().flush(RoleMemberBo.class);
780
781                    List<RoleMembership> roleMemberInfos = KimApiServiceLocator.getRoleService().getRoleMembers(Collections.singletonList(role.getId()), Collections.<String, String>emptyMap());
782                    assertEquals("role member list should be empty now", 0, roleMemberInfos.size());
783
784                    // now that we've removed all members from the Role, let's trying routing the doc!
785                    WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), "RoleRouteModuleTest1");
786                    document.route("");
787
788                    // the document should be final now, because the role has no members so all nodes should have been skipped for routing purposes
789
790                    assertTrue("document should now be in final status", document.isFinal());
791
792                    // verify that the document went through the appropriate route path
793
794                    List<RouteNodeInstance> routeNodeInstances = document.getRouteNodeInstances();
795                    assertEquals("Document should have 2 route node instances", 2, routeNodeInstances.size());
796
797                    return null;
798                } finally {
799                    status.setRollbackOnly();
800                }
801            }
802        });
803    }
804
805}