001 /**
002 * Copyright 2005-2011 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.kew.actionrequest.service.impl;
017
018 import static org.junit.Assert.assertEquals;
019 import static org.junit.Assert.assertFalse;
020 import static org.junit.Assert.assertNotNull;
021 import static org.junit.Assert.assertTrue;
022
023 import java.util.ArrayList;
024 import java.util.List;
025
026 import mocks.MockDocumentRefreshQueueImpl;
027 import mocks.MockEmailNotificationService;
028
029 import org.apache.commons.collections.CollectionUtils;
030 import org.apache.commons.lang.StringUtils;
031 import org.junit.Test;
032 import org.kuali.rice.core.api.config.CoreConfigHelper;
033 import org.kuali.rice.core.api.delegation.DelegationType;
034 import org.kuali.rice.kew.actionitem.ActionItem;
035 import org.kuali.rice.kew.actionrequest.ActionRequestValue;
036 import org.kuali.rice.kew.api.WorkflowDocument;
037 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
038 import org.kuali.rice.kew.api.action.ActionRequest;
039 import org.kuali.rice.kew.engine.node.RouteNodeInstance;
040 import org.kuali.rice.kew.messaging.MessageServiceNames;
041 import org.kuali.rice.kew.rule.RuleBaseValues;
042 import org.kuali.rice.kew.rule.RuleDelegationBo;
043 import org.kuali.rice.kew.rule.RuleResponsibilityBo;
044 import org.kuali.rice.kew.rule.bo.RuleTemplateBo;
045 import org.kuali.rice.kew.service.KEWServiceLocator;
046 import org.kuali.rice.kew.test.KEWTestCase;
047 import org.kuali.rice.kew.api.KewApiConstants;
048
049 /**
050 * This is a description of what this class does - gilesp don't forget to fill this in.
051 *
052 * @author Kuali Rice Team (rice.collab@kuali.org)
053 *
054 */
055 public class NotificationSuppressionTest extends KEWTestCase {
056
057 private static final String TEST_RULE_TEMPLATE = "WorkflowDocumentTemplate";
058
059 protected void loadTestData() throws Exception {
060 loadXmlFile("NotificationSuppressionTestConfig.xml");
061 }
062
063 private static final String TEST_DOC_TYPE = "NotificationSuppressionTestDocType";
064
065 /**
066 * Tests that the notification suppression keys work equivalently for ActionRequestDTO and
067 * ActionRequestValue
068 *
069 * @throws Exception
070 */
071 @Test
072 public void testNotificationSuppressionKeys() throws Exception {
073 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("ewestfal"),
074 TEST_DOC_TYPE);
075 document.route("");
076 List<ActionRequest> requests = document.getRootActionRequests();
077 assertTrue("there must be ActionRequestDTOs to test!", requests != null && requests.size() > 0);
078
079 NotificationSuppression notificationSuppression = new NotificationSuppression();
080
081 boolean atLeastOne = false;
082 for (ActionRequest reqDTO : requests)
083 if (reqDTO.getParentActionRequestId() == null) {
084 atLeastOne = true;
085 ActionRequestValue reqVal = ActionRequestValue.from(reqDTO);
086 assertTrue(CollectionUtils.isEqualCollection(
087 notificationSuppression.getSuppressNotifyNodeStateKeys(reqVal),
088 notificationSuppression.getSuppressNotifyNodeStateKeys(reqDTO)));
089
090 // test that changing the responsible party changes the key
091
092 ActionRequest.Builder builder = ActionRequest.Builder.create(reqDTO);
093 builder.setPrincipalId("asdf");
094 reqDTO = builder.build();
095 assertFalse(CollectionUtils.isEqualCollection(
096 notificationSuppression.getSuppressNotifyNodeStateKeys(reqVal),
097 notificationSuppression.getSuppressNotifyNodeStateKeys(reqDTO)));
098 }
099 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 MessageServiceNames.getDocumentRequeuerService(
228 (applicationId != null) ? applicationId : CoreConfigHelper.getApplicationId(),
229 document.getDocumentId(), 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 }