View Javadoc

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