View Javadoc

1   /*
2    * Copyright 2007-2010 The Kuali Foundation
3    * 
4    * 
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    * 
9    * http://www.opensource.org/licenses/ecl2.php
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.routeheader;
18  
19  
20  import org.junit.Test;
21  import org.kuali.rice.kew.dto.ActionRequestDTO;
22  import org.kuali.rice.kew.dto.DocumentStatusTransitionDTO;
23  import org.kuali.rice.kew.dto.NetworkIdDTO;
24  import org.kuali.rice.kew.dto.RouteHeaderDTO;
25  import org.kuali.rice.kew.exception.WorkflowRuntimeException;
26  import org.kuali.rice.kew.service.WorkflowDocument;
27  import org.kuali.rice.kew.service.WorkflowInfo;
28  import org.kuali.rice.kew.test.KEWTestCase;
29  import org.kuali.rice.kew.util.KEWConstants;
30  
31  
32  public class AppDocStatusTest extends KEWTestCase {
33      
34      
35      private static final String DOCUMENT_TYPE_NAME = "TestAppDocStatusDoc2";
36  	private static final String ADHOC_NODE = "AdHoc";
37  	private static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
38      private static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
39      private static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
40  	    
41      protected void loadTestData() throws Exception {
42      	super.loadTestData();
43          loadXmlFile("AppDocStatusTestConfig.xml");
44      }
45          
46      /**
47       * 
48       * This method performs several positive tests related to Application Document Status
49       * For these tests the doctype definition defines a valid set of statuses.
50       * It also defines two status transitions in the route path
51       * It tests:
52       * 	- That the AppDocStatus is properly set by the workflow engine during
53       *    appropriate transitions.
54       *  - That the AppDocStatus may be retrieved by the client API
55       *  - That the AppDocStatus may be set by the client API
56       *  - That a history of AppDocStatus transitions is created.
57       * 
58       */
59      @Test public void testValidAppDocStatus() throws Exception {
60      	// Create document
61      	WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), "TestAppDocStatusDoc2");
62      	document.saveRoutingData();
63      	assertNotNull(document.getRouteHeaderId());
64      	assertTrue("Document should be initiatied", document.stateIsInitiated());
65      	assertEquals("Invalid route level.", new Integer(0), document.getRouteHeader().getDocRouteLevel());
66      	
67      	// route document to first stop and check status, etc.
68      	document.routeDocument("Test Routing.");    	
69      	RouteHeaderDTO rh = document.getRouteHeader();
70      	String appDocStatus = rh.getAppDocStatus();
71      	assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Approval in Progress".equalsIgnoreCase(appDocStatus));
72          
73          // should have generated a request to "bmcgough"
74      	document = new WorkflowDocument(new NetworkIdDTO("bmcgough"), document.getRouteHeaderId());
75          assertTrue("Document should be enroute", document.stateIsEnroute());
76      	assertEquals("Invalid route level.", new Integer(1), document.getRouteHeader().getDocRouteLevel());
77      	String[] nodeNames = document.getNodeNames();
78      	assertEquals("Wrong number of node names.", 1, nodeNames.length);
79      	assertEquals("Wrong node name.", "DestinationApproval", nodeNames[0]);
80  
81      	// check action request
82          ActionRequestDTO[] requests = document.getActionRequests();
83          assertEquals(1, requests.length);
84          ActionRequestDTO request = requests[0];
85          assertEquals(getPrincipalIdForName("bmcgough"), request.getPrincipalId());
86          assertEquals(KEWConstants.ACTION_REQUEST_APPROVE_REQ, request.getActionRequested());
87          assertEquals(new Integer(1), request.getRouteLevel());
88          assertTrue(document.isApprovalRequested());
89          
90          // approve the document to send it to its next route node
91          document.approve("Test approve by bmcgough");
92          
93          // check status 
94          document = new WorkflowDocument(new NetworkIdDTO("temay"), document.getRouteHeaderId());
95          rh = document.getRouteHeader();
96      	appDocStatus = rh.getAppDocStatus();
97      	assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Submitted".equalsIgnoreCase(appDocStatus));
98          
99          // should have generated a request to "temay"
100     	assertTrue("Document should be enroute", document.stateIsEnroute());
101     	assertEquals("Invalid route level.", new Integer(2), document.getRouteHeader().getDocRouteLevel());
102     	nodeNames = document.getNodeNames();
103     	assertEquals("Wrong number of node names.", 1, nodeNames.length);
104     	assertEquals("Wrong node name.", "TravelerApproval", nodeNames[0]);
105     	document.approve("Test approve by temay");
106     	
107     	// update the AppDocStatus via client API
108         document.updateAppDocStatus("Completed");
109 
110         // get a refreshed document and check it out
111         document = new WorkflowDocument(new NetworkIdDTO("temay"), document.getRouteHeaderId());
112 //        assertTrue("Document should be processed.", document.stateIsProcessed());        
113         rh = document.getRouteHeader();
114     	appDocStatus = rh.getAppDocStatus();
115     	assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Completed".equalsIgnoreCase(appDocStatus));
116     	
117         // check app doc status transition history
118         WorkflowInfo info = new WorkflowInfo();
119         DocumentStatusTransitionDTO[] history = info.getDocumentStatusTransitionHistory(document.getRouteHeaderId());
120         
121         assertEquals(3, history.length);
122     	assertTrue("First History record has incorrect status", "Approval In Progress".equalsIgnoreCase(history[0].getNewAppDocStatus()));
123     	assertTrue("Second History record has incorrect old status", "Approval In Progress".equalsIgnoreCase(history[1].getOldAppDocStatus()));
124     	assertTrue("Second History record has incorrect new status", "Submitted".equalsIgnoreCase(history[1].getNewAppDocStatus()));
125     	assertTrue("Third History record has incorrect old status", "Submitted".equalsIgnoreCase(history[2].getOldAppDocStatus()));
126     	assertTrue("Third History record has incorrect new status", "Completed".equalsIgnoreCase(history[2].getNewAppDocStatus()));
127                
128     	// TODO when we are able to, we should also verify the RouteNodeInstances are correct
129         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
130     	assertTrue("Document should be final.", document.stateIsFinal());
131     }        
132 
133     /**
134      * 
135      * This method is similar to the above test, except that the doctype definition
136      * does NOT specify a valid set of values.  This means that the value can be any valid string.
137      * 
138      * @throws Exception
139      */
140     @Test public void testAppDocStatusValuesNotDefined() throws Exception {
141     	// Create document
142     	WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), "TestAppDocStatusDoc1");
143     	document.saveRoutingData();
144     	assertNotNull(document.getRouteHeaderId());
145     	assertTrue("Document should be initiatied", document.stateIsInitiated());
146     	assertEquals("Invalid route level.", new Integer(0), document.getRouteHeader().getDocRouteLevel());
147     	
148     	// route document to first stop and check status, etc.
149     	document.routeDocument("Test Routing.");    	
150     	RouteHeaderDTO rh = document.getRouteHeader();
151     	String appDocStatus = rh.getAppDocStatus();
152     	assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Approval in Progress".equalsIgnoreCase(appDocStatus));
153         
154         // should have generated a request to "bmcgough"
155     	document = new WorkflowDocument(new NetworkIdDTO("bmcgough"), document.getRouteHeaderId());
156         assertTrue("Document should be enroute", document.stateIsEnroute());
157     	assertEquals("Invalid route level.", new Integer(1), document.getRouteHeader().getDocRouteLevel());
158     	String[] nodeNames = document.getNodeNames();
159     	assertEquals("Wrong number of node names.", 1, nodeNames.length);
160     	assertEquals("Wrong node name.", "step1", nodeNames[0]);
161 
162     	// check action request
163         ActionRequestDTO[] requests = document.getActionRequests();
164         assertEquals(1, requests.length);
165         ActionRequestDTO request = requests[0];
166         assertEquals(getPrincipalIdForName("bmcgough"), request.getPrincipalId());
167         assertEquals(KEWConstants.ACTION_REQUEST_APPROVE_REQ, request.getActionRequested());
168         assertEquals(new Integer(1), request.getRouteLevel());
169         assertTrue(document.isApprovalRequested());
170         
171         // approve the document to send it to its next route node
172         document.approve("Test approve by bmcgough");
173         
174         // check status 
175         document = new WorkflowDocument(new NetworkIdDTO("temay"), document.getRouteHeaderId());
176         rh = document.getRouteHeader();
177     	appDocStatus = rh.getAppDocStatus();
178     	assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Submitted".equalsIgnoreCase(appDocStatus));
179         
180         // should have generated a request to "temay"
181     	assertTrue("Document should be enroute", document.stateIsEnroute());
182     	assertEquals("Invalid route level.", new Integer(2), document.getRouteHeader().getDocRouteLevel());
183     	nodeNames = document.getNodeNames();
184     	assertEquals("Wrong number of node names.", 1, nodeNames.length);
185     	assertEquals("Wrong node name.", "step2", nodeNames[0]);
186     	document.approve("Test approve by temay");
187     	
188     	// update the AppDocStatus via client API
189         document.updateAppDocStatus("Some Random Value");
190 
191         // get a refreshed document and check it out
192         document = new WorkflowDocument(new NetworkIdDTO("temay"), document.getRouteHeaderId());
193 //        assertTrue("Document should be processed.", document.stateIsProcessed());        
194         rh = document.getRouteHeader();
195     	appDocStatus = rh.getAppDocStatus();
196     	assertTrue("Application Document Status:" + appDocStatus +" is invalid", "Some Random Value".equalsIgnoreCase(appDocStatus));
197     	
198         // check app doc status transition history
199         WorkflowInfo info = new WorkflowInfo();
200         DocumentStatusTransitionDTO[] history = info.getDocumentStatusTransitionHistory(document.getRouteHeaderId());
201         
202         assertEquals(3, history.length);
203     	assertTrue("First History record has incorrect status", "Approval In Progress".equalsIgnoreCase(history[0].getNewAppDocStatus()));
204     	assertTrue("Second History record has incorrect old status", "Approval In Progress".equalsIgnoreCase(history[1].getOldAppDocStatus()));
205     	assertTrue("Second History record has incorrect new status", "Submitted".equalsIgnoreCase(history[1].getNewAppDocStatus()));
206     	assertTrue("Third History record has incorrect old status", "Submitted".equalsIgnoreCase(history[2].getOldAppDocStatus()));
207     	assertTrue("Third History record has incorrect new status", "Some Random Value".equalsIgnoreCase(history[2].getNewAppDocStatus()));
208                
209     	// TODO when we are able to, we should also verify the RouteNodeInstances are correct
210         document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), document.getRouteHeaderId());
211     	assertTrue("Document should be final.", document.stateIsFinal());
212     }        
213 
214     /**
215      * 
216      * This test attempts to set an invalid status value for a document that has a valid set
217      * of statuses defined.
218      * It expects to throw a WorkflowRuntimeException when attempting to set the invalid status value.
219      * 
220      * @throws Exception
221      */
222     @Test public void testInvalidAppDocStatusValue() throws Exception {
223     	WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), "TestAppDocStatusDoc2");
224     	document.saveRoutingData();
225     	assertNotNull(document.getRouteHeaderId());
226     	assertTrue("Document should be initiatied", document.stateIsInitiated());
227     	assertEquals("Invalid route level.", new Integer(0), document.getRouteHeader().getDocRouteLevel());
228     	    	
229     	// update the AppDocStatus via client API
230     	boolean gotException = false;
231     	try {
232     		document.updateAppDocStatus("BAD STATUS");
233     	} catch (Throwable t){
234     		gotException = true;
235     		WorkflowRuntimeException ex = new WorkflowRuntimeException();
236     		assertEquals("WrongExceptionType", t.getClass(), ex.getClass());
237     	} finally {
238     		assertTrue("Expected WorkflowRuntimeException not thrown.", gotException);
239     		
240     	}
241     }
242 }