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