View Javadoc

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