001    /**
002     * Copyright 2005-2011 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     */
016    package org.kuali.rice.kew.routemodule;
017    
018    import org.junit.Test;
019    import org.kuali.rice.kew.api.KewApiServiceLocator;
020    import org.kuali.rice.kew.api.WorkflowDocument;
021    import org.kuali.rice.kew.api.WorkflowDocumentFactory;
022    import org.kuali.rice.kew.api.action.ActionRequest;
023    import org.kuali.rice.kew.api.action.ActionRequestStatus;
024    import org.kuali.rice.kew.api.action.RoutingReportCriteria;
025    import org.kuali.rice.kew.api.document.DocumentDetail;
026    import org.kuali.rice.kew.engine.node.RouteNodeInstance;
027    import org.kuali.rice.kew.service.KEWServiceLocator;
028    import org.kuali.rice.kew.test.KEWTestCase;
029    import org.kuali.rice.kew.api.KewApiConstants;
030    
031    import java.util.Collection;
032    import java.util.List;
033    
034    import static org.junit.Assert.*;
035    
036    public class RoutingReportServiceTest extends KEWTestCase {
037        
038    
039        protected void loadTestData() throws Exception {
040            loadXmlFile("RouteModuleConfig.xml");
041        }
042    
043        /**
044         * Tests the report() method against a sequential document type.
045         */
046        @Test public void testReportSequential() throws Exception {
047            
048            
049            // route a document to the first node
050            WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.DOCUMENT_TYPE_NAME);
051            document.route("");
052            
053            // there should now be 1 active node and 2 pending requests on the document
054            Collection activeNodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
055            List requests = KEWServiceLocator.getActionRequestService().findAllActionRequestsByDocumentId(document.getDocumentId());
056            assertEquals("Should be one active node.", 1, activeNodeInstances.size());
057            String activeNodeId = ((RouteNodeInstance)activeNodeInstances.iterator().next()).getRouteNodeInstanceId();
058            assertEquals("Should be 2 pending requests.", 2, requests.size());
059            
060            // now, lets "get our report on", the WorkflowInfo.executeSimulation method will call the service's report method.
061            RoutingReportCriteria criteria = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId()).build();
062            
063            long start = System.currentTimeMillis();
064            DocumentDetail documentDetail = KewApiServiceLocator.getWorkflowDocumentActionsService().executeSimulation(
065                    criteria);
066            long end = System.currentTimeMillis();
067            System.out.println("Time to run routing report: " + (end-start)+" milliseconds.");
068            
069            // document detail should have all of our requests on it, 2 activated approves, 1 initialized approve, 2 initialized acknowledges
070            assertEquals("There should be 5 requests.", 5, documentDetail.getActionRequests().size());
071            boolean approveToBmcgough = false;
072            boolean approveToRkirkend = false;
073            boolean approveToPmckown = false;
074            boolean ackToTemay = false;
075            boolean ackToJhopf = false;
076            for (ActionRequest requestVO : documentDetail.getActionRequests()) {
077                String netId = getPrincipalNameForId(requestVO.getPrincipalId()); 
078                if (netId.equals("bmcgough")) {
079                    assertEquals("Should be approve.", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, requestVO.getActionRequested().getCode());
080                    assertEquals("Should be activated.", ActionRequestStatus.ACTIVATED, requestVO.getStatus());
081                    assertEquals("Wrong node name", SeqSetup.WORKFLOW_DOCUMENT_NODE, requestVO.getNodeName());
082                    approveToBmcgough = true;
083                } else if (netId.equals("rkirkend")) {
084                    assertEquals("Should be approve.", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, requestVO.getActionRequested().getCode());
085                    assertEquals("Should be activated.", ActionRequestStatus.ACTIVATED, requestVO.getStatus());
086                    assertEquals("Wrong node name", SeqSetup.WORKFLOW_DOCUMENT_NODE, requestVO.getNodeName());
087                    approveToRkirkend = true;
088                } else if (netId.equals("pmckown")) {
089                    assertEquals("Should be approve.", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, requestVO.getActionRequested().getCode());
090                    assertEquals("Should be initialized.", ActionRequestStatus.INITIALIZED, requestVO.getStatus());
091                    assertEquals("Wrong node name", SeqSetup.WORKFLOW_DOCUMENT_2_NODE, requestVO.getNodeName());
092                    approveToPmckown = true;
093                } else if (netId.equals("temay")) {
094                    assertEquals("Should be acknowledge.", KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, requestVO.getActionRequested().getCode());
095                    assertEquals("Should be initialized.", ActionRequestStatus.INITIALIZED, requestVO.getStatus());
096                    assertEquals("Wrong node name", SeqSetup.ACKNOWLEDGE_1_NODE, requestVO.getNodeName());
097                    ackToTemay = true;
098                } else if (netId.equals("jhopf")) {
099                    assertEquals("Should be acknowledge.", KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, requestVO.getActionRequested().getCode());
100                    assertEquals("Should be initialized.", ActionRequestStatus.INITIALIZED, requestVO.getStatus());
101                    assertEquals("Wrong node name", SeqSetup.ACKNOWLEDGE_2_NODE, requestVO.getNodeName());
102                    ackToJhopf = true;
103                } 
104                assertNotNull(requestVO.getId());
105            }
106            assertTrue("There should be an approve to bmcgough", approveToBmcgough);
107            assertTrue("There should be an approve to rkirkend", approveToRkirkend);
108            assertTrue("There should be an approve to pmckown", approveToPmckown);
109            assertTrue("There should be an ack to temay", ackToTemay);
110            assertTrue("There should be an ack to jhopf", ackToJhopf);
111            
112            // assert that the report call didn't save any of the nodes or requests
113            activeNodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId());
114            requests = KEWServiceLocator.getActionRequestService().findAllActionRequestsByDocumentId(document.getDocumentId());
115            assertEquals("Should be one active node.", 1, activeNodeInstances.size());
116            assertEquals("Should be at the same node.", activeNodeId, ((RouteNodeInstance)activeNodeInstances.iterator().next()).getRouteNodeInstanceId());
117            assertEquals("Should be 2 pending requests.", 2, requests.size());
118            
119            // test reporting to a specified target node
120            criteria = RoutingReportCriteria.Builder.createByDocumentIdAndTargetNodeName(document.getDocumentId(), SeqSetup.ACKNOWLEDGE_1_NODE).build();
121            documentDetail = KewApiServiceLocator.getWorkflowDocumentActionsService().executeSimulation(criteria);
122            
123            // document detail should have all of our requests except for the final acknowledge
124            assertEquals("There should be 4 requets.", 4, documentDetail.getActionRequests().size());
125            // assert that we don't have an acknowledge to jhopf
126            for (ActionRequest requestVO : documentDetail.getActionRequests()) {
127                if (requestVO.getPrincipalId().equals(getPrincipalIdForName("jhopf"))) {
128                    fail("There should be no request to jhopf");
129                }
130            }
131        }
132    
133        private static class SeqSetup {
134            public static final String DOCUMENT_TYPE_NAME = "SeqDocType";
135            public static final String ADHOC_NODE = "AdHoc";
136            public static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
137            public static final String WORKFLOW_DOCUMENT_2_NODE = "WorkflowDocument2";
138            public static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
139            public static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
140        }
141        
142        private static class DynSetup {
143            public static final String DOCUMENT_TYPE_NAME = "DynChartOrgDocType";
144            public static final String INITIAL_NODE = "Initial";
145            public static final String CHART_ORG_NODE = "ChartOrg";
146            public static final String SPLIT_NODE_NAME = "Organization Split";
147            public static final String JOIN_NODE_NAME = "Organization Join";
148            public static final String REQUEST_NODE_NAME = "Organization Request";
149        }
150    }