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.engine;
017
018import org.junit.Test;
019import org.kuali.rice.kew.api.WorkflowDocument;
020import org.kuali.rice.kew.api.WorkflowDocumentFactory;
021import org.kuali.rice.kew.api.action.ActionRequest;
022import org.kuali.rice.kew.api.action.ActionRequestStatus;
023import org.kuali.rice.kew.api.action.ActionRequestType;
024import org.kuali.rice.kew.engine.node.RouteNodeInstance;
025import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
026import org.kuali.rice.kew.service.KEWServiceLocator;
027import org.kuali.rice.kew.test.KEWTestCase;
028import org.kuali.rice.kew.test.TestUtilities;
029
030import java.util.List;
031import java.util.Set;
032
033import static org.junit.Assert.*;
034
035public class SequentialRoutingTest extends KEWTestCase {
036    
037    
038    private static final String DOCUMENT_TYPE_NAME = "SeqDocType";
039        private static final String ADHOC_NODE = "AdHoc";
040        private static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
041    private static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
042    private static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
043            
044    protected void loadTestData() throws Exception {
045        loadXmlFile("EngineConfig.xml");
046    }
047
048    @Test public void testSequentialRoute() throws Exception {
049        WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), DOCUMENT_TYPE_NAME);
050        document.saveDocumentData();
051        assertNotNull(document.getDocumentId());
052
053        DocumentRouteHeaderValue drhv = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
054
055        assertTrue("Document should be initiatied", document.isInitiated());
056        Set<String> nodeNames = document.getNodeNames();
057        assertEquals("Wrong number of node names.", 1, nodeNames.size());
058        assertEquals("Wrong node name.", ADHOC_NODE, nodeNames.iterator().next());
059        document.route("Routing sequentially.");
060        
061        // should have generated a request to "bmcgough"
062        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
063        assertTrue("Document should be enroute", document.isEnroute());
064        nodeNames = document.getNodeNames();
065        assertEquals("Wrong number of node names.", 1, nodeNames.size());
066        assertEquals("Wrong node name.", WORKFLOW_DOCUMENT_NODE, nodeNames.iterator().next());
067        List<ActionRequest> requests = document.getRootActionRequests();
068        assertEquals(1, requests.size());
069        ActionRequest request = requests.get(0);
070        assertEquals(getPrincipalIdForName("bmcgough"), request.getPrincipalId());
071        assertEquals(ActionRequestType.APPROVE, request.getActionRequested());
072        TestUtilities.assertAtNode(document, WORKFLOW_DOCUMENT_NODE);
073        assertTrue(document.isApprovalRequested());
074        document.approve("Test approve by bmcgough");
075        
076        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
077        assertTrue("Document should be processed.", document.isProcessed());
078        requests = document.getRootActionRequests();
079        assertEquals(3, requests.size());
080        boolean toTemay = false;
081        boolean toJhopf = false;
082        for (int i = 0; i < requests.size(); i++) {
083            ActionRequest requestVO = requests.get(i);
084            if (requestVO.getPrincipalId().equals(getPrincipalIdForName("temay"))) {
085                toTemay = true;
086                assertEquals(ActionRequestType.ACKNOWLEDGE, requestVO.getActionRequested());
087                assertEquals(ACKNOWLEDGE_1_NODE, requestVO.getNodeName());
088                assertEquals(ActionRequestStatus.ACTIVATED, requestVO.getStatus());
089            } else if (requestVO.getPrincipalId().equals(getPrincipalIdForName("jhopf"))) {
090                toJhopf = true;
091                assertEquals(ActionRequestType.ACKNOWLEDGE, requestVO.getActionRequested());
092                assertEquals(ACKNOWLEDGE_2_NODE, requestVO.getNodeName());
093                assertEquals(ActionRequestStatus.ACTIVATED, requestVO.getStatus());
094            }
095        }
096        assertTrue("Should be an acknowledge to temay", toTemay);
097        assertTrue("Should be an acknowledge to jhopf", toJhopf);
098//        assertEquals(ACKNOWLEDGE_2_NODE, document.getRouteHeader().getNodeNames()[0]);
099        // have temay take her acknowledge
100        document.acknowledge("Temay taking acknowledge");
101        
102        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
103        assertTrue("Document should be processed.", document.isProcessed());
104        requests = document.getRootActionRequests();
105        toTemay = false;
106        toJhopf = false;
107        for (int i = 0; i < requests.size(); i++) {
108            ActionRequest requestVO = requests.get(i);
109            if (requestVO.getPrincipalId().equals(getPrincipalIdForName("temay"))) {
110                toTemay = true;
111                assertEquals(ActionRequestType.ACKNOWLEDGE, requestVO.getActionRequested());
112                assertEquals(ActionRequestStatus.DONE, requestVO.getStatus());
113            } else if (requestVO.getPrincipalId().equals(getPrincipalIdForName("jhopf"))) {
114                toJhopf = true;
115                assertEquals(ActionRequestType.ACKNOWLEDGE, requestVO.getActionRequested());
116                assertEquals(ACKNOWLEDGE_2_NODE, requestVO.getNodeName());
117                assertEquals(ActionRequestStatus.ACTIVATED, requestVO.getStatus());
118            }
119        }
120        assertTrue("Should be a DONE acknowledge to temay", toTemay);
121        assertTrue("Should be an acknowledge to jhopf", toJhopf);
122        // have jhopf take his acknowledge, this should cause the document to go final
123        document.acknowledge("Jhopf taking acknowledge");
124        
125        // TODO when we are able to, we should also verify the RouteNodeInstances are correct
126        document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
127        assertTrue("Document should be final.", document.isFinal());
128        
129        verifyRoutingPath(document.getDocumentId());
130    }        
131
132    private void verifyRoutingPath(String documentId) {
133        DocumentRouteHeaderValue document = KEWServiceLocator.getRouteHeaderService().getRouteHeader(documentId);
134        List initial = document.getInitialRouteNodeInstances();
135        assertEquals(1, initial.size());
136        RouteNodeInstance adhoc = (RouteNodeInstance)initial.get(0);
137        assertEquals(ADHOC_NODE, adhoc.getRouteNode().getRouteNodeName());
138        assertEquals(0, adhoc.getPreviousNodeInstances().size());
139        
140        List next = adhoc.getNextNodeInstances();
141        assertEquals(1, next.size());
142        RouteNodeInstance wd = (RouteNodeInstance)next.get(0);
143        assertEquals(WORKFLOW_DOCUMENT_NODE, wd.getRouteNode().getRouteNodeName());
144        assertEquals(1, wd.getPreviousNodeInstances().size());
145        
146        next = wd.getNextNodeInstances();
147        assertEquals(1, next.size());
148        RouteNodeInstance ack1 = (RouteNodeInstance)next.get(0);
149        assertEquals(ACKNOWLEDGE_1_NODE, ack1.getRouteNode().getRouteNodeName());
150        assertEquals(1, ack1.getPreviousNodeInstances().size());
151        
152        next = ack1.getNextNodeInstances();
153        assertEquals(1, next.size());
154        RouteNodeInstance ack2 = (RouteNodeInstance)next.get(0);
155        assertEquals(ACKNOWLEDGE_2_NODE, ack2.getRouteNode().getRouteNodeName());
156        assertEquals(1, ack2.getPreviousNodeInstances().size());
157        
158        next = ack2.getNextNodeInstances();
159        assertEquals(0, next.size());
160    }
161
162}