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