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