View Javadoc

1   /**
2    * Copyright 2005-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kew.actionrequest.service.impl;
17  
18  import static org.junit.Assert.assertEquals;
19  import static org.junit.Assert.assertFalse;
20  import static org.junit.Assert.assertNotNull;
21  import static org.junit.Assert.assertTrue;
22  
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import mocks.MockDocumentRefreshQueueImpl;
27  import mocks.MockEmailNotificationService;
28  
29  import org.apache.commons.collections.CollectionUtils;
30  import org.apache.commons.lang.StringUtils;
31  import org.junit.Test;
32  import org.kuali.rice.core.api.config.CoreConfigHelper;
33  import org.kuali.rice.core.api.delegation.DelegationType;
34  import org.kuali.rice.kew.actionitem.ActionItem;
35  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
36  import org.kuali.rice.kew.api.KewApiServiceLocator;
37  import org.kuali.rice.kew.api.WorkflowDocument;
38  import org.kuali.rice.kew.api.WorkflowDocumentFactory;
39  import org.kuali.rice.kew.api.action.ActionRequest;
40  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
41  import org.kuali.rice.kew.rule.RuleBaseValues;
42  import org.kuali.rice.kew.rule.RuleDelegationBo;
43  import org.kuali.rice.kew.rule.RuleResponsibilityBo;
44  import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
45  import org.kuali.rice.kew.service.KEWServiceLocator;
46  import org.kuali.rice.kew.test.KEWTestCase;
47  import org.kuali.rice.kew.api.KewApiConstants;
48  
49  /**
50   * This is a description of what this class does - gilesp don't forget to fill this in.
51   * 
52   * @author Kuali Rice Team (rice.collab@kuali.org)
53   * 
54   */
55  public class NotificationSuppressionTest extends KEWTestCase {
56  
57      private static final String TEST_RULE_TEMPLATE = "WorkflowDocumentTemplate";
58  
59      protected void loadTestData() throws Exception {
60          loadXmlFile("NotificationSuppressionTestConfig.xml");
61      }
62  
63      private static final String TEST_DOC_TYPE = "NotificationSuppressionTestDocType";
64  
65      /**
66       * Tests that the notification suppression keys work equivalently for ActionRequestDTO and
67       * ActionRequestValue
68       * 
69       * @throws Exception
70       */
71      @Test
72      public void testNotificationSuppressionKeys() throws Exception {
73          WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"),
74                  TEST_DOC_TYPE);
75          document.route("");
76          List<ActionRequest> requests = document.getRootActionRequests();
77          assertTrue("there must be ActionRequestDTOs to test!", requests != null && requests.size() > 0);
78  
79          NotificationSuppression notificationSuppression = new NotificationSuppression();
80  
81          boolean atLeastOne = false;
82          for (ActionRequest reqDTO : requests)
83              if (reqDTO.getParentActionRequestId() == null) {
84                  atLeastOne = true;
85                  ActionRequestValue reqVal = ActionRequestValue.from(reqDTO);
86                  assertTrue(CollectionUtils.isEqualCollection(
87                          notificationSuppression.getSuppressNotifyNodeStateKeys(reqVal),
88                          notificationSuppression.getSuppressNotifyNodeStateKeys(reqDTO)));
89  
90                  // test that changing the responsible party changes the key
91  
92                  ActionRequest.Builder builder = ActionRequest.Builder.create(reqDTO);
93                  builder.setPrincipalId("asdf");
94                  reqDTO = builder.build();
95                  assertFalse(CollectionUtils.isEqualCollection(
96                          notificationSuppression.getSuppressNotifyNodeStateKeys(reqVal),
97                          notificationSuppression.getSuppressNotifyNodeStateKeys(reqDTO)));
98              }
99          assertTrue(atLeastOne);
100 
101     }
102 
103     /**
104      * test that ActionItemS are filtered when a corresponding notification suppression NodeState is
105      * present in the related RouteNodeInstance
106      * 
107      * @throws Exception
108      */
109     @Test
110     public void testActionItemFiltering() throws Exception {
111         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"),
112                 TEST_DOC_TYPE);
113         document.route("");
114         List<ActionRequest> requests = document.getRootActionRequests();
115         assertTrue("there must be ActionRequestDTOs to test!", requests != null && requests.size() > 0);
116 
117         NotificationSuppression notificationSuppression = new NotificationSuppression();
118 
119         boolean atLeastOne = false;
120         for (ActionRequest reqDTO : requests) {
121             if (reqDTO.getParentActionRequestId() == null) {
122                 atLeastOne = true;
123 
124                 ActionRequestValue reqVal = ActionRequestValue.from(reqDTO);
125 
126                 List<ActionItem> actionItems = new ArrayList<ActionItem>();
127                 actionItems.add(KEWServiceLocator.getActionListService().createActionItemForActionRequest(reqVal));
128 
129                 RouteNodeInstance routeNodeInstance = new RouteNodeInstance();
130 
131                 // if there is no notification suppression state, nothing should be filtered
132                 int actionItemsCount = actionItems.size();
133                 notificationSuppression.filterNotificationSuppressedActionItems(actionItems, routeNodeInstance);
134                 assertTrue(actionItemsCount == actionItems.size());
135 
136                 // if there is a suppression state for this ActionRequestValue, the ActionItem(s) should be filtered
137                 notificationSuppression.addNotificationSuppression(routeNodeInstance, reqVal);
138                 notificationSuppression.filterNotificationSuppressedActionItems(actionItems, routeNodeInstance);
139                 assertTrue(actionItems.size() == 0);
140             }
141         }
142         assertTrue(atLeastOne);
143 
144     }
145 
146     /**
147      * This method tests email suppression soup to nuts by routing / requeueing documents and
148      * meddling with the responsible parties.
149      * 
150      * @throws Exception
151      */
152     @Test
153     public void testSuppression() throws Exception {
154         WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"),
155                 TEST_DOC_TYPE);
156         document.route("");
157 
158         assertTrue("the responsible party should have been notified",
159                 1 == getMockEmailService().immediateReminderEmailsSent("user1", document.getDocumentId(),
160                         KewApiConstants.ACTION_REQUEST_COMPLETE_REQ));
161 
162         getMockEmailService().resetReminderCounts();
163 
164         List<RuleBaseValues> existingRules =
165                 KEWServiceLocator.getRuleService().fetchAllCurrentRulesForTemplateDocCombination(TEST_RULE_TEMPLATE,
166                         TEST_DOC_TYPE);
167         assertNotNull(existingRules);
168         assertEquals(1, existingRules.size());
169 
170         RuleBaseValues originalRule = existingRules.get(0);
171         assertTrue("Original rule should be current.", originalRule.getCurrentInd());
172 
173         List<RuleResponsibilityBo> originalResps = originalRule.getRuleResponsibilities();
174         assertEquals(1, originalResps.size());
175 
176         RuleResponsibilityBo originalResp = originalResps.get(0);
177 
178         RuleTemplateBo ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(
179                 TEST_RULE_TEMPLATE);
180         assertNotNull(ruleTemplate);
181         assertNotNull(ruleTemplate.getId());
182         assertFalse(StringUtils.isEmpty(ruleTemplate.getName()));
183 
184         // save a new rule delegation
185         RuleDelegationBo ruleDelegation = new RuleDelegationBo();
186         ruleDelegation.setResponsibilityId(originalResp.getResponsibilityId());
187         ruleDelegation.setDelegationType(DelegationType.PRIMARY);
188         RuleBaseValues rule = new RuleBaseValues();
189         ruleDelegation.setDelegationRule(rule);
190         rule.setDelegateRule(true);
191         rule.setActive(true);
192         rule.setCurrentInd(true);
193         rule.setDocTypeName(originalRule.getDocTypeName());
194         rule.setRuleTemplateId(ruleTemplate.getDelegationTemplateId());
195         rule.setRuleTemplate(ruleTemplate);
196         rule.setDescription("Description of this delegate rule");
197         rule.setForceAction(true);
198         RuleResponsibilityBo delegationResponsibility = new RuleResponsibilityBo();
199         rule.getRuleResponsibilities().add(delegationResponsibility);
200         delegationResponsibility.setRuleBaseValues(rule);
201         delegationResponsibility.setRuleResponsibilityName("user2");
202         delegationResponsibility.setRuleResponsibilityType(KewApiConstants.RULE_RESPONSIBILITY_WORKFLOW_ID);
203 
204         // reset mock service test data
205         getMockEmailService().resetReminderCounts();
206         MockDocumentRefreshQueueImpl.clearRequeuedDocumentIds();
207 
208         // this *SHOULD* requeue
209         KEWServiceLocator.getRuleService().saveRuleDelegation(ruleDelegation, true);
210 
211         assertTrue("document should have been requeued",
212                 MockDocumentRefreshQueueImpl.getRequeuedDocumentIds().contains(document.getDocumentId()));
213 
214         assertTrue("should have notified user2",
215                 1 == getMockEmailService().immediateReminderEmailsSent("user2", document.getDocumentId(),
216                         KewApiConstants.ACTION_REQUEST_COMPLETE_REQ));
217         assertTrue("the responsible party that is delegating should not be notified",
218                 0 == getMockEmailService().immediateReminderEmailsSent("user1", document.getDocumentId(),
219                         KewApiConstants.ACTION_REQUEST_COMPLETE_REQ));
220 
221         getMockEmailService().resetReminderCounts();
222 
223         // now if we requeue, nobody should get notified
224         MockDocumentRefreshQueueImpl.clearRequeuedDocumentIds();
225         String applicationId = KEWServiceLocator.getRouteHeaderService().getApplicationIdByDocumentId(
226                 document.getDocumentId());
227         KewApiServiceLocator.getDocumentRequeuerService(
228                 (applicationId != null) ? applicationId : CoreConfigHelper.getApplicationId(), document.getDocumentId(),
229                 0).refreshDocument(document.getDocumentId());
230 
231         assertTrue("nobody should have been notified",
232                 0 == getMockEmailService().immediateReminderEmailsSent("user2", document.getDocumentId(),
233                         KewApiConstants.ACTION_REQUEST_COMPLETE_REQ));
234         assertTrue("nobody should have been notified",
235                 0 == getMockEmailService().immediateReminderEmailsSent("user1", document.getDocumentId(),
236                         KewApiConstants.ACTION_REQUEST_COMPLETE_REQ));
237 
238         getMockEmailService().resetReminderCounts();
239     }
240 
241     private MockEmailNotificationService getMockEmailService() {
242         return (MockEmailNotificationService) KEWServiceLocator.getActionListEmailService();
243     }
244 }