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