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 }