001    /**
002     * Copyright 2005-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kew.actionlist;
017    
018    import org.junit.Test;
019    import org.kuali.rice.core.api.util.Truth;
020    import org.kuali.rice.kew.actionitem.ActionItem;
021    import org.kuali.rice.kew.actionitem.OutboxItemActionListExtension;
022    import org.kuali.rice.kew.api.action.ActionInvocation;
023    import org.kuali.rice.kew.api.action.ActionRequest;
024    import org.kuali.rice.kew.api.action.ActionType;
025    import org.kuali.rice.kew.api.KewApiServiceLocator;
026    import org.kuali.rice.kew.api.WorkflowDocument;
027    import org.kuali.rice.kew.api.WorkflowDocumentFactory;
028    import org.kuali.rice.kew.api.action.ActionRequestType;
029    import org.kuali.rice.kew.api.preferences.Preferences;
030    import org.kuali.rice.kew.preferences.service.impl.PreferencesServiceImpl;
031    import org.kuali.rice.kew.rule.TestRuleAttribute;
032    import org.kuali.rice.kew.service.KEWServiceLocator;
033    import org.kuali.rice.kew.test.KEWTestCase;
034    import org.kuali.rice.kew.api.KewApiConstants;
035    import org.kuali.rice.test.BaselineTestCase;
036    import org.springframework.transaction.TransactionStatus;
037    import org.springframework.transaction.support.TransactionCallback;
038    import org.springframework.transaction.support.TransactionTemplate;
039    
040    import java.util.ArrayList;
041    import java.util.Collection;
042    import java.util.Iterator;
043    import java.util.List;
044    
045    import static org.junit.Assert.*;
046    
047    /**
048     * Tests Outbox functionality
049     *
050     * @author Kuali Rice Team (rice.collab@kuali.org)
051     */
052    @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
053    public class OutboxTest extends KEWTestCase {
054    
055        protected void loadTestData() throws Exception {
056            loadXmlFile("OutboxTestConfig.xml");
057        }
058    
059        private void turnOnOutboxForUser(final String principalId) {
060            new TransactionTemplate(KEWServiceLocator.getPlatformTransactionManager()).execute(new TransactionCallback() {
061                public Object doInTransaction(TransactionStatus status) {
062                    KEWServiceLocator.getUserOptionsService().save(principalId, Preferences.KEYS.USE_OUT_BOX, KewApiConstants.PREFERENCES_YES_VAL);
063                    return null;
064                }
065            });
066        }
067    
068        @Test
069        public void testOutboxItemNotSavedOnSavedDocumentStatus() throws Exception {
070            final String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
071            List<String> recipients = new ArrayList<String>();
072            recipients.add(rkirkendPrincipalId);
073            TestRuleAttribute.setRecipientPrincipalIds("TestRole", "qualRole", recipients);
074    
075            WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("quickstart"), "TestDocumentType");
076            document.route("");
077    
078            document = WorkflowDocumentFactory.loadDocument(rkirkendPrincipalId, document.getDocumentId());
079            assertTrue("approve should be requested", document.isApprovalRequested());
080    
081            turnOnOutboxForUser(rkirkendPrincipalId);
082    
083            document.saveDocument("");
084    
085            Collection<OutboxItemActionListExtension> outbox = KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter());
086            assertEquals("there should not be any outbox items", 0, outbox.size());
087        }
088    
089        @Test
090        public void testTakeActionsOnOutboxItem() throws Exception {
091    
092            final String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
093            List<String> recipients = new ArrayList<String>();
094            recipients.add(rkirkendPrincipalId);
095            TestRuleAttribute.setRecipientPrincipalIds("TestRole", "qualRole", recipients);
096    
097            WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("quickstart"),
098                    "TestDocumentType");
099            document.route("");
100    
101            document = WorkflowDocumentFactory.loadDocument(rkirkendPrincipalId, document.getDocumentId());
102            assertTrue("approve should be requested", document.isApprovalRequested());
103    
104            turnOnOutboxForUser(rkirkendPrincipalId);
105    
106            document.approve("");
107    
108            Collection<OutboxItemActionListExtension> outbox = KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter());
109            assertEquals("there should be an outbox item", 1, outbox.size());
110    
111            outbox = KEWServiceLocator.getActionListService().getOutboxItemsByDocumentType(document.getDocumentTypeName());
112            assertEquals("there should be an outbox item", 1, outbox.size());
113    
114            List<String> outBoxItemIds = new ArrayList();
115            ActionItem actionItem = null;
116            for (Iterator<OutboxItemActionListExtension> iterator = outbox.iterator(); iterator.hasNext(); ) {
117                actionItem = iterator.next();
118                outBoxItemIds.add(actionItem.getId());
119            }
120    
121            KEWServiceLocator.getActionListService().removeOutboxItems(rkirkendPrincipalId, outBoxItemIds);
122            outbox = KEWServiceLocator.getActionListService().getOutboxItemsByDocumentType(document.getDocumentTypeName());
123            assertEquals("there should be zero outbox item", 0, outbox.size());
124    
125            KEWServiceLocator.getActionListService().saveOutboxItem(actionItem);
126            outbox = KEWServiceLocator.getActionListService().getOutboxItemsByDocumentType(document.getDocumentTypeName());
127            assertEquals("there should be 1 outbox item", 1, outbox.size());
128        }
129    
130        @Test
131        public void testSingleOutboxItemPerDocument() throws Exception {
132            final String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
133            final String user1PrincipalId = getPrincipalIdForName("user1");
134            List<String> recipients = new ArrayList<String>();
135            recipients.add(rkirkendPrincipalId);
136            recipients.add(user1PrincipalId);
137            TestRuleAttribute.setRecipientPrincipalIds("TestRole", "qualRole", recipients);
138    
139            WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("quickstart"), "TestDocumentType");
140            document.route("");
141    
142            document = WorkflowDocumentFactory.loadDocument(rkirkendPrincipalId, document.getDocumentId());
143            assertTrue("approve should be requested", document.isApprovalRequested());
144    
145            turnOnOutboxForUser(rkirkendPrincipalId);
146    
147            document.adHocToPrincipal(ActionRequestType.APPROVE, "", user1PrincipalId, "", true);
148    
149            document.approve("");
150    
151            Collection<OutboxItemActionListExtension> outbox = KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter());
152            assertEquals("there should be an outbox item", 1, outbox.size());
153    
154            document = WorkflowDocumentFactory.loadDocument(user1PrincipalId, document.getDocumentId());
155            assertTrue("approve should be requested", document.isApprovalRequested());
156    
157            document.adHocToPrincipal(ActionRequestType.APPROVE, "", rkirkendPrincipalId, "", true);
158    
159            document = WorkflowDocumentFactory.loadDocument(rkirkendPrincipalId, document.getDocumentId());
160            assertTrue("approve should be requested", document.isApprovalRequested());
161            document.approve("");
162    
163            outbox = KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter());
164            assertEquals("there should be an outbox item", 1, outbox.size());
165    
166    
167        }
168    
169    
170        @Test
171        public void testOnlyPersonWhoTookActionReceivesOutboxItem_Route() throws Exception {
172            final String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
173            final String user1PrincipalId = getPrincipalIdForName("user1");
174            List<String> recipients = new ArrayList<String>();
175            recipients.add(getPrincipalIdForName("rkirkend"));
176            recipients.add(getPrincipalIdForName("user1"));
177            TestRuleAttribute.setRecipientPrincipalIds("TestRole", "qualRole", recipients);
178    
179            turnOnOutboxForUser(rkirkendPrincipalId);
180            turnOnOutboxForUser(user1PrincipalId);
181    
182            WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("quickstart"), "TestDocumentType");
183            document.route("");
184    
185            // verify test is sane and users have action items
186            assertFalse(KEWServiceLocator.getActionListService().getActionList(rkirkendPrincipalId, new ActionListFilter()).isEmpty());
187            assertFalse(KEWServiceLocator.getActionListService().getActionList(user1PrincipalId, new ActionListFilter()).isEmpty());
188    
189            document = WorkflowDocumentFactory.loadDocument(user1PrincipalId, document.getDocumentId());
190            document.approve("");
191            // verify only user who took action has the outbox item
192            assertTrue(KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter()).isEmpty());
193            assertEquals(1, KEWServiceLocator.getActionListService().getOutbox(user1PrincipalId, new ActionListFilter()).size());
194        }
195    
196        @Test
197        public void testOnlyPersonWhoTookActionReceivesOutboxItem_BlanketApprove() throws Exception {
198            final String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
199            final String user1PrincipalId = getPrincipalIdForName("user1");
200            List<String> recipients = new ArrayList<String>();
201            recipients.add(rkirkendPrincipalId);
202            recipients.add(user1PrincipalId);
203            TestRuleAttribute.setRecipientPrincipalIds("TestRole", "qualRole", recipients);
204    
205            turnOnOutboxForUser(rkirkendPrincipalId);
206            turnOnOutboxForUser(user1PrincipalId);
207    
208            WorkflowDocument document = WorkflowDocumentFactory.createDocument(rkirkendPrincipalId, "TestDocumentType");
209            document.blanketApprove("");
210            // verify only user who took action has the outbox item
211            assertEquals("Wrong number of outbox items found for rkirkend", 0, KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter()).size());
212            assertEquals("Wrong number of outbox items found for user1", 0, KEWServiceLocator.getActionListService().getOutbox(user1PrincipalId, new ActionListFilter()).size());
213    
214            document = WorkflowDocumentFactory.createDocument(rkirkendPrincipalId, "TestDocumentType");
215            document.saveDocument("");
216            // verify test is sane and users have action items
217            assertEquals("Wrong number of action items found for rkirkend", 1, KEWServiceLocator.getActionListService().getActionList(rkirkendPrincipalId, new ActionListFilter()).size());
218            // verify that outboxes of two users are clear
219            assertEquals("Wrong number of outbox items found for rkirkend", 0, KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter()).size());
220            assertEquals("Wrong number of outbox items found for user1", 0, KEWServiceLocator.getActionListService().getOutbox(user1PrincipalId, new ActionListFilter()).size());
221    
222            document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
223            document.blanketApprove("");
224            // verify only user who took action has the outbox item
225            assertEquals("Wrong number of outbox items found for rkirkend", 1, KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter()).size());
226            assertEquals("Wrong number of outbox items found for user1", 0, KEWServiceLocator.getActionListService().getOutbox(user1PrincipalId, new ActionListFilter()).size());
227        }
228    
229        @Test
230        public void testOnlyPersonWhoTookActionReceivesOutboxItem_Workgroup() throws Exception {
231            final String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
232            final String user1PrincipalId = getPrincipalIdForName("user1");
233            final String ewestfalPrincipalId = getPrincipalIdForName("ewestfal");
234    
235            turnOnOutboxForUser(rkirkendPrincipalId);
236            turnOnOutboxForUser(user1PrincipalId);
237    
238            WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user2"), "OutboxTestDocumentType");
239            document.route("");
240            // verify action items exist
241            assertEquals("Wrong number of action items found for rkirkend", 1, KEWServiceLocator.getActionListService().getActionList(rkirkendPrincipalId, new ActionListFilter()).size());
242            assertEquals("Wrong number of action items found for ewestfal", 1, KEWServiceLocator.getActionListService().getActionList(ewestfalPrincipalId, new ActionListFilter()).size());
243            assertEquals("Wrong number of action items found for user1", 1, KEWServiceLocator.getActionListService().getActionList(user1PrincipalId, new ActionListFilter()).size());
244            // verify outboxes are clear
245            assertEquals("Wrong number of outbox items found for rkirkend", 0, KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter()).size());
246            assertEquals("Wrong number of outbox items found for ewestfal", 0, KEWServiceLocator.getActionListService().getOutbox(ewestfalPrincipalId, new ActionListFilter()).size());
247            assertEquals("Wrong number of outbox items found for user1", 0, KEWServiceLocator.getActionListService().getOutbox(user1PrincipalId, new ActionListFilter()).size());
248    
249            document = WorkflowDocumentFactory.loadDocument(rkirkendPrincipalId, document.getDocumentId());
250            document.approve("");
251            // verify only user who took action has the outbox item
252            assertEquals("Wrong number of outbox items found for rkirkend", 1, KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter()).size());
253            assertEquals("Wrong number of outbox items found for ewestfal", 0, KEWServiceLocator.getActionListService().getOutbox(ewestfalPrincipalId, new ActionListFilter()).size());
254            assertEquals("Wrong number of outbox items found for user1", 0, KEWServiceLocator.getActionListService().getOutbox(user1PrincipalId, new ActionListFilter()).size());
255        }
256    
257        @Test
258        public void testOutBoxDefaultPreferenceOnConfigParam() throws Exception {
259            final String user1PrincipalId = getPrincipalIdForName("user1");
260            Preferences prefs = KewApiServiceLocator.getPreferencesService().getPreferences(user1PrincipalId);
261            assertTrue("By default the user's pref should be outbox on", Truth.strToBooleanIgnoreCase(prefs.getUseOutbox()));
262    
263            //TODO: this can no longer be set on the fly and grabbed through the preferences service (default values are set at startup)
264            //TODO: this is a prime candidate for a mocking tool
265            /*ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.USER_OPTIONS_DEFAULT_USE_OUTBOX_PARAM, "false");
266            final String natjohnsPrincipalId = getPrincipalIdForName("natjohns");
267            prefs = KEWServiceLocator.getPreferencesService().getPreferences(natjohnsPrincipalId);
268            assertFalse("The user's pref should be outbox off", prefs.isUsingOutbox());*/
269        }
270        
271        @Test
272        public void testTakeMassActions() throws Exception {
273            final String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
274            List<String> recipients = new ArrayList<String>();
275            recipients.add(rkirkendPrincipalId);
276            TestRuleAttribute.setRecipientPrincipalIds("TestRole", "qualRole", recipients);
277            turnOnOutboxForUser(rkirkendPrincipalId);
278    
279            WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("quickstart"), "TestDocumentType");
280            document.route("");
281            
282            document = WorkflowDocumentFactory.loadDocument(rkirkendPrincipalId, document.getDocumentId());
283            assertTrue("approve should be requested", document.isApprovalRequested());
284         
285            document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), "OutboxTestDocumentType");
286            document.route("");
287            
288            document = WorkflowDocumentFactory.loadDocument(rkirkendPrincipalId, document.getDocumentId());
289            assertTrue("approve should be requested", document.isApprovalRequested());
290            
291            List<ActionItem> actionList = new ArrayList<ActionItem>(KEWServiceLocator.getActionListService().getActionList(rkirkendPrincipalId, new ActionListFilter()));
292            List<ActionInvocation> invocations = new ArrayList<ActionInvocation>();
293            ActionToTake actionToTake = new ActionToTake();
294            ActionItem actionItem = new ActionItem();
295    
296            for (ActionItem actinItem : actionList)
297            {
298                actionToTake.setActionItemId(actinItem.getId());
299                actionToTake.setActionTakenCd(actinItem.getActionRequestCd());
300                invocations.add(ActionInvocation.create(ActionType.fromCode(actionToTake.getActionTakenCd()),
301                        actinItem.getId()));
302            }
303            KEWServiceLocator.getWorkflowDocumentService().takeMassActions(rkirkendPrincipalId, invocations);
304            assertEquals("Wrong number of outbox items found for rkirkendPrincipalId", 2, KEWServiceLocator.getActionListService().getOutbox(rkirkendPrincipalId, new ActionListFilter()).size());
305              
306        }
307    }