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