View Javadoc

1   /**
2    * Copyright 2005-2011 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.server;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.joda.time.DateTime;
20  import org.junit.Test;
21  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
22  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
23  import org.kuali.rice.core.api.parameter.Parameter;
24  import org.kuali.rice.core.framework.services.CoreFrameworkServiceLocator;
25  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
26  import org.kuali.rice.kew.api.KewApiServiceLocator;
27  import org.kuali.rice.kew.api.WorkflowDocument;
28  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
29  import org.kuali.rice.kew.api.action.ActionItem;
30  import org.kuali.rice.kew.api.action.ActionRequest;
31  import org.kuali.rice.kew.api.action.ActionRequestType;
32  import org.kuali.rice.kew.api.action.RoutingReportActionToTake;
33  import org.kuali.rice.kew.api.action.RoutingReportCriteria;
34  import org.kuali.rice.kew.api.action.WorkflowDocumentActionsService;
35  import org.kuali.rice.kew.api.actionlist.ActionListService;
36  import org.kuali.rice.kew.api.document.DocumentDetail;
37  import org.kuali.rice.kew.api.document.DocumentStatus;
38  import org.kuali.rice.kew.api.document.WorkflowDocumentService;
39  import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
40  import org.kuali.rice.kew.api.document.search.DocumentSearchResult;
41  import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
42  import org.kuali.rice.kew.api.document.search.RouteNodeLookupLogic;
43  import org.kuali.rice.kew.api.exception.WorkflowException;
44  import org.kuali.rice.kew.api.rule.Rule;
45  import org.kuali.rice.kew.api.rule.RuleReportCriteria;
46  import org.kuali.rice.kew.api.rule.RuleResponsibility;
47  import org.kuali.rice.kew.api.rule.RuleService;
48  import org.kuali.rice.kew.docsearch.DocumentSearchInternalUtils;
49  import org.kuali.rice.kew.docsearch.TestXMLSearchableAttributeDateTime;
50  import org.kuali.rice.kew.docsearch.TestXMLSearchableAttributeFloat;
51  import org.kuali.rice.kew.docsearch.TestXMLSearchableAttributeLong;
52  import org.kuali.rice.kew.docsearch.TestXMLSearchableAttributeString;
53  import org.kuali.rice.kew.service.KEWServiceLocator;
54  import org.kuali.rice.kew.test.KEWTestCase;
55  import org.kuali.rice.kew.test.TestUtilities;
56  import org.kuali.rice.kew.api.KewApiConstants;
57  import org.kuali.rice.kim.api.KimConstants;
58  import org.kuali.rice.kim.api.group.Group;
59  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
60  import org.kuali.rice.krad.util.KRADConstants;
61  import org.kuali.rice.test.BaselineTestCase;
62  
63  import java.rmi.RemoteException;
64  import java.sql.Timestamp;
65  import java.util.ArrayList;
66  import java.util.Arrays;
67  import java.util.Calendar;
68  import java.util.Collection;
69  import java.util.Collections;
70  import java.util.HashMap;
71  import java.util.HashSet;
72  import java.util.Iterator;
73  import java.util.List;
74  import java.util.Map;
75  import java.util.Set;
76  
77  import static org.junit.Assert.*;
78  
79  @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
80  public class WorkflowUtilityTest extends KEWTestCase {
81      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(WorkflowUtilityTest.class);
82  
83  	protected void loadTestData() throws Exception {
84          loadXmlFile("WorkflowUtilityConfig.xml");
85      }
86  
87  	@Test
88      public void testGetDocumentDetailByAppId() throws WorkflowException{
89          WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.DOCUMENT_TYPE_NAME);
90          document.setApplicationDocumentId("123456789");
91          document.route("");
92          WorkflowDocumentService documentService = KewApiServiceLocator.getWorkflowDocumentService();
93          DocumentDetail doc= documentService.getDocumentDetailByAppId(SeqSetup.DOCUMENT_TYPE_NAME, "123456789");
94      	
95      	assertNotNull(doc);
96      	
97          document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.DOCUMENT_TYPE_NAME);
98          document.setApplicationDocumentId("123456789");
99          document.route("");
100 
101         try{
102         	documentService.getDocumentDetailByAppId(SeqSetup.DOCUMENT_TYPE_NAME, "123456789");
103         	assertTrue(false);
104         }catch(RiceIllegalStateException e){
105         	assertTrue(true);
106         }
107         
108         try{
109         	documentService.getDocumentDetailByAppId("notExist", "wrong");
110         	assertTrue(false);
111         }catch(RiceIllegalStateException e){
112         	assertTrue(true);
113         }
114         
115         try{
116         	documentService.getDocumentDetailByAppId("notExist", null);
117         	assertTrue(false);
118         }catch(RiceIllegalArgumentException e){
119         	assertTrue(true);
120         }
121     	
122         try{
123         	documentService.getDocumentDetailByAppId(null, null);
124         	assertTrue(false);
125         }catch(RiceIllegalArgumentException e){
126         	assertTrue(true);
127         }
128         
129     }
130 
131     @Test public void testGetActionsRequested() throws Exception {
132         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.DOCUMENT_TYPE_NAME);
133         document.route("");
134         assertActionsRequested("ewestfal", document.getDocumentId());
135         assertActionsRequested("bmcgough", document.getDocumentId());
136         assertActionsRequested("rkirkend", document.getDocumentId());
137     }
138 
139     protected void assertActionsRequested(String principalName, String documentId) throws Exception {
140     	Map<String, String> attrSet = KewApiServiceLocator.getWorkflowDocumentService().getActionsRequested(
141                 getPrincipalIdForName(principalName), documentId);
142     	assertNotNull("Actions requested should be populated", attrSet);
143     	assertFalse("Actions requested should be populated with at least one entry", attrSet.isEmpty());
144     	assertEquals("Wrong number of actions requested", 4, attrSet.size());
145     }
146 
147     @Test
148     public void testIsUserInRouteLog() throws Exception {
149         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.DOCUMENT_TYPE_NAME);
150         document.route("");
151         assertTrue(document.isEnroute());
152         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
153         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("ewestfal"), false));
154         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), false));
155         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), false));
156         assertFalse("User should not be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), false));
157         assertFalse("User should not be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("temay"), false));
158         assertFalse("User should not be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("jhopf"), false));
159         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), true));
160         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("temay"), true));
161         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("jhopf"), true));
162 
163         // test that we can run isUserInRouteLog on a SAVED document
164         document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.DOCUMENT_TYPE_NAME);
165         document.saveDocument("");
166         assertTrue(document.isSaved());
167         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("ewestfal"), false));
168         assertFalse("User should not be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), false));
169         assertFalse("User should not be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), false));
170         assertFalse("User should not be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), false));
171         assertFalse("User should not be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("temay"), false));
172         assertFalse("User should not be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("jhopf"), false));
173 
174         // now look all up in the future of this saved document
175         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true));
176         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true));
177         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), true));
178         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("temay"), true));
179         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("jhopf"), true));
180     }
181 
182     @Test public void testIsUserInRouteLogAfterReturnToPrevious() throws Exception {
183 	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.DOCUMENT_TYPE_NAME);
184         document.route("");
185         assertTrue(document.isEnroute());
186 
187         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
188         assertTrue(document.isApprovalRequested());
189         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
190         assertTrue(document.isApprovalRequested());
191 
192         // bmcgough and rkirkend should be in route log
193         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
194         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), false));
195         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), false));
196         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true));
197         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true));
198         assertFalse("User should NOT be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), false));
199         // Phil of the future
200         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), true));
201         TestUtilities.assertAtNode(document, "WorkflowDocument");
202 
203         document.returnToPreviousNode("", "AdHoc");
204         TestUtilities.assertAtNode(document, "AdHoc");
205         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
206         assertTrue(document.isApprovalRequested());
207 
208         document.approve("");
209 
210         // we should be back where we were
211         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
212         assertTrue(document.isApprovalRequested());
213         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
214         assertTrue(document.isApprovalRequested());
215         TestUtilities.assertAtNode(document, "WorkflowDocument");
216 
217         // now verify that is route log authenticated still works
218         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), false));
219         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), false));
220         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true));
221         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true));
222         assertFalse("User should NOT be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), false));
223         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), true));
224 
225         // let's look at the revoked node instances
226 
227         List revokedNodeInstances = KEWServiceLocator.getRouteNodeService().getRevokedNodeInstances(KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId()));
228         assertNotNull(revokedNodeInstances);
229         assertEquals(2, revokedNodeInstances.size());
230 
231         // let's approve past this node and another
232         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
233         document.approve("");
234         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
235         document.approve("");
236 
237         // should be at WorkflowDocument2
238         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("pmckown"), document.getDocumentId());
239         TestUtilities.assertAtNode(document, "WorkflowDocument2");
240         assertTrue(document.isApprovalRequested());
241         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), false));
242         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), false));
243         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true));
244         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true));
245         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), false));
246         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), true));
247 
248         // now return back to WorkflowDocument
249         document.returnToPreviousNode("WorkflowDocument", "");
250         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
251         assertTrue(document.isApprovalRequested());
252         // Phil should no longer be non-future route log authenticated
253         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), false));
254         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), false));
255         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true));
256         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true));
257         assertFalse("User should NOT be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), false));
258         assertTrue("User should be authenticated.", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("pmckown"), true));
259     }
260     
261     @Test
262     public void testIsUserInRouteLogWithSplits() throws Exception {
263     	loadXmlFile("WorkflowUtilitySplitConfig.xml");
264     	
265     	// initialize the split node to both branches
266     	TestSplitNode.setLeftBranch(true);
267     	TestSplitNode.setRightBranch(true);
268     	
269     	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("admin"), "UserInRouteLog_Split");
270         document.route("");
271         
272         // document should be in ewestfal action list
273         document = TestUtilities.switchByPrincipalName("ewestfal", document);
274         assertTrue("should have approve", document.isApprovalRequested());
275         TestUtilities.assertAtNode(document, "BeforeSplit");
276         
277         // now let's run some simulations
278         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
279         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("ewestfal"), true));
280         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true));
281         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true));
282         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("jhopf"), true));
283         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("natjohns"), true));
284         assertFalse("should NOT be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("user1"), true));
285         
286         // now let's activate only the left branch and make sure the split is properly executed
287         TestSplitNode.setRightBranch(false);
288         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true));
289         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true));
290         assertFalse("should NOT be in route log because right branch is not active", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("jhopf"), true));
291         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("natjohns"), true));
292         
293         // now let's do a flattened evaluation, it should hit both branches
294         assertTrue("should be in route log", wdas.isUserInRouteLogWithOptionalFlattening(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true, true));
295         assertTrue("should be in route log", wdas.isUserInRouteLogWithOptionalFlattening(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true, true));
296         assertTrue("should be in route log because we've flattened nodes", wdas.isUserInRouteLogWithOptionalFlattening(document.getDocumentId(), getPrincipalIdForName("jhopf"), true, true));
297         assertTrue("should be in route log", wdas.isUserInRouteLogWithOptionalFlattening(document.getDocumentId(), getPrincipalIdForName("natjohns"), true, true));
298         
299         // now let's switch to the right branch
300         TestSplitNode.setRightBranch(true);
301         TestSplitNode.setLeftBranch(false);
302         
303         assertFalse("should NOT be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true));
304         assertFalse("should NOT be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true));
305         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("jhopf"), true));
306         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("natjohns"), true));
307 
308         // now let's switch back to the left branch and approve it
309         TestSplitNode.setLeftBranch(true);
310         TestSplitNode.setRightBranch(false);
311         
312         // now let's approve it so that we're inside the right branch of the split
313         document.approve("");
314         // shoudl be at SplitLeft1 node
315         TestUtilities.assertAtNode(document, "SplitLeft1");
316         
317         document = TestUtilities.switchByPrincipalName("rkirkend", document);
318         assertTrue("should have an approve request", document.isApprovalRequested());
319         
320         // now let's run the simulation so we can test running from inside a split branch
321         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("rkirkend"), true));
322         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("bmcgough"), true));
323         assertFalse("should NOT be in route log because right branch is not active", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("jhopf"), true));
324         assertTrue("should be in route log", wdas.isUserInRouteLog(document.getDocumentId(), getPrincipalIdForName("natjohns"), true));
325     }
326     
327     public abstract interface ReportCriteriaGenerator { public abstract RoutingReportCriteria buildCriteria(WorkflowDocument workflowDoc) throws Exception; public boolean isCriteriaRouteHeaderBased();}
328 
329     private class ReportCriteriaGeneratorUsingXML implements ReportCriteriaGenerator {
330         public RoutingReportCriteria buildCriteria(WorkflowDocument workflowDoc) throws Exception {
331             RoutingReportCriteria.Builder criteria = RoutingReportCriteria.Builder.createByDocumentTypeName(
332                     workflowDoc.getDocumentTypeName());
333             criteria.setXmlContent(workflowDoc.getDocumentContent().getApplicationContent());
334             return criteria.build();
335         }
336         public boolean isCriteriaRouteHeaderBased() {
337             return false;
338         }
339     }
340 
341     private class ReportCriteriaGeneratorUsingDocumentId implements ReportCriteriaGenerator {
342         public RoutingReportCriteria buildCriteria(WorkflowDocument workflowDoc) throws Exception {
343             RoutingReportCriteria.Builder criteria = RoutingReportCriteria.Builder.createByDocumentId(workflowDoc.getDocumentId());
344             return criteria.build();
345         }
346         public boolean isCriteriaRouteHeaderBased() {
347             return true;
348         }
349     }
350 
351     @Test public void testDocumentWillHaveApproveOrCompleteRequestAtNode_DocumentId() throws Exception {
352         runDocumentWillHaveApproveOrCompleteRequestAtNode(SeqSetup.DOCUMENT_TYPE_NAME,new ReportCriteriaGeneratorUsingDocumentId());
353     }
354 
355     @Test public void testDocumentWillHaveApproveOrCompleteRequestAtNode_XmlContent() throws Exception {
356         runDocumentWillHaveApproveOrCompleteRequestAtNode(SeqSetup.DOCUMENT_TYPE_NAME,new ReportCriteriaGeneratorUsingXML());
357     }
358 
359     @Test public void testDocumentWillHaveApproveOrCompleteRequestAtNode_ForceAction_DocumentId() throws Exception {
360         runDocumentWillHaveApproveOrCompleteRequestAtNode_ForceAction("SimulationTestDocumenType_ForceAction",new ReportCriteriaGeneratorUsingDocumentId());
361     }
362 
363     @Test public void testDocumentWillHaveApproveOrCompleteRequestAtNode_ForceAction_XmlContent() throws Exception {
364         runDocumentWillHaveApproveOrCompleteRequestAtNode_ForceAction("SimulationTestDocumenType_ForceAction",new ReportCriteriaGeneratorUsingXML());
365     }
366 
367     private void runDocumentWillHaveApproveOrCompleteRequestAtNode_ForceAction(String documentType, ReportCriteriaGenerator generator) throws Exception {
368       /*
369         name="WorkflowDocument"
370           -  rkirkend - Approve - false
371         name="WorkflowDocument2"
372           -  rkirkend - Approve - false
373         name="WorkflowDocument3"
374           -  rkirkend - Approve - true
375         name="WorkflowDocument4"
376           -  rkirkend - Approve - false
377           -  jitrue   - Approve - true
378       */
379         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
380 
381         WorkflowDocument doc = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), documentType);
382         RoutingReportCriteria.Builder builder = RoutingReportCriteria.Builder.createByDocumentId(doc.getDocumentId());
383         builder.setXmlContent(doc.getDocumentContent().getApplicationContent());
384         builder.setTargetNodeName("WorkflowDocument2");
385         builder.setRoutingPrincipalId(getPrincipalIdForName("bmcgough"));
386         assertTrue("Document should have at least one unfulfilled approve/complete request",wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
387         builder.setTargetPrincipalIds(Collections.singletonList(getPrincipalIdForName("bmcgough")));
388         assertFalse("Document should not have any unfulfilled approve/complete requests",wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
389 
390         builder = RoutingReportCriteria.Builder.createByDocumentId(doc.getDocumentId());
391         builder.setXmlContent(doc.getDocumentContent().getApplicationContent());
392         builder.setTargetNodeName("WorkflowDocument4");
393         builder.setRoutingPrincipalId(getPrincipalIdForName("bmcgough"));
394         List<RoutingReportActionToTake.Builder> actionsToTake = new ArrayList<RoutingReportActionToTake.Builder>();
395         actionsToTake.add(RoutingReportActionToTake.Builder.create(KewApiConstants.ACTION_TAKEN_APPROVED_CD,getPrincipalIdForName("rkirkend"),"WorkflowDocument3"));
396         actionsToTake.add(RoutingReportActionToTake.Builder.create(KewApiConstants.ACTION_TAKEN_APPROVED_CD,
397                 getPrincipalIdForName("jitrue"), "WorkflowDocument4"));
398 
399         builder.setActionsToTake(actionsToTake);
400         assertFalse("Document should not have any unfulfilled approve/complete requests",
401                 wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(
402                         new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,
403                                 KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
404 
405         builder = RoutingReportCriteria.Builder.createByDocumentId(doc.getDocumentId());
406         builder.setXmlContent(doc.getDocumentContent().getApplicationContent());
407         builder.setTargetNodeName("WorkflowDocument4");
408         actionsToTake = new ArrayList<RoutingReportActionToTake.Builder>();
409         actionsToTake.add(RoutingReportActionToTake.Builder.create(KewApiConstants.ACTION_TAKEN_APPROVED_CD,getPrincipalIdForName("rkirkend"),"WorkflowDocument3"));
410         actionsToTake.add(RoutingReportActionToTake.Builder.create(KewApiConstants.ACTION_TAKEN_APPROVED_CD,getPrincipalIdForName("jitrue"),"WorkflowDocument4"));
411         builder.setActionsToTake(actionsToTake);
412         assertFalse("Document should not have any unfulfilled approve/complete requests", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
413 
414         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), documentType);
415         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
416         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
417         builder.setRoutingPrincipalId(getPrincipalIdForName("rkirkend"));
418         builder.setTargetNodeName("WorkflowDocument");
419         assertFalse("Document should not have any approve/complete requests", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
420 
421         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
422         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
423         builder.setRoutingPrincipalId(getPrincipalIdForName("rkirkend"));
424         builder.setTargetNodeName("WorkflowDocument2");
425         assertFalse("Document should not have any approve/complete requests", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
426 
427         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
428         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
429         builder.setRoutingPrincipalId(getPrincipalIdForName("rkirkend"));
430         builder.setTargetPrincipalIds(Collections.singletonList(getPrincipalIdForName("rkirkend")));
431         assertFalse("Document should not have any approve/complete requests for user rkirkend", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
432 
433         document.route("");
434         assertEquals("Document should be enroute", DocumentStatus.ENROUTE, document.getStatus());
435         assertEquals("Document route node is incorrect", "WorkflowDocument3", document.getNodeNames().iterator().next());
436         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
437         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
438         builder.setTargetNodeName("WorkflowDocument4");
439         assertTrue("At least one unfulfilled approve/complete request should have been generated", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
440 
441         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
442         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
443         builder.setTargetPrincipalIds(Collections.singletonList(getPrincipalIdForName("rkirkend")));
444         assertTrue("At least one unfulfilled approve/complete request should have been generated for rkirkend", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
445 
446         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
447         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
448         builder.setTargetNodeName("WorkflowDocument4");
449         assertTrue("At least one unfulfilled approve/complete request should have been generated", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
450 
451         // if rkirkend approvers the document here it will move to last route node and no more simulations need to be run
452         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
453         document.approve("");
454         assertEquals("Document should be enroute", DocumentStatus.ENROUTE, document.getStatus());
455         assertEquals("Document route node is incorrect", "WorkflowDocument4", document.getNodeNames().iterator().next());
456     }
457 
458     private void runDocumentWillHaveApproveOrCompleteRequestAtNode(String documentType,ReportCriteriaGenerator generator) throws Exception {
459       /*
460         name="WorkflowDocument"
461           -  bmcgough - Approve - false
462           -  rkirkend - Approve - false
463         name="WorkflowDocument2"
464           -  pmckown - Approve - false
465         name="Acknowledge1"
466           -  temay - Ack - false
467         name="Acknowledge2"
468           -  jhopf - Ack - false
469       */
470         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
471 
472         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), documentType);
473         RoutingReportCriteria.Builder builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
474         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
475         builder.setTargetNodeName("WorkflowDocument2");
476         builder.setRoutingPrincipalId(getPrincipalIdForName("bmcgough"));
477         assertTrue("Document should have one unfulfilled approve/complete request", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
478         builder.setTargetPrincipalIds(Collections.singletonList(getPrincipalIdForName("bmcgough")));
479         assertFalse("Document should not have any unfulfilled approve/complete requests", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
480 
481         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
482         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
483         builder.setTargetNodeName("WorkflowDocument2");
484         builder.setRoutingPrincipalId(getPrincipalIdForName("bmcgough"));
485         List<RoutingReportActionToTake.Builder> actionsToTake = new ArrayList<RoutingReportActionToTake.Builder>();
486 //        actionsToTake[0] = new ReportActionToTakeDTO(KewApiConstants.ACTION_TAKEN_APPROVED_CD,getPrincipalIdForName("rkirkend"),"WorkflowDocument");
487         actionsToTake.add(RoutingReportActionToTake.Builder.create(KewApiConstants.ACTION_TAKEN_APPROVED_CD,getPrincipalIdForName("pmckown"),"WorkflowDocument2"));
488         builder.setActionsToTake(actionsToTake);
489         assertFalse("Document should not have any unfulfilled approve/complete requests", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
490 
491         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
492         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
493         builder.setTargetNodeName("WorkflowDocument2");
494         actionsToTake = new ArrayList<RoutingReportActionToTake.Builder>();
495         actionsToTake.add(RoutingReportActionToTake.Builder.create(KewApiConstants.ACTION_TAKEN_APPROVED_CD,getPrincipalIdForName("bmcgough"),"WorkflowDocument"));
496         actionsToTake.add(RoutingReportActionToTake.Builder.create(KewApiConstants.ACTION_TAKEN_APPROVED_CD,getPrincipalIdForName("rkirkend"),"WorkflowDocument"));
497         builder.setActionsToTake(actionsToTake);
498         builder.setRoutingPrincipalId(getPrincipalIdForName("pmckown"));
499         assertFalse("Document should not have any unfulfilled approve/complete requests", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
500 
501         document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), documentType);
502         document.route("");
503         assertTrue(document.isEnroute());
504 
505         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
506         document.approve("");
507 
508         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
509         document.approve("");
510 
511         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
512         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
513         builder.setTargetNodeName("WorkflowDocument2");
514         assertTrue("Document should have one unfulfilled approve/complete request", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
515 
516         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("pmckown"), document.getDocumentId());
517         document.approve("");
518         assertTrue(document.isProcessed());
519 
520         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
521         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
522         builder.setTargetNodeName("Acknowledge1");
523         assertFalse("Document should not have any unfulfilled approve/complete requests when in processed status", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ,KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}), false));
524 
525         builder = RoutingReportCriteria.Builder.createByDocumentId(document.getDocumentId());
526         builder.setXmlContent(document.getDocumentContent().getApplicationContent());
527         builder.setTargetNodeName("Acknowledge1");
528         assertTrue("Document should have one unfulfilled Ack request when in final status", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ}), false));
529         if (generator.isCriteriaRouteHeaderBased()) {
530             assertFalse("Document should have no unfulfilled Ack request generated when in final status", wdas.documentWillHaveAtLeastOneActionRequest(builder.build(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ}), true));
531         }
532 
533         // if temay acknowledges the document here it will move to processed and no more simulations would need to be tested
534         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
535         document.acknowledge("");
536         assertTrue(document.isProcessed());
537     }
538 
539     @Test public void testIsLastApprover() throws Exception {
540         // test the is last approver in route level against our sequential document type
541         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.DOCUMENT_TYPE_NAME);
542         document.saveDocumentData();
543 
544         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
545 
546         // the initial "route level" should have no requests initially so it should return false
547         assertFalse("Should not be last approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.ADHOC_NODE));
548 
549         // app specific route a request to a workgroup at the initial node (TestWorkgroup)
550 		String groupId = getGroupIdForName(KimConstants.KIM_GROUP_WORKFLOW_NAMESPACE_CODE, "TestWorkgroup");
551         document.adHocToGroup(ActionRequestType.APPROVE, "AdHoc", "", groupId, "", false);
552 
553         assertTrue("Should be last approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.ADHOC_NODE));
554 
555         // app specific route a request to a member of the workgroup (jitrue)
556         document.adHocToPrincipal(ActionRequestType.APPROVE, "AdHoc", "", getPrincipalIdForName("jitrue"), "", false);
557         // member of the workgroup with the user request should be last approver
558         assertTrue("Should be last approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("jitrue"), SeqSetup.ADHOC_NODE));
559         // other members of the workgroup will not be last approvers because they don't satisfy the individuals request (ewestfal)
560         assertFalse("Should not be last approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.ADHOC_NODE));
561 
562         // route the document, should stay at the adhoc node until those requests have been completed
563         document.route("");
564         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jitrue"), document.getDocumentId());
565         assertEquals("Document should be at adhoc node.", SeqSetup.ADHOC_NODE, document.getNodeNames().iterator().next());
566         assertTrue("Approve should be requested.", document.isApprovalRequested());
567         document.approve("");
568 
569         // document should now be at the WorkflowDocument node with a request to bmcgough and rkirkend
570         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
571         assertTrue("Approve should be requested.", document.isApprovalRequested());
572         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
573         assertTrue("Approve should be requested.", document.isApprovalRequested());
574         // since there are two requests, neither should be last approver
575         assertFalse("Should not be last approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("bmcgough"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
576         assertFalse("Should not be last approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("rkirkend"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
577         document.approve("");
578 
579         // request to rirkend has been satisfied, now request to bmcgough is only request remaining at level so he should be last approver
580         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
581         assertTrue("Approve should be requested.", document.isApprovalRequested());
582         assertTrue("Should be last approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("bmcgough"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
583         document.approve("");
584 
585     }
586 
587     /**
588      * This method tests how the isLastApproverAtNode method deals with force action requests, there is an app constant
589      * with the value specified in KewApiConstants.IS_LAST_APPROVER_ACTIVATE_FIRST which dictates whether or not to simulate
590      * activation of initialized requests before running the method.
591      *
592      * Tests the fix to issue http://fms.dfa.cornell.edu:8080/browse/KULWF-366
593      */
594     @Test public void testIsLastApproverActivation() throws Exception {
595         // first test without the parameter set
596         Parameter lastApproverActivateParameter = CoreFrameworkServiceLocator.getParameterService().getParameter(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.FEATURE_DETAIL_TYPE, KewApiConstants.IS_LAST_APPROVER_ACTIVATE_FIRST_IND);
597         assertNotNull("last approver parameter should exist.", lastApproverActivateParameter);
598         assertTrue("initial parameter value should be null or empty.", StringUtils.isBlank(lastApproverActivateParameter.getValue()));
599         String originalParameterValue = lastApproverActivateParameter.getValue();
600         
601         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.LAST_APPROVER_DOCUMENT_TYPE_NAME);
602         document.route("");
603 
604         // at the first node (WorkflowDocument) we should have a request to rkirkend, bmcgough and to ewestfal with forceAction=true,
605         assertEquals("We should be at the WorkflowDocument node.", SeqSetup.WORKFLOW_DOCUMENT_NODE, document.getNodeNames().iterator().next());
606         assertFalse("ewestfal should have not have approve because it's initiated", document.isApprovalRequested());
607         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
608         assertFalse("rkirkend should not have approve because it's initiated", document.isApprovalRequested());
609         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
610         assertTrue("bmcgough should have approve", document.isApprovalRequested());
611         List actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
612         assertEquals("Should be 3 pending requests.", 3, actionRequests.size());
613         // the requests to bmcgough should be activated, the request to rkirkend should be initialized,
614         // and the request to ewestfal should be initialized and forceAction=true
615         boolean foundBmcgoughRequest = false;
616         boolean foundRkirkendRequest = false;
617         boolean foundEwestfalRequest = false;
618         for (Iterator iterator = actionRequests.iterator(); iterator.hasNext();) {
619             ActionRequestValue actionRequest = (ActionRequestValue) iterator.next();
620             String netId = getPrincipalNameForId(actionRequest.getPrincipalId());
621             if ("bmcgough".equals(netId)) {
622                 assertTrue("Request to bmcgough should be activated.", actionRequest.isActive());
623                 foundBmcgoughRequest = true;
624             } else if ("rkirkend".equals(netId)) {
625                 assertTrue("Request to rkirkend should be initialized.", actionRequest.isInitialized());
626                 foundRkirkendRequest = true;
627             } else if ("ewestfal".equals(netId)) {
628                 assertTrue("Request to ewestfal should be initialized.", actionRequest.isInitialized());
629                 assertTrue("Request to ewestfal should be forceAction.", actionRequest.getForceAction().booleanValue());
630                 foundEwestfalRequest = true;
631             }
632         }
633         assertTrue("Did not find request to bmcgough.", foundBmcgoughRequest);
634         assertTrue("Did not find request to rkirkend.", foundRkirkendRequest);
635         assertTrue("Did not find request to ewestfal.", foundEwestfalRequest);
636 
637         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
638         // at this point, neither bmcgough, rkirkend nor ewestfal should be the last approver
639         assertFalse("Bmcgough should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("bmcgough"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
640         assertFalse("Rkirkend should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("rkirkend"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
641         assertFalse("Ewestfal should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
642 
643         // approve as bmcgough
644         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
645         document.approve("");
646 
647         // still, neither rkirkend nor ewestfal should be "final approver"
648         // at this point, neither bmcgough, rkirkend nor ewestfal should be the last approver
649         assertFalse("Rkirkend should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("rkirkend"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
650         assertFalse("Ewestfal should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
651 
652         // approve as rkirkend
653         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
654         document.approve("");
655 
656         // should be one pending activated to ewestfal now
657         actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
658         assertEquals("Should be 1 pending requests.", 1, actionRequests.size());
659         ActionRequestValue actionRequest = (ActionRequestValue)actionRequests.get(0);
660         assertTrue("Should be activated.", actionRequest.isActive());
661 
662         // ewestfal should now be the final approver
663         assertTrue("Ewestfal should be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
664 
665         // approve as ewestfal to send to next node
666         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
667         assertTrue("ewestfal should have approve request", document.isApprovalRequested());
668         document.approve("");
669 
670         // should be at the workflow document 2 node
671         assertEquals("Should be at the WorkflowDocument2 Node.", SeqSetup.WORKFLOW_DOCUMENT_2_NODE, document.getNodeNames().iterator().next());
672         // at this node there should be two requests, one to ewestfal with forceAction=false and one to pmckown,
673         // since we haven't set the application constant, the non-force action request won't be activated first so pmckown
674         // will not be the final approver
675         assertFalse("Pmckown should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("pmckown"), SeqSetup.WORKFLOW_DOCUMENT_2_NODE));
676         assertFalse("Ewestfal should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.WORKFLOW_DOCUMENT_2_NODE));
677         actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId());
678         assertEquals("Should be 2 action requests.", 2, actionRequests.size());
679 
680         // Now set up the app constant that checks force action properly and try a new document
681         String parameterValue = "Y";
682         Parameter.Builder b = Parameter.Builder.create(lastApproverActivateParameter);
683         b.setValue(parameterValue);
684         CoreFrameworkServiceLocator.getParameterService().updateParameter(b.build());
685 
686         lastApproverActivateParameter = CoreFrameworkServiceLocator.getParameterService().getParameter(KewApiConstants.KEW_NAMESPACE, KRADConstants.DetailTypes.FEATURE_DETAIL_TYPE, KewApiConstants.IS_LAST_APPROVER_ACTIVATE_FIRST_IND);
687         assertNotNull("Parameter should not be null.", lastApproverActivateParameter);
688         assertEquals("Parameter should be Y.", parameterValue, lastApproverActivateParameter.getValue());
689 
690 
691         document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.LAST_APPROVER_DOCUMENT_TYPE_NAME);
692         document.route("");
693         
694         // on this document type approval progression will go as follows:
695         // Workflow Document   (Sequential): bmcgough (1, fa=false),  rkirkend (2, fa=false), ewestfal (3, fa=true)
696         // Workflow Document 2 (Sequential): pmckown (1, fa=false), ewestfal (2, fa=false)
697 
698         // at this point, neither bmcgough, rkirkend nor ewestfal should be the last approver
699         assertFalse("Bmcgough should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("bmcgough"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
700         assertFalse("Rkirkend should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("rkirkend"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
701         assertFalse("Ewestfal should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
702 
703         // approve as bmcgough
704         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
705         document.approve("");
706 
707         // now there is just a request to rkirkend and ewestfal, since ewestfal is force action true, neither should be final approver
708         assertFalse("Rkirkend should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("rkirkend"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
709         assertFalse("Ewestfal should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
710 
711         // verify that ewestfal does not have permissions to approve the document yet since his request has not yet been activated
712         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
713         assertFalse("Ewestfal should not have permissions to approve", document.isApprovalRequested());
714         
715         // approve as rkirkend
716         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
717         document.approve("");
718 
719         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), document.getDocumentId());
720         assertTrue("Ewestfal should now have permission to approve", document.isApprovalRequested());
721         
722         // ewestfal should now be the final approver
723         assertTrue("Ewestfal should now be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.WORKFLOW_DOCUMENT_NODE));
724 
725         // approve as ewestfal to send it to the next node
726         document.approve("");
727 
728         TestUtilities.assertAtNode(document, SeqSetup.WORKFLOW_DOCUMENT_2_NODE);
729         List<ActionRequestValue> requests = KEWServiceLocator.getActionRequestService().findPendingRootRequestsByDocId(document.getDocumentId());
730         assertEquals("We should have 2 requests here.", 2, requests.size());
731         
732         // now, there are requests to pmckown and ewestfal here, the request to ewestfal is forceAction=false and since ewestfal
733         // routed the document, this request should be auto-approved.  However, it's priority is 2 so it is activated after the
734         // request to pmckown which is the situation we are testing
735         assertTrue("Pmckown should be the last approver at this node.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("pmckown"), SeqSetup.WORKFLOW_DOCUMENT_2_NODE));
736         assertFalse("Ewestfal should not be the final approver.", wdas.isLastApproverAtNode(document.getDocumentId(), getPrincipalIdForName("ewestfal"), SeqSetup.WORKFLOW_DOCUMENT_2_NODE));
737 
738         // if we approve as pmckown, the document should go into acknowledgement and become processed
739         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("pmckown"), document.getDocumentId());
740         document.approve("");
741         assertTrue("Document should be processed.", document.isProcessed());
742 
743         // set parameter value back to it's original value
744         Parameter.Builder b2 = Parameter.Builder.create(lastApproverActivateParameter);
745         b2.setValue("");
746         CoreFrameworkServiceLocator.getParameterService().updateParameter(b2.build());
747     }
748 
749     @Test public void testIsFinalApprover() throws Exception {
750         // for this document, pmckown should be the final approver
751         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.DOCUMENT_TYPE_NAME);
752         assertFinalApprover(document);
753     }
754 
755     @Test public void testIsFinalApproverChild() throws Exception {
756         // 12-13-2005: HR ran into a bug where this method was not correctly locating the final approver node when using a document type whic
757         // inherits the route from a parent, so we will incorporate this into the unit test to prevent regression
758         WorkflowDocument childDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"), SeqSetup.CHILD_DOCUMENT_TYPE_NAME);
759         assertFinalApprover(childDocument);
760     }
761 
762     /**
763      * Factored out so as not to duplicate a bunch of code between testIsFinalApprover and testIsFinalApproverChild.
764      */
765     private void assertFinalApprover(WorkflowDocument document) throws Exception {
766         document.route("");
767 
768         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), document.getDocumentId());
769         assertTrue("Document should be enroute.", document.isEnroute());
770         assertTrue("Should have approve request.", document.isApprovalRequested());
771 
772         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
773         // bmcgough is not the final approver
774         assertFalse("Should not be final approver.", wdas.isFinalApprover(document.getDocumentId(), getPrincipalIdForName("bmcgough")));
775         // approve as bmcgough
776         document.approve("");
777 
778         // should be to Ryan now, who is also not the final approver on the document
779         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
780         assertTrue("Document should be enroute.", document.isEnroute());
781         assertTrue("Should have approve request.", document.isApprovalRequested());
782         assertFalse("Should not be final approver.", wdas.isFinalApprover(document.getDocumentId(), getPrincipalIdForName("rkirkend")));
783         document.approve("");
784 
785         // should be to Phil now, who *IS* the final approver on the document
786         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("pmckown"), document.getDocumentId());
787         assertTrue("Document should be enroute.", document.isEnroute());
788         assertTrue("Should have approve request.", document.isApprovalRequested());
789         assertTrue("Should be final approver.", wdas.isFinalApprover(document.getDocumentId(), getPrincipalIdForName("pmckown")));
790 
791         // now adhoc an approve to temay, phil should no longer be the final approver
792         document.adHocToPrincipal(ActionRequestType.APPROVE, SeqSetup.WORKFLOW_DOCUMENT_2_NODE,
793                 "", getPrincipalIdForName("temay"), "", true);
794         assertFalse("Should not be final approver.", wdas.isFinalApprover(document.getDocumentId(), getPrincipalIdForName("pmckown")));
795         assertFalse("Should not be final approver.", wdas.isFinalApprover(document.getDocumentId(), getPrincipalIdForName("temay")));
796 
797         // now approve as temay and then adhoc an ack to jeremy
798         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("temay"), document.getDocumentId());
799         assertTrue("SHould have approve request.", document.isApprovalRequested());
800         document.approve("");
801 
802         // phil should be final approver again
803         assertTrue("Should be final approver.", wdas.isFinalApprover(document.getDocumentId(), getPrincipalIdForName("pmckown")));
804         document.adHocToPrincipal(ActionRequestType.ACKNOWLEDGE, SeqSetup.WORKFLOW_DOCUMENT_2_NODE,
805                 "", getPrincipalIdForName("jhopf"), "", true);
806         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
807         assertTrue("Should have acknowledge request.", document.isAcknowledgeRequested());
808 
809         // now there should be an approve to phil and an ack to jeremy, so phil should be the final approver and jeremy should not
810         assertTrue("Should be final approver.", wdas.isFinalApprover(document.getDocumentId(), getPrincipalIdForName("pmckown")));
811         assertFalse("Should not be final approver.", wdas.isFinalApprover(document.getDocumentId(), getPrincipalIdForName("jhopf")));
812 
813         // after approving as phil, the document should go processed
814         document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("pmckown"), document.getDocumentId());
815         document.approve("");
816         assertTrue("Document should be processed.", document.isProcessed());
817     }
818     
819     @Test public void testGetPrincipalIdsInRouteLog() throws Exception {
820     	Set<String> NonSITMembers = new HashSet<String>(
821     			Arrays.asList(
822 						new String[] {
823 								getPrincipalIdForName("user1"), 
824 								getPrincipalIdForName("user2"), 
825 								getPrincipalIdForName("user3"), 
826 								getPrincipalIdForName("dewey")}
827 				)
828     	);
829     	
830     	Set<String> WorkflowAdminMembers = new HashSet<String>(
831     			Arrays.asList(
832     					new String[] {
833     							getPrincipalIdForName("ewestfal"), 
834     							getPrincipalIdForName("rkirkend"), 
835     							getPrincipalIdForName("jhopf"), 
836     							getPrincipalIdForName("bmcgough"), 
837     							getPrincipalIdForName("shenl"), 
838     							getPrincipalIdForName("quickstart")
839     					}
840     			)
841     	);
842     	
843     	WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), RouteLogTestSetup.DOCUMENT_TYPE_NAME);
844 		document.route("");
845 
846         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
847 		// just look at the current node
848 		List<String> principalIds = wdas.getPrincipalIdsInRouteLog(document.getDocumentId(), false);
849 		// should contain ewestfal and NonSIT group members
850 		assertTrue(principalIds.contains(getPrincipalIdForName("ewestfal")));
851 		assertTrue(principalIds.containsAll(NonSITMembers));
852 		
853 		// should NOT contain jitrue and WorkflowAdmin group members as they are in the rule for the future node
854 		assertFalse(principalIds.contains(getPrincipalIdForName("jitrue")));
855 		assertFalse(principalIds.containsAll(WorkflowAdminMembers));
856 		
857 		// this time look at future nodes too
858 		principalIds = 	wdas.getPrincipalIdsInRouteLog(document.getDocumentId(), true);
859 		
860 		// should contain ewestfal and NonSIT group members
861 		assertTrue(principalIds.contains(getPrincipalIdForName("ewestfal")));
862 		assertTrue(principalIds.containsAll(NonSITMembers));
863 
864 		// should also contain jitrue and WorkflowAdmin group members
865 		assertTrue(principalIds.contains(getPrincipalIdForName("jitrue")));
866 		assertTrue(principalIds.containsAll(WorkflowAdminMembers));
867     }
868 
869     @Test public void testRoutingReportOnDocumentType() throws Exception {
870         RoutingReportCriteria.Builder criteria = RoutingReportCriteria.Builder.createByDocumentTypeName("SeqDocType");
871     	criteria.setRuleTemplateNames(Collections.singletonList("WorkflowDocumentTemplate"));
872         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
873     	DocumentDetail documentDetail = wdas.executeSimulation(criteria.build());
874     	assertNotNull(documentDetail);
875     	assertEquals("Should have been 2 requests generated.", 2, documentDetail.getActionRequests().size());
876 
877     	// let's try doing both WorkflowDocumentTemplate and WorkflowDocumentTemplate2 together
878     	criteria.setRuleTemplateNames(Arrays.asList(new String[] {"WorkflowDocumentTemplate", "WorkflowDocument2Template"}));
879     	documentDetail = wdas.executeSimulation(criteria.build());
880     	assertEquals("Should have been 3 requests generated.", 3, documentDetail.getActionRequests().size());
881 
882     	boolean foundRkirkend = false;
883     	boolean foundBmcgough = false;
884     	boolean foundPmckown = false;
885     	for (ActionRequest actionRequest : documentDetail.getActionRequests()) {
886 			String netId = getPrincipalNameForId(actionRequest.getPrincipalId());
887 			if (netId.equals("rkirkend")) {
888 				foundRkirkend = true;
889 				assertEquals(SeqSetup.WORKFLOW_DOCUMENT_NODE, actionRequest.getNodeName());
890 			} else if (netId.equals("bmcgough")) {
891 				foundBmcgough = true;
892 				assertEquals(SeqSetup.WORKFLOW_DOCUMENT_NODE, actionRequest.getNodeName());
893 			} else if (netId.equals("pmckown")) {
894 				foundPmckown = true;
895 				assertEquals(SeqSetup.WORKFLOW_DOCUMENT_2_NODE, actionRequest.getNodeName());
896 			}
897 		}
898     	assertTrue("Did not find request for rkirkend", foundRkirkend);
899     	assertTrue("Did not find request for bmcgough", foundBmcgough);
900     	assertTrue("Did not find request for pmckown", foundPmckown);
901 
902     }
903 
904     @Test public void testRoutingReportOnDocumentId() throws Exception {
905         WorkflowDocument doc = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), "SeqDocType");
906 
907         WorkflowDocumentActionsService wdas = KewApiServiceLocator.getWorkflowDocumentActionsService();
908         RoutingReportCriteria.Builder criteria = RoutingReportCriteria.Builder.createByDocumentId(doc.getDocumentId());
909         criteria.setRuleTemplateNames(Collections.singletonList("WorkflowDocumentTemplate"));
910         DocumentDetail documentDetail = wdas.executeSimulation(criteria.build());
911         assertNotNull(documentDetail);
912         assertEquals("Document id returned should be the same as the one passed in", doc.getDocumentId(),
913                 documentDetail.getDocument().getDocumentId());
914         assertEquals("Wrong number of action requests generated", 2, documentDetail.getActionRequests().size());
915 
916         // let's try doing both WorkflowDocumentTemplate and WorkflowDocumentTemplate2 together
917         criteria.setRuleTemplateNames(Arrays.asList(new String[] { "WorkflowDocumentTemplate", "WorkflowDocument2Template" }));
918         documentDetail = wdas.executeSimulation(criteria.build());
919         assertEquals("Should have been 3 requests generated.", 3, documentDetail.getActionRequests().size());
920 
921         boolean foundRkirkend = false;
922         boolean foundBmcgough = false;
923         boolean foundPmckown = false;
924         for (ActionRequest actionRequest : documentDetail.getActionRequests()) {
925             String netId = getPrincipalNameForId(actionRequest.getPrincipalId());
926             if (netId.equals("rkirkend")) {
927                 foundRkirkend = true;
928                 assertEquals(SeqSetup.WORKFLOW_DOCUMENT_NODE, actionRequest.getNodeName());
929             } else if (netId.equals("bmcgough")) {
930                 foundBmcgough = true;
931                 assertEquals(SeqSetup.WORKFLOW_DOCUMENT_NODE, actionRequest.getNodeName());
932             } else if (netId.equals("pmckown")) {
933                 foundPmckown = true;
934                 assertEquals(SeqSetup.WORKFLOW_DOCUMENT_2_NODE, actionRequest.getNodeName());
935             }
936         }
937         assertTrue("Did not find request for rkirkend", foundRkirkend);
938         assertTrue("Did not find request for bmcgough", foundBmcgough);
939         assertTrue("Did not find request for pmckown", foundPmckown);
940 
941     }
942     
943     protected void verifyEmptyArray(String qualifier, Object[] array) {
944     	assertNotNull("Array should not be empty", array);
945         assertEquals("Number of " + qualifier + "s Returned Should be 0",0,array.length);
946     }
947 
948     private void verifyEmptyCollection(String qualifier, Collection collection) {
949     	assertNotNull("Array should not be empty", collection);
950         assertEquals("Number of " + qualifier + "s Returned Should be 0",0,collection.size());
951     }
952 
953     @Test public void testRuleReportGeneralFunction() throws Exception {
954         this.ruleExceptionTest(null, "Sending in null RuleReportCriteriaDTO should throw Exception");
955 
956         RuleReportCriteria.Builder ruleReportCriteria = RuleReportCriteria.Builder.create();
957         this.ruleExceptionTest(ruleReportCriteria.build(), "Sending in empty RuleReportCriteriaDTO should throw Exception");
958 
959         ruleReportCriteria.setResponsiblePrincipalId("hobo_man");
960         this.ruleExceptionTest(ruleReportCriteria.build(), "Sending in an invalid principle ID should throw Exception");
961 
962         ruleReportCriteria = RuleReportCriteria.Builder.create();
963         ruleReportCriteria.setResponsibleGroupId("-1234567");
964         this.ruleExceptionTest(ruleReportCriteria.build(), "Sending in an invalid Workgroup ID should throw Exception");
965 
966         ruleReportCriteria = RuleReportCriteria.Builder.create();
967         ruleReportCriteria.setRuleExtensions(Collections.singletonMap("key", "value"));
968         this.ruleExceptionTest(ruleReportCriteria.build(), "Sending in one or more RuleExtentionVO objects with no Rule Template Name should throw Exception");
969 
970 
971         RuleService wdas = KewApiServiceLocator.getRuleService();
972         List<Rule> rules = null;
973         ruleReportCriteria = RuleReportCriteria.Builder.create();
974         ruleReportCriteria.setConsiderGroupMembership(Boolean.FALSE.booleanValue());
975         ruleReportCriteria.setDocumentTypeName(RuleTestGeneralSetup.DOCUMENT_TYPE_NAME);
976         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
977         rules = wdas.ruleReport(ruleReportCriteria.build());
978         assertEquals("Number of Rules Returned Should be 3",3,rules.size());
979 
980         rules = null;
981         ruleReportCriteria = RuleReportCriteria.Builder.create();
982         ruleReportCriteria.setActionRequestCodes(Collections.singletonList(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
983         ruleReportCriteria.setConsiderGroupMembership(Boolean.FALSE.booleanValue());
984         ruleReportCriteria.setDocumentTypeName(RuleTestGeneralSetup.DOCUMENT_TYPE_NAME);
985         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
986         ruleReportCriteria.setResponsiblePrincipalId(getPrincipalIdForName("temay"));
987         rules = wdas.ruleReport(ruleReportCriteria.build());
988         verifyEmptyCollection("Rule", rules);
989 
990         rules = null;
991         ruleReportCriteria = RuleReportCriteria.Builder.create();
992         ruleReportCriteria.setActionRequestCodes(Collections.singletonList(KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ));
993         ruleReportCriteria.setConsiderGroupMembership(Boolean.FALSE.booleanValue());
994         ruleReportCriteria.setDocumentTypeName(RuleTestGeneralSetup.DOCUMENT_TYPE_NAME);
995         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
996         rules = wdas.ruleReport(ruleReportCriteria.build());
997         assertEquals("Number of Rules Returned Should be 1",1,rules.size());
998         // check the rule returned
999 
1000         Rule ruleVO = rules.get(0);
1001         assertEquals("Rule Document Type is not " + RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,ruleVO.getDocTypeName());
1002         assertEquals("Rule Template Named returned is not " + RuleTestGeneralSetup.RULE_TEST_TEMPLATE_2,RuleTestGeneralSetup.RULE_TEST_TEMPLATE_2,ruleVO.getRuleTemplateName());
1003         assertEquals("Rule did not have force action set to false",Boolean.FALSE,ruleVO.isForceAction());
1004         assertEquals("Number of Rule Responsibilities returned is incorrect",2,ruleVO.getRuleResponsibilities().size());
1005 
1006         for (RuleResponsibility responsibility : ruleVO.getRuleResponsibilities()) {
1007             String responsibilityPrincipalName = getPrincipalNameForId(responsibility.getPrincipalId());
1008             if ("temay".equals(responsibilityPrincipalName)) {
1009                 assertEquals("Rule user is not correct","temay",responsibilityPrincipalName);
1010                 assertEquals("Rule priority is incorrect",Integer.valueOf(1),responsibility.getPriority());
1011                 assertEquals("Rule should be Ack Request",KewApiConstants.ACTION_REQUEST_APPROVE_REQ,responsibility.getActionRequestedCd());
1012             } else if ("ewestfal".equals(responsibilityPrincipalName)) {
1013                 assertEquals("Rule user is not correct","ewestfal",responsibilityPrincipalName);
1014                 assertEquals("Rule priority is incorrect",Integer.valueOf(2),responsibility.getPriority());
1015                 assertEquals("Rule should be Ack Request",KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ,responsibility.getActionRequestedCd());
1016             } else {
1017                 fail("Network ID of user for this responsibility is neither temay or ewestfal");
1018             }
1019         }
1020 
1021         rules = null;
1022         ruleVO = null;
1023         RuleResponsibility responsibilityVO = null;
1024         ruleReportCriteria = RuleReportCriteria.Builder.create();
1025         ruleReportCriteria.setConsiderGroupMembership(Boolean.FALSE.booleanValue());
1026         ruleReportCriteria.setDocumentTypeName(RuleTestGeneralSetup.DOCUMENT_TYPE_NAME);
1027         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
1028         ruleReportCriteria.setResponsiblePrincipalId(getPrincipalIdForName("temay"));
1029         rules = wdas.ruleReport(ruleReportCriteria.build());
1030         assertEquals("Number of Rules returned is not correct",2,rules.size());
1031         for (Rule rule : rules) {
1032             if (RuleTestGeneralSetup.RULE_TEST_TEMPLATE_1.equals(rule.getRuleTemplateName())) {
1033                 assertEquals("Rule Document Type is not " + RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,rule.getDocTypeName());
1034                 assertEquals("Rule Template Named returned is not " + RuleTestGeneralSetup.RULE_TEST_TEMPLATE_1,RuleTestGeneralSetup.RULE_TEST_TEMPLATE_1,rule.getRuleTemplateName());
1035                 assertEquals("Rule did not have force action set to true",Boolean.TRUE,rule.isForceAction());
1036                 assertEquals("Number of Rule Responsibilities Returned Should be 1",1,rule.getRuleResponsibilities().size());
1037                 responsibilityVO = rule.getRuleResponsibilities().get(0);
1038                 assertEquals("Rule user is incorrect","temay",getPrincipalNameForId(responsibilityVO.getPrincipalId()));
1039                 assertEquals("Rule priority is incorrect",Integer.valueOf(3),responsibilityVO.getPriority());
1040                 assertEquals("Rule action request is incorrect",KewApiConstants.ACTION_REQUEST_APPROVE_REQ,responsibilityVO.getActionRequestedCd());
1041             } else if (RuleTestGeneralSetup.RULE_TEST_TEMPLATE_2.equals(rule.getRuleTemplateName())) {
1042                 assertEquals("Rule Document Type is not " + RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,rule.getDocTypeName());
1043                 assertEquals("Rule Template Named returned is not " + RuleTestGeneralSetup.RULE_TEST_TEMPLATE_2,RuleTestGeneralSetup.RULE_TEST_TEMPLATE_2,rule.getRuleTemplateName());
1044                 assertEquals("Rule did not have force action set to false",Boolean.FALSE,rule.isForceAction());
1045                 assertEquals("Number of Rule Responsibilities returned is incorrect",2,rule.getRuleResponsibilities().size());
1046                 for (RuleResponsibility responsibility : rule.getRuleResponsibilities()) {
1047 
1048                     String responsibilityPrincipalName = getPrincipalNameForId(responsibility.getPrincipalId());
1049                     if ("temay".equals(responsibilityPrincipalName)) {
1050                         assertEquals("Rule user is not correct","temay",responsibilityPrincipalName);
1051                         assertEquals("Rule priority is incorrect",Integer.valueOf(1),responsibility.getPriority());
1052                         assertEquals("Rule should be Ack Request",KewApiConstants.ACTION_REQUEST_APPROVE_REQ,responsibility.getActionRequestedCd());
1053                     } else if ("ewestfal".equals(responsibilityPrincipalName)) {
1054                         assertEquals("Rule user is not correct","ewestfal",responsibilityPrincipalName);
1055                         assertEquals("Rule priority is incorrect",Integer.valueOf(2),responsibility.getPriority());
1056                         assertEquals("Rule should be Ack Request",KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ,responsibility.getActionRequestedCd());
1057                     } else {
1058                         fail("Network ID of user for this responsibility is neither temay or ewestfal");
1059                     }
1060                 }
1061             } else {
1062                 fail("Rule Template of returned rule is not of type " + RuleTestGeneralSetup.RULE_TEST_TEMPLATE_1 + " nor " + RuleTestGeneralSetup.RULE_TEST_TEMPLATE_2);
1063             }
1064         }
1065 
1066         rules = null;
1067         ruleVO = null;
1068         responsibilityVO = null;
1069         ruleReportCriteria = RuleReportCriteria.Builder.create();
1070         ruleReportCriteria.setDocumentTypeName(RuleTestGeneralSetup.DOCUMENT_TYPE_NAME);
1071         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
1072         ruleReportCriteria.setResponsibleGroupId(RuleTestGeneralSetup.RULE_TEST_GROUP_ID);
1073         rules = wdas.ruleReport(ruleReportCriteria.build());
1074         assertEquals("Number of Rules Returned Should be 1",1,rules.size());
1075         ruleVO = rules.get(0);
1076         assertEquals("Rule Document Type is not " + RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,ruleVO.getDocTypeName());
1077         assertEquals("Rule Template Named returned is not " + RuleTestGeneralSetup.RULE_TEST_TEMPLATE_3,RuleTestGeneralSetup.RULE_TEST_TEMPLATE_3,ruleVO.getRuleTemplateName());
1078         assertEquals("Rule did not have force action set to true",Boolean.TRUE,ruleVO.isForceAction());
1079         assertEquals("Number of Rule Responsibilities Returned Should be 1",1,ruleVO.getRuleResponsibilities().size());
1080         responsibilityVO = ruleVO.getRuleResponsibilities().get(0);
1081         Group ruleTestGroup = KimApiServiceLocator.getGroupService().getGroup(responsibilityVO.getGroupId());
1082         assertEquals("Rule workgroup id is incorrect",RuleTestGeneralSetup.RULE_TEST_GROUP_ID, ruleTestGroup.getId());
1083         assertEquals("Rule priority is incorrect",Integer.valueOf(1),responsibilityVO.getPriority());
1084         assertEquals("Rule action request is incorrect",KewApiConstants.ACTION_REQUEST_FYI_REQ,responsibilityVO.getActionRequestedCd());
1085 
1086         rules = null;
1087         ruleVO = null;
1088         responsibilityVO = null;
1089         ruleReportCriteria = RuleReportCriteria.Builder.create();
1090         ruleReportCriteria.setDocumentTypeName(RuleTestGeneralSetup.DOCUMENT_TYPE_NAME);
1091         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
1092         ruleReportCriteria.setResponsiblePrincipalId(getPrincipalIdForName("user1"));
1093         rules = wdas.ruleReport(ruleReportCriteria.build());
1094         assertEquals("Number of Rules Returned Should be 1",1,rules.size());
1095         ruleVO = rules.get(0);
1096         assertEquals("Rule Document Type is not " + RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,RuleTestGeneralSetup.DOCUMENT_TYPE_NAME,ruleVO.getDocTypeName());
1097         assertNotSame("Rule Template Named returned is not " + RuleTestGeneralSetup.RULE_TEST_TEMPLATE_3,
1098                 RuleTestGeneralSetup.RULE_TEST_TEMPLATE_3, ruleVO.getRuleTemplateName());
1099         assertEquals("Rule did not have force action set to true",Boolean.TRUE,ruleVO.isForceAction());
1100         assertEquals("Number of Rule Responsibilities Returned Should be 1",1,ruleVO.getRuleResponsibilities().size());
1101         responsibilityVO = ruleVO.getRuleResponsibilities().get(0);
1102         assertEquals("Rule workgroup id is incorrect",RuleTestGeneralSetup.RULE_TEST_GROUP_ID, ruleTestGroup.getId());
1103         assertEquals("Rule priority is incorrect",Integer.valueOf(1),responsibilityVO.getPriority());
1104         assertEquals("Rule action request is incorrect",KewApiConstants.ACTION_REQUEST_FYI_REQ,responsibilityVO.getActionRequestedCd());
1105     }
1106 
1107     /**
1108      * Tests specific rule scenario relating to standard org review routing
1109      *
1110      * @throws Exception
1111      */
1112     @Test public void testRuleReportOrgReviewTest() throws Exception {
1113         loadXmlFile("WorkflowUtilityRuleReportConfig.xml");
1114 
1115         RuleService wdas = KewApiServiceLocator.getRuleService();
1116 
1117         RuleReportCriteria.Builder ruleReportCriteria = RuleReportCriteria.Builder.create();
1118         ruleReportCriteria.setDocumentTypeName(RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME);
1119         ruleReportCriteria.setRuleTemplateName(RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE);
1120         ruleReportCriteria.setResponsiblePrincipalId(getPrincipalIdForName("user1"));
1121         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
1122         List<Rule> rules = wdas.ruleReport(ruleReportCriteria.build());
1123         assertEquals("Number of rules returned is incorrect",2,rules.size());
1124 
1125         ruleReportCriteria = null;
1126         rules = null;
1127         ruleReportCriteria = RuleReportCriteria.Builder.create();
1128         ruleReportCriteria.setDocumentTypeName(RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME);
1129         ruleReportCriteria.setRuleTemplateName(RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE);
1130         ruleReportCriteria.setResponsiblePrincipalId(getPrincipalIdForName("user1"));
1131         ruleReportCriteria.setConsiderGroupMembership(Boolean.FALSE.booleanValue());
1132         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
1133         rules = wdas.ruleReport(ruleReportCriteria.build());
1134         assertEquals("Number of rules returned is incorrect",1,rules.size());
1135 
1136         ruleReportCriteria = null;
1137         rules = null;
1138         ruleReportCriteria = RuleReportCriteria.Builder.create();
1139         ruleReportCriteria.setDocumentTypeName(RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME);
1140         ruleReportCriteria.setRuleTemplateName(RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE);
1141         Map<String, String> ruleExtensions = new HashMap<String, String>();
1142         ruleExtensions.put(RuleTestOrgReviewSetup.RULE_TEST_CHART_CODE_NAME, "BA");
1143         ruleExtensions.put(RuleTestOrgReviewSetup.RULE_TEST_ORG_CODE_NAME,"FMOP");
1144         ruleReportCriteria.setRuleExtensions(ruleExtensions);
1145         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
1146         rules = wdas.ruleReport(ruleReportCriteria.build());
1147         assertEquals("Number of rules returned is incorrect",2,rules.size());
1148 
1149         ruleReportCriteria = null;
1150         rules = null;
1151         ruleExtensions = new HashMap<String, String>();
1152         ruleReportCriteria = RuleReportCriteria.Builder.create();
1153         ruleReportCriteria.setDocumentTypeName(RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME);
1154         ruleReportCriteria.setRuleTemplateName(RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE);
1155         ruleReportCriteria.setResponsiblePrincipalId(getPrincipalIdForName("ewestfal"));
1156         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE.booleanValue());
1157         rules = wdas.ruleReport(ruleReportCriteria.build());
1158         assertEquals("Number of rules returned is incorrect",1,rules.size());
1159         Rule ruleVO = rules.get(0);
1160         assertEquals("Rule Document Type is not " + RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME,RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME,ruleVO.getDocTypeName());
1161         assertEquals("Rule Template Named returned is not " + RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE,RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE,ruleVO.getRuleTemplateName());
1162         assertEquals("Rule did not have force action set to true",Boolean.TRUE,ruleVO.isForceAction());
1163         assertEquals("Number of Rule Responsibilities Returned Should be 1",1,ruleVO.getRuleResponsibilities().size());
1164         RuleResponsibility responsibilityVO = ruleVO.getRuleResponsibilities().get(0);
1165         Group ruleTestGroup2 = KimApiServiceLocator.getGroupService().getGroup(responsibilityVO.getGroupId());
1166         assertEquals("Rule workgroup name is incorrect",RuleTestOrgReviewSetup.RULE_TEST_WORKGROUP2,ruleTestGroup2.getName());
1167         assertEquals("Rule priority is incorrect",Integer.valueOf(4),responsibilityVO.getPriority());
1168         assertEquals("Rule action request is incorrect",KewApiConstants.ACTION_REQUEST_FYI_REQ,responsibilityVO.getActionRequestedCd());
1169         ruleExtensions = ruleVO.getRuleExtensionMap();
1170         assertEquals("Number of Rule Extensions Returned Should be 2",2,ruleExtensions.size());
1171         for (Map.Entry<String, String> entry : ruleExtensions.entrySet()) {
1172             // if rule key is chartCode.... should equal UA
1173             // else if rule key is orgCode.... should equal VPIT
1174             // otherwise error
1175             if (RuleTestOrgReviewSetup.RULE_TEST_CHART_CODE_NAME.equals(entry.getKey())) {
1176                 assertEquals("Rule Extension for key '" + RuleTestOrgReviewSetup.RULE_TEST_CHART_CODE_NAME + "' is incorrect","UA",entry.getValue());
1177             } else if (RuleTestOrgReviewSetup.RULE_TEST_ORG_CODE_NAME.equals(entry.getKey())) {
1178                 assertEquals("Rule Extension for key '" + RuleTestOrgReviewSetup.RULE_TEST_ORG_CODE_NAME + "' is incorrect","VPIT",entry.getValue());
1179             } else {
1180                 fail("Rule Extension has attribute key that is neither '" + RuleTestOrgReviewSetup.RULE_TEST_CHART_CODE_NAME +
1181                         "' nor '" + RuleTestOrgReviewSetup.RULE_TEST_ORG_CODE_NAME + "'");
1182             }
1183         }
1184 
1185         ruleReportCriteria = null;
1186         rules = null;
1187         ruleVO = null;
1188         responsibilityVO = null;
1189         ruleReportCriteria = RuleReportCriteria.Builder.create();
1190         ruleReportCriteria.setDocumentTypeName(RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME);
1191         ruleReportCriteria.setRuleTemplateName(RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE);
1192         ruleReportCriteria.setResponsiblePrincipalId(getPrincipalIdForName("user1"));
1193         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE);
1194         rules = wdas.ruleReport(ruleReportCriteria.build());
1195         assertEquals("Number of rules returned is incorrect",2,rules.size());
1196 
1197         ruleReportCriteria = null;
1198         rules = null;
1199         ruleVO = null;
1200         responsibilityVO = null;
1201         ruleExtensions = new HashMap<String, String>();
1202         ruleReportCriteria = RuleReportCriteria.Builder.create();
1203         ruleReportCriteria.setDocumentTypeName(RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME);
1204         ruleReportCriteria.setRuleTemplateName(RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE);
1205         ruleExtensions.put(RuleTestOrgReviewSetup.RULE_TEST_CHART_CODE_NAME, "UA");
1206         ruleExtensions.put(RuleTestOrgReviewSetup.RULE_TEST_ORG_CODE_NAME, "FMOP");
1207         ruleReportCriteria.setRuleExtensions(ruleExtensions);
1208         ruleReportCriteria.setIncludeDelegations(Boolean.FALSE);
1209         rules = wdas.ruleReport(ruleReportCriteria.build());
1210         assertEquals("Number of rules returned is incorrect",1,rules.size());
1211         ruleVO = rules.get(0);
1212         assertEquals("Rule Document Type is not " + RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME,RuleTestOrgReviewSetup.DOCUMENT_TYPE_NAME,ruleVO.getDocTypeName());
1213         assertEquals("Rule Template Named returned is not " + RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE,RuleTestOrgReviewSetup.RULE_TEST_TEMPLATE,ruleVO.getRuleTemplateName());
1214         assertEquals("Rule did not have force action set to true",Boolean.TRUE,ruleVO.isForceAction());
1215         assertEquals("Number of Rule Responsibilities Returned Should be 1",1,ruleVO.getRuleResponsibilities().size());
1216         responsibilityVO = ruleVO.getRuleResponsibilities().get(0);
1217         ruleTestGroup2 = KimApiServiceLocator.getGroupService().getGroup(responsibilityVO.getGroupId());
1218         assertEquals("Rule workgroup name is incorrect",RuleTestOrgReviewSetup.RULE_TEST_WORKGROUP, ruleTestGroup2.getName());
1219         assertEquals("Rule priority is incorrect",Integer.valueOf(1),responsibilityVO.getPriority());
1220         assertEquals("Rule action request is incorrect",KewApiConstants.ACTION_REQUEST_APPROVE_REQ,responsibilityVO.getActionRequestedCd());
1221     }
1222 
1223     @Test public void testGetUserActionItemCount() throws Exception {
1224         String principalId = getPrincipalIdForName("ewestfal");
1225         WorkflowDocument document = WorkflowDocumentFactory.createDocument(principalId, SeqSetup.DOCUMENT_TYPE_NAME);
1226         document.route("");
1227         assertTrue(document.isEnroute());
1228 
1229         ActionListService als = KewApiServiceLocator.getActionListService();
1230         assertEquals("Count is incorrect for user " + principalId, Integer.valueOf(0), als.getUserActionItemCount(principalId));
1231         principalId = getPrincipalIdForName("bmcgough");
1232         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1233         assertTrue(document.isApprovalRequested());
1234         assertEquals("Count is incorrect for user " + principalId, Integer.valueOf(1), als.getUserActionItemCount(
1235                 principalId));
1236         principalId = getPrincipalIdForName("rkirkend");
1237         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1238         assertTrue(document.isApprovalRequested());
1239         assertEquals("Count is incorrect for user " + principalId, Integer.valueOf(1), als.getUserActionItemCount(
1240                 principalId));
1241 
1242         TestUtilities.assertAtNode(document, "WorkflowDocument");
1243         document.returnToPreviousNode("", "AdHoc");
1244         TestUtilities.assertAtNode(document, "AdHoc");
1245         // verify count after return to previous
1246         principalId = getPrincipalIdForName("ewestfal");
1247         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1248         assertTrue(document.isApprovalRequested());
1249         // expect one action item for approval request
1250         assertEquals("Count is incorrect for user " + principalId, Integer.valueOf(1), als.getUserActionItemCount(
1251                 principalId));
1252         principalId = getPrincipalIdForName("bmcgough");
1253         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1254         assertFalse(document.isApprovalRequested());
1255         assertTrue(document.isFYIRequested());
1256         // expect one action item for fyi action request
1257         assertEquals("Count is incorrect for user " + principalId, Integer.valueOf(1), als.getUserActionItemCount(
1258                 principalId));
1259         principalId = getPrincipalIdForName("rkirkend");
1260         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1261         assertFalse(document.isApprovalRequested());
1262         // expect no action items
1263         assertEquals("Count is incorrect for user " + principalId, Integer.valueOf(0), als.getUserActionItemCount(
1264                 principalId));
1265 
1266         principalId = getPrincipalIdForName("ewestfal");
1267         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1268         document.approve("");
1269         TestUtilities.assertAtNode(document, "WorkflowDocument");
1270 
1271         // we should be back where we were
1272         principalId = getPrincipalIdForName("ewestfal");
1273         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1274         assertFalse(document.isApprovalRequested());
1275         assertEquals("Count is incorrect for user " + principalId, Integer.valueOf(0), als.getUserActionItemCount(
1276                 principalId));
1277         principalId = getPrincipalIdForName("bmcgough");
1278         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1279         assertTrue(document.isApprovalRequested());
1280         assertEquals("Count is incorrect for user " + principalId, Integer.valueOf(1), als.getUserActionItemCount(
1281                 principalId));
1282         principalId = getPrincipalIdForName("rkirkend");
1283         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1284         assertTrue(document.isApprovalRequested());
1285         assertEquals("Count is incorrect for user " + principalId, Integer.valueOf(1), als.getUserActionItemCount(
1286                 principalId));
1287     }
1288 
1289     @Test public void testGetActionItems() throws Exception {
1290         String initiatorNetworkId = "ewestfal";
1291         String user1NetworkId = "bmcgough";
1292         String user2NetworkId ="rkirkend";
1293         String initiatorPrincipalId = getPrincipalIdForName(initiatorNetworkId);
1294         String user1PrincipalId = getPrincipalIdForName(user1NetworkId);
1295         String user2PrincipalId = getPrincipalIdForName(user2NetworkId);
1296         String principalId = getPrincipalIdForName(initiatorNetworkId);
1297         String docTitle = "this is the doc title";
1298         WorkflowDocument document = WorkflowDocumentFactory.createDocument(principalId, SeqSetup.DOCUMENT_TYPE_NAME);
1299         document.setTitle(docTitle);
1300         document.route("");
1301         assertTrue(document.isEnroute());
1302 
1303         ActionListService als = KewApiServiceLocator.getActionListService();
1304         List<ActionItem> actionItems = als.getAllActionItems(document.getDocumentId());
1305         assertEquals("Incorrect number of action items returned",2,actionItems.size());
1306         for (ActionItem actionItem : actionItems) {
1307             assertEquals("Action Item should be Approve request", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, actionItem.getActionRequestCd());
1308             assertEquals("Action Item has incorrect doc title", docTitle, actionItem.getDocTitle());
1309             assertTrue("User should be one of '" + user1NetworkId + "' or '" + user2NetworkId + "'", user1PrincipalId.equals(actionItem.getPrincipalId()) || user2PrincipalId.equals(actionItem.getPrincipalId()));
1310         }
1311 
1312         principalId = getPrincipalIdForName(user2NetworkId);
1313         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1314         assertTrue(document.isApprovalRequested());
1315         TestUtilities.assertAtNode(document, "WorkflowDocument");
1316         document.returnToPreviousNode("", "AdHoc");
1317         TestUtilities.assertAtNode(document, "AdHoc");
1318         // verify count after return to previous
1319         actionItems = als.getAllActionItems(document.getDocumentId());
1320         assertEquals("Incorrect number of action items returned",2,actionItems.size());
1321         for (ActionItem actionItem : actionItems) {
1322             assertEquals("Action Item has incorrect doc title", docTitle, actionItem.getDocTitle());
1323             assertTrue("Action Items should be Approve or FYI requests only", KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(actionItem.getActionRequestCd()) || KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(actionItem.getActionRequestCd()));
1324             if (KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(actionItem.getActionRequestCd())) {
1325                 assertTrue("User should be '" + initiatorNetworkId + "'", initiatorPrincipalId.equals(actionItem.getPrincipalId()));
1326             } else if (KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(actionItem.getActionRequestCd())) {
1327                 assertTrue("User should be  '" + user1NetworkId + "'", user1PrincipalId.equals(actionItem.getPrincipalId()));
1328             }
1329         }
1330 
1331         principalId = getPrincipalIdForName(initiatorNetworkId);
1332         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1333         assertTrue(document.isApprovalRequested());
1334         document.approve("");
1335         TestUtilities.assertAtNode(document, "WorkflowDocument");
1336 
1337         // we should be back where we were
1338         actionItems = als.getAllActionItems(document.getDocumentId());
1339         assertEquals("Incorrect number of action items returned",2,actionItems.size());
1340         for (ActionItem actionItem : actionItems) {
1341             assertEquals("Action Item should be Approve request", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, actionItem.getActionRequestCd());
1342             assertEquals("Action Item has incorrect doc title", docTitle, actionItem.getDocTitle());
1343             assertTrue("User should be one of '" + user1NetworkId + "' or '" + user2NetworkId + "'", user1PrincipalId.equals(actionItem.getPrincipalId()) || user2PrincipalId.equals(actionItem.getPrincipalId()));
1344         }
1345     }
1346 
1347     @Test public void testGetActionItems_ActionRequestCodes() throws Exception {
1348         String initiatorNetworkId = "ewestfal";
1349         String user1NetworkId = "bmcgough";
1350         String user2NetworkId ="rkirkend";
1351         String initiatorPrincipalId = getPrincipalIdForName(initiatorNetworkId);
1352         String user1PrincipalId = getPrincipalIdForName(user1NetworkId);
1353         String user2PrincipalId = getPrincipalIdForName(user2NetworkId);
1354         String principalId = getPrincipalIdForName(initiatorNetworkId);
1355         String docTitle = "this is the doc title";
1356         WorkflowDocument document = WorkflowDocumentFactory.createDocument(principalId, SeqSetup.DOCUMENT_TYPE_NAME);
1357         document.setTitle(docTitle);
1358         document.route("");
1359         assertTrue(document.isEnroute());
1360 
1361         ActionListService als = KewApiServiceLocator.getActionListService();
1362         List<ActionItem> actionItems = als.getActionItems(document.getDocumentId(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}));
1363         verifyEmptyCollection("Action Item", actionItems);
1364         actionItems = als.getActionItems(document.getDocumentId(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ}));
1365         assertEquals("Incorrect number of action items returned",2,actionItems.size());
1366         for (ActionItem actionItem : actionItems) {
1367             assertEquals("Action Item should be Approve request", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, actionItem.getActionRequestCd());
1368             assertEquals("Action Item has incorrect doc title", docTitle, actionItem.getDocTitle());
1369             assertTrue("User should be one of '" + user1NetworkId + "' or '" + user2NetworkId + "'", user1PrincipalId.equals(actionItem.getPrincipalId()) || user2PrincipalId.equals(actionItem.getPrincipalId()));
1370         }
1371 
1372         principalId = getPrincipalIdForName(user2NetworkId);
1373         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1374         assertTrue(document.isApprovalRequested());
1375         TestUtilities.assertAtNode(document, "WorkflowDocument");
1376         document.returnToPreviousNode("", "AdHoc");
1377         TestUtilities.assertAtNode(document, "AdHoc");
1378         // verify count after return to previous
1379         actionItems = als.getActionItems(document.getDocumentId(), Arrays.asList(new String[]{KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}));
1380         verifyEmptyCollection("Action Item", actionItems);
1381         actionItems = als.getActionItems(document.getDocumentId(), Arrays.asList(
1382                 new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ}));
1383         assertEquals("Incorrect number of action items returned",1,actionItems.size());
1384         actionItems = als.getActionItems(document.getDocumentId(), Arrays.asList(
1385                 new String[]{KewApiConstants.ACTION_REQUEST_FYI_REQ}));
1386         assertEquals("Incorrect number of action items returned",1,actionItems.size());
1387         actionItems = als.getActionItems(document.getDocumentId(), Arrays.asList(
1388                 new String[]{KewApiConstants.ACTION_REQUEST_FYI_REQ, KewApiConstants.ACTION_REQUEST_APPROVE_REQ}));
1389         assertEquals("Incorrect number of action items returned",2,actionItems.size());
1390         for (ActionItem actionItem : actionItems) {
1391             assertEquals("Action Item has incorrect doc title", docTitle, actionItem.getDocTitle());
1392             assertTrue("Action Items should be Approve or FYI requests only", KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(actionItem.getActionRequestCd()) || KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(actionItem.getActionRequestCd()));
1393             if (KewApiConstants.ACTION_REQUEST_APPROVE_REQ.equals(actionItem.getActionRequestCd())) {
1394                 assertTrue("User should be '" + initiatorNetworkId + "'", initiatorPrincipalId.equals(actionItem.getPrincipalId()));
1395             } else if (KewApiConstants.ACTION_REQUEST_FYI_REQ.equals(actionItem.getActionRequestCd())) {
1396                 assertTrue("User should be  '" + user1NetworkId + "'", user1PrincipalId.equals(actionItem.getPrincipalId()));
1397             } else {
1398                 fail("Should not have found action request with requested action '" + KewApiConstants.ACTION_REQUEST_CD.get(actionItem.getActionRequestCd()) + "'");
1399             }
1400         }
1401 
1402         principalId = getPrincipalIdForName(initiatorNetworkId);
1403         document = WorkflowDocumentFactory.loadDocument(principalId, document.getDocumentId());
1404         assertTrue(document.isApprovalRequested());
1405         document.approve("");
1406         TestUtilities.assertAtNode(document, "WorkflowDocument");
1407 
1408         // we should be back where we were
1409         actionItems = als.getActionItems(document.getDocumentId(), Arrays.asList(
1410                 new String[]{KewApiConstants.ACTION_REQUEST_COMPLETE_REQ}));
1411         verifyEmptyCollection("Action Item", actionItems);
1412         actionItems = als.getActionItems(document.getDocumentId(), Arrays.asList(
1413                 new String[]{KewApiConstants.ACTION_REQUEST_APPROVE_REQ}));
1414         assertEquals("Incorrect number of action items returned",2,actionItems.size());
1415         for (ActionItem actionItem : actionItems) {
1416             assertEquals("Action Item should be Approve request", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, actionItem.getActionRequestCd());
1417             assertEquals("Action Item has incorrect doc title", docTitle, actionItem.getDocTitle());
1418             assertTrue("User should be one of '" + user1NetworkId + "' or '" + user2NetworkId + "'", user1PrincipalId.equals(actionItem.getPrincipalId()) || user2PrincipalId.equals(actionItem.getPrincipalId()));
1419         }
1420     }
1421 
1422     /**
1423      * This method routes two test documents of the type specified.  One has the given title and another has a dummy title.
1424      */
1425     private void setupPerformDocumentSearchTests(String documentTypeName, String expectedRouteNodeName, String docTitle) throws WorkflowException {
1426         String userNetworkId = "ewestfal";
1427         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName);
1428         workflowDocument.setTitle("Respect my Authoritah");
1429         workflowDocument.route("routing this document.");
1430         if (StringUtils.isNotBlank(expectedRouteNodeName)) {
1431         	assertEquals("Document is not at expected routeNodeName", expectedRouteNodeName, workflowDocument.getNodeNames().iterator().next());
1432         }
1433 
1434         userNetworkId = "rkirkend";
1435         workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName);
1436         workflowDocument.setTitle(docTitle);
1437         workflowDocument.route("routing this document.");
1438         if (StringUtils.isNotBlank(expectedRouteNodeName)) {
1439         	assertEquals("Document is not at expected routeNodeName", expectedRouteNodeName, workflowDocument.getNodeNames().iterator().next());
1440         }
1441     }
1442 
1443     @Test public void testPerformDocumentSearch_WithUser_CustomThreshold() throws Exception {
1444         runTestPerformDocumentSearch_CustomThreshold(getPrincipalIdForName("user2"));
1445     }
1446 
1447     @Test public void testPerformDocumentSearch_NoUser_CustomThreshold() throws Exception {
1448     	runTestPerformDocumentSearch_CustomThreshold(null);
1449     }
1450 
1451     private void runTestPerformDocumentSearch_CustomThreshold(String principalId) throws Exception {
1452         String documentTypeName = SeqSetup.DOCUMENT_TYPE_NAME;
1453         String docTitle = "Routing Style";
1454         setupPerformDocumentSearchTests(documentTypeName, null, docTitle);
1455 
1456         DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
1457         criteria.setDocumentTypeName(documentTypeName);
1458         DocumentSearchResults results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId,
1459                 criteria.build());
1460         assertEquals("Search results should have two documents.", 2, results.getSearchResults().size());
1461 
1462         int threshold = 1;
1463         criteria.setMaxResults(1);
1464         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1465         assertTrue("Search results should signify search went over the given threshold: " + threshold, results.isOverThreshold());
1466         assertEquals("Search results should have one document.", threshold, results.getSearchResults().size());
1467     }
1468 
1469     @Test public void testPerformDocumentSearch_WithUser_BasicCriteria() throws Exception {
1470         runTestPerformDocumentSearch_BasicCriteria(getPrincipalIdForName("user2"));
1471     }
1472 
1473     @Test public void testPerformDocumentSearch_NoUser_BasicCriteria() throws Exception {
1474     	runTestPerformDocumentSearch_BasicCriteria(null);
1475     }
1476 
1477     private void runTestPerformDocumentSearch_BasicCriteria(String principalId) throws Exception {
1478         String documentTypeName = SeqSetup.DOCUMENT_TYPE_NAME;
1479         String docTitle = "Routing Style";
1480         setupPerformDocumentSearchTests(documentTypeName, null, docTitle);
1481         String userNetworkId = "delyea";
1482         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName);
1483         workflowDocument.setTitle("Get Outta Dodge");
1484         workflowDocument.route("routing this document.");
1485 
1486         DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
1487         criteria.setDocumentTypeName(documentTypeName);
1488         criteria.setTitle(docTitle);
1489         DocumentSearchResults results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId,
1490                 criteria.build());
1491         assertEquals("Search results should have one document.", 1, results.getSearchResults().size());
1492 
1493         criteria = DocumentSearchCriteria.Builder.create();
1494         criteria.setInitiatorPrincipalName("rkirkend");
1495         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1496         assertEquals("Search results should have one document.", 1, results.getSearchResults().size());
1497 
1498         criteria = DocumentSearchCriteria.Builder.create();
1499         criteria.setInitiatorPrincipalName("user1");
1500         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1501         assertEquals("Search results should be empty.", 0, results.getSearchResults().size());
1502 
1503         criteria = DocumentSearchCriteria.Builder.create();
1504         criteria.setDocumentTypeName(documentTypeName);
1505         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1506         assertEquals("Search results should have three documents.", 3, results.getSearchResults().size());
1507         // now verify that the search returned the proper document id
1508         boolean foundValidDocId = false;
1509         for (DocumentSearchResult result : results.getSearchResults()) {
1510             if (result.getDocument().getDocumentId().equals(workflowDocument.getDocumentId())) {
1511                 foundValidDocId = true;
1512                 break;
1513             }
1514         }
1515         assertTrue("Should have found document search result with specified document id", foundValidDocId);
1516     }
1517 
1518     @Test public void testPerformDocumentSearch_WithUser_RouteNodeSearch() throws Exception {
1519         runTestPerformDocumentSearch_RouteNodeSearch(getPrincipalIdForName("user2"));
1520     }
1521 
1522     @Test public void testPerformDocumentSearch_NoUser_RouteNodeSearch() throws Exception {
1523     	runTestPerformDocumentSearch_RouteNodeSearch(null);
1524     }
1525 
1526     private void runTestPerformDocumentSearch_RouteNodeSearch(String principalId) throws Exception {
1527         String documentTypeName = SeqSetup.DOCUMENT_TYPE_NAME;
1528         setupPerformDocumentSearchTests(documentTypeName, SeqSetup.WORKFLOW_DOCUMENT_NODE, "Doc Title");
1529 
1530         // test exception thrown when route node specified and no doc type specified
1531         DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
1532         criteria.setRouteNodeName(SeqSetup.ADHOC_NODE);
1533         try {
1534             KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1535             fail("Exception should have been thrown when specifying a route node name but no document type name");
1536         } catch (IllegalStateException e) {
1537             e.printStackTrace();
1538         }
1539 
1540         // test exception thrown when route node specified does not exist on document type
1541         criteria = DocumentSearchCriteria.Builder.create();
1542         criteria.setDocumentTypeName(documentTypeName);
1543         criteria.setRouteNodeName("This is an invalid route node name!!!");
1544         try {
1545             DocumentSearchResults results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1546             assertTrue("No results should have been returned for route node name that does not exist on the specified documentType.", results.getSearchResults().isEmpty());
1547         } catch (Exception e) {
1548             fail("Exception should not have been thrown when specifying a route node name that does not exist on the specified document type name");
1549         }
1550 
1551         runPerformDocumentSearch_RouteNodeSearch(principalId, SeqSetup.ADHOC_NODE, documentTypeName, 0, 0, 2);
1552         runPerformDocumentSearch_RouteNodeSearch(principalId, SeqSetup.WORKFLOW_DOCUMENT_NODE, documentTypeName, 0, 2, 0);
1553         runPerformDocumentSearch_RouteNodeSearch(principalId, SeqSetup.WORKFLOW_DOCUMENT_2_NODE, documentTypeName, 2, 0, 0);
1554     }
1555 
1556     @Test public void testPerformDocumentSearch_RouteNodeSpecial() throws RemoteException, WorkflowException {
1557         String documentTypeName = "DocumentWithSpecialRouteNodes";
1558         setupPerformDocumentSearchTests(documentTypeName, "Level1", "Doc Title");
1559         runPerformDocumentSearch_RouteNodeSearch(null, "Level5", documentTypeName, 0, 0, 2);
1560         runPerformDocumentSearch_RouteNodeSearch(null, "Level1", documentTypeName, 0, 2, 0);
1561         runPerformDocumentSearch_RouteNodeSearch(null, "Level3", documentTypeName, 2, 0, 0);
1562 
1563     }
1564 
1565     private void runPerformDocumentSearch_RouteNodeSearch(String principalId, String routeNodeName, String documentTypeName, int countBeforeNode, int countAtNode, int countAfterNode) throws RemoteException, WorkflowException {
1566 
1567         DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
1568         criteria.setDocumentTypeName(documentTypeName);
1569         criteria.setRouteNodeName(routeNodeName);
1570         DocumentSearchResults results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId,
1571                 criteria.build());
1572         assertEquals("Wrong number of search results when checking docs at default node logic.", countAtNode, results.getSearchResults().size());
1573 
1574         criteria.setRouteNodeLookupLogic(RouteNodeLookupLogic.EXACTLY);
1575         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1576         assertEquals("Wrong number of search results when checking docs at exact node.", countAtNode, results.getSearchResults().size());
1577 
1578         criteria.setRouteNodeLookupLogic(RouteNodeLookupLogic.BEFORE);
1579         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1580         assertEquals("Wrong number of search results when checking docs before node.", countBeforeNode, results.getSearchResults().size());
1581 
1582         criteria.setRouteNodeLookupLogic(RouteNodeLookupLogic.AFTER);
1583         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1584         assertEquals("Wrong number of search results when checking docs after node.", countAfterNode, results.getSearchResults().size());
1585     }
1586 
1587     @Test public void testPerformDocumentSearch_WithUser_SearchAttributes() throws Exception {
1588     	runTestPerformDocumentSearch_SearchAttributes(getPrincipalIdForName("user2"));
1589     }
1590 
1591     @Test public void testPerformDocumentSearch_NoUser_SearchAttributes() throws Exception {
1592     	runTestPerformDocumentSearch_SearchAttributes(null);
1593     }
1594 
1595     private void runTestPerformDocumentSearch_SearchAttributes(String principalId) throws Exception {
1596         String documentTypeName = SeqSetup.DOCUMENT_TYPE_NAME;
1597         String docTitle = "Routing Style";
1598         setupPerformDocumentSearchTests(documentTypeName, null, docTitle);
1599 
1600         DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
1601         criteria.setDocumentTypeName(documentTypeName);
1602         criteria.getDocumentAttributeValues().put(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, Collections.singletonList(TestXMLSearchableAttributeString.SEARCH_STORAGE_VALUE));
1603         DocumentSearchResults results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId,
1604                 criteria.build());
1605         assertEquals("Search results should have two documents.", 2, results.getSearchResults().size());
1606 
1607         criteria = DocumentSearchCriteria.Builder.create();
1608         criteria.setDocumentTypeName(documentTypeName);
1609         criteria.getDocumentAttributeValues().put(TestXMLSearchableAttributeString.SEARCH_STORAGE_KEY, Collections.singletonList("fred"));
1610         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1611         assertEquals("Search results should be empty.", 0, results.getSearchResults().size());
1612 
1613         criteria = DocumentSearchCriteria.Builder.create();
1614         criteria.setDocumentTypeName(documentTypeName);
1615         criteria.getDocumentAttributeValues().put("fakeproperty", Collections.singletonList("doesntexist"));
1616         try {
1617             results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1618             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
1619         } catch (Exception e) {}
1620 
1621         criteria = DocumentSearchCriteria.Builder.create();
1622         criteria.setDocumentTypeName(documentTypeName);
1623         criteria.getDocumentAttributeValues().put(TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, Collections.singletonList(TestXMLSearchableAttributeLong.SEARCH_STORAGE_VALUE.toString()));
1624         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1625         assertEquals("Search results should have two documents.", 2, results.getSearchResults().size());
1626 
1627         criteria = DocumentSearchCriteria.Builder.create();
1628         criteria.setDocumentTypeName(documentTypeName);
1629         criteria.getDocumentAttributeValues().put(TestXMLSearchableAttributeLong.SEARCH_STORAGE_KEY, Collections.singletonList("1111111"));
1630         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1631         assertEquals("Search results should be empty.", 0, results.getSearchResults().size());
1632 
1633         criteria = DocumentSearchCriteria.Builder.create();
1634         criteria.setDocumentTypeName(documentTypeName);
1635         criteria.getDocumentAttributeValues().put("fakeymcfakefake", Collections.singletonList("99999999"));
1636         try {
1637             results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1638             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
1639         } catch (IllegalStateException ise) {
1640         } catch (Exception e) {}
1641 
1642         criteria = DocumentSearchCriteria.Builder.create();
1643         criteria.setDocumentTypeName(documentTypeName);
1644         criteria.getDocumentAttributeValues().put(TestXMLSearchableAttributeFloat.SEARCH_STORAGE_KEY, Collections.singletonList(TestXMLSearchableAttributeFloat.SEARCH_STORAGE_VALUE.toString()));
1645         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1646         assertEquals("Search results should have two documents.", 2, results.getSearchResults().size());
1647 
1648         criteria = DocumentSearchCriteria.Builder.create();
1649         criteria.setDocumentTypeName(documentTypeName);
1650         criteria.getDocumentAttributeValues().put(TestXMLSearchableAttributeFloat.SEARCH_STORAGE_KEY, Collections.singletonList("215.3548"));
1651         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1652         assertEquals("Search results should be empty.", 0, results.getSearchResults().size());
1653 
1654         criteria = DocumentSearchCriteria.Builder.create();
1655         criteria.setDocumentTypeName(documentTypeName);
1656         criteria.getDocumentAttributeValues().put("fakeylostington", Collections.singletonList("9999.9999"));
1657         try {
1658             results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1659             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
1660         } catch (Exception e) {}
1661 
1662         criteria = DocumentSearchCriteria.Builder.create();
1663         criteria.setDocumentTypeName(documentTypeName);
1664         criteria.getDocumentAttributeValues().put(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY, Collections.singletonList(
1665                 DocumentSearchInternalUtils.getDisplayValueWithDateOnly(new Timestamp(
1666                         TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_VALUE_IN_MILLS))));
1667         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1668         assertEquals("Search results should have two documents.", 2, results.getSearchResults().size());
1669 
1670         criteria = DocumentSearchCriteria.Builder.create();
1671         criteria.setDocumentTypeName(documentTypeName);
1672         criteria.getDocumentAttributeValues().put(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY, Collections.singletonList("07/06/1979"));
1673         results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1674         assertEquals("Search results should be empty.", 0, results.getSearchResults().size());
1675 
1676         criteria = DocumentSearchCriteria.Builder.create();
1677         criteria.setDocumentTypeName(documentTypeName);
1678         criteria.getDocumentAttributeValues().put("lastingsfakerson", Collections.singletonList("07/06/2007"));
1679         try {
1680             results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(principalId, criteria.build());
1681             fail("Search results should be throwing a validation exception for use of non-existant searchable attribute");
1682         } catch (Exception e) {}
1683     }
1684 
1685     @Test public void testGetSearchableAttributeDateTimeValuesByKey() throws Exception {
1686         String documentTypeName = SeqSetup.DOCUMENT_TYPE_NAME;
1687         String userNetworkId = "ewestfal";
1688         WorkflowDocument workflowDocument = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName);
1689         workflowDocument.setTitle("Respect my Authoritah");
1690         workflowDocument.route("routing this document.");
1691         userNetworkId = "rkirkend";
1692         WorkflowDocument workflowDocument2 = WorkflowDocumentFactory.createDocument(getPrincipalIdForName(userNetworkId), documentTypeName);
1693         workflowDocument2.setTitle("Routing Style");
1694         workflowDocument2.route("routing this document.");
1695 
1696         WorkflowDocumentService wds = KewApiServiceLocator.getWorkflowDocumentService();
1697         List<DateTime> dateTimes = wds.getSearchableAttributeDateTimeValuesByKey(workflowDocument.getDocumentId(), TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY);
1698         assertNotNull("dateTimes should not be null", dateTimes);
1699         assertTrue("dateTimes should not be empty", !dateTimes.isEmpty());
1700         verifyTimestampToSecond(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_VALUE_IN_MILLS, dateTimes.get(0).getMillis());
1701 
1702         dateTimes = wds.getSearchableAttributeDateTimeValuesByKey(workflowDocument2.getDocumentId(), TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_KEY);
1703         assertNotNull("dateTimes should not be null", dateTimes);
1704         assertTrue("dateTimes should not be empty", !dateTimes.isEmpty());
1705         verifyTimestampToSecond(TestXMLSearchableAttributeDateTime.SEARCH_STORAGE_VALUE_IN_MILLS, dateTimes.get(0).getMillis());
1706     }
1707 
1708     protected void verifyTimestampToSecond(Long originalTimeInMillis, Long testTimeInMillis) throws Exception {
1709         Calendar testDate = Calendar.getInstance();
1710         testDate.setTimeInMillis(originalTimeInMillis);
1711         testDate.set(Calendar.MILLISECOND, 0);
1712         Calendar attributeDate = Calendar.getInstance();
1713         attributeDate.setTimeInMillis(testTimeInMillis);
1714         attributeDate.set(Calendar.MILLISECOND, 0);
1715         assertEquals("The month value for the searchable attribute is wrong",testDate.get(Calendar.MONTH),attributeDate.get(Calendar.MONTH));
1716         assertEquals("The date value for the searchable attribute is wrong",testDate.get(Calendar.DATE),attributeDate.get(Calendar.DATE));
1717         assertEquals("The year value for the searchable attribute is wrong",testDate.get(Calendar.YEAR),attributeDate.get(Calendar.YEAR));
1718         assertEquals("The hour value for the searchable attribute is wrong",testDate.get(Calendar.HOUR),attributeDate.get(Calendar.HOUR));
1719         assertEquals("The minute value for the searchable attribute is wrong",testDate.get(Calendar.MINUTE),attributeDate.get(Calendar.MINUTE));
1720         assertEquals("The second value for the searchable attribute is wrong",testDate.get(Calendar.SECOND),attributeDate.get(Calendar.SECOND));
1721     }
1722 
1723     private void ruleExceptionTest(RuleReportCriteria ruleReportCriteria, String message) {
1724         try {
1725             KewApiServiceLocator.getRuleService().ruleReport(ruleReportCriteria);
1726             fail(message);
1727         } catch (Exception e) {
1728             //e.printStackTrace();
1729         }
1730     }
1731 
1732     private class RuleTestGeneralSetup {
1733         public static final String DOCUMENT_TYPE_NAME = "RuleTestDocType";
1734         public static final String RULE_TEST_TEMPLATE_1 = "WorkflowDocumentTemplate";
1735         public static final String RULE_TEST_TEMPLATE_2 = "WorkflowDocument2Template";
1736         public static final String RULE_TEST_TEMPLATE_3 = "WorkflowDocument3Template";
1737         public static final String RULE_TEST_GROUP_ID = "3003"; // the NonSIT group
1738     }
1739 
1740     private class RuleTestOrgReviewSetup {
1741         public static final String DOCUMENT_TYPE_NAME = "OrgReviewTestDocType";
1742         public static final String RULE_TEST_TEMPLATE = "OrgReviewTemplate";
1743         public static final String RULE_TEST_WORKGROUP = "Org_Review_Group";
1744         public static final String RULE_TEST_WORKGROUP2 = "Org_Review_Group_2";
1745         public static final String RULE_TEST_CHART_CODE_NAME = "chartCode";
1746         public static final String RULE_TEST_ORG_CODE_NAME = "orgCode";
1747     }
1748 
1749     private class SeqSetup {
1750         public static final String DOCUMENT_TYPE_NAME = "SeqDocType";
1751         public static final String LAST_APPROVER_DOCUMENT_TYPE_NAME = "SeqLastApproverDocType";
1752         public static final String CHILD_DOCUMENT_TYPE_NAME = "SeqChildDocType";
1753         public static final String ADHOC_NODE = "AdHoc";
1754         public static final String WORKFLOW_DOCUMENT_NODE = "WorkflowDocument";
1755         public static final String WORKFLOW_DOCUMENT_2_NODE = "WorkflowDocument2";
1756         public static final String ACKNOWLEDGE_1_NODE = "Acknowledge1";
1757         public static final String ACKNOWLEDGE_2_NODE = "Acknowledge2";
1758     }
1759     
1760     private class RouteLogTestSetup {
1761         public static final String DOCUMENT_TYPE_NAME = "UserAndGroupTestDocType";
1762         public static final String RULE_TEST_TEMPLATE_1 = "WorkflowDocumentTemplate";
1763         public static final String RULE_TEST_TEMPLATE_2 = "WorkflowDocument2Template";
1764         public static final String RULE_TEST_GROUP_ID = "3003"; // the NonSIT group
1765     }
1766 
1767 }