View Javadoc

1   /*
2    * Copyright 2007-2009 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 java.util.ArrayList;
19  import java.util.List;
20  
21  import mocks.MockDocumentRequeuerImpl;
22  import mocks.MockEmailNotificationService;
23  
24  import org.apache.commons.collections.CollectionUtils;
25  import org.apache.commons.lang.StringUtils;
26  import org.junit.Test;
27  import org.kuali.rice.kew.actionitem.ActionItem;
28  import org.kuali.rice.kew.actionrequest.ActionRequestScenariosTest;
29  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
30  import org.kuali.rice.kew.actionrequest.service.impl.DocumentRequeuerImpl;
31  import org.kuali.rice.kew.actionrequest.service.impl.NotificationSuppression;
32  import org.kuali.rice.kew.dto.ActionRequestDTO;
33  import org.kuali.rice.kew.dto.DTOConverter;
34  import org.kuali.rice.kew.dto.NetworkIdDTO;
35  import org.kuali.rice.kew.engine.node.RouteNodeInstance;
36  import org.kuali.rice.kew.rule.RuleBaseValues;
37  import org.kuali.rice.kew.rule.RuleDelegation;
38  import org.kuali.rice.kew.rule.RuleResponsibility;
39  import org.kuali.rice.kew.rule.bo.RuleTemplate;
40  import org.kuali.rice.kew.service.KEWServiceLocator;
41  import org.kuali.rice.kew.service.WorkflowDocument;
42  import org.kuali.rice.kew.test.KEWTestCase;
43  import org.kuali.rice.kew.util.KEWConstants;
44  
45  
46  /**
47   * This is a description of what this class does - gilesp don't forget to fill this in. 
48   * 
49   * @author Kuali Rice Team (rice.collab@kuali.org)
50   *
51   */
52  public class NotificationSuppressionTest extends KEWTestCase {
53  
54  	private static final String TEST_RULE_TEMPLATE = "WorkflowDocumentTemplate";
55  
56  	protected void loadTestData() throws Exception {
57  		loadXmlFile("NotificationSuppressionTestConfig.xml");
58  	}
59  	
60  	private static final String TEST_DOC_TYPE = "NotificationSuppressionTestDocType";
61  
62  	/**
63  	 * Tests that the notification suppression keys work equivalently for ActionRequestDTO and ActionRequestValue
64  	 * 
65  	 * @throws Exception
66  	 */
67  	@Test public void testNotificationSuppressionKeys() throws Exception {
68  		WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), TEST_DOC_TYPE);
69  		document.routeDocument("");
70  		ActionRequestDTO[] requests = document.getActionRequests();
71  		assertTrue("there must be ActionRequestDTOs to test!", requests != null && requests.length > 0);
72  
73  		NotificationSuppression notificationSuppression = new NotificationSuppression();
74  
75  		boolean atLeastOne = false;
76  		for (ActionRequestDTO reqDTO : requests) if (reqDTO.getParentActionRequestId() == null) {
77  			atLeastOne = true;
78  			ActionRequestValue reqVal = DTOConverter.convertActionRequestDTO(reqDTO);
79  			assertTrue(CollectionUtils.isEqualCollection(notificationSuppression.getSuppressNotifyNodeStateKeys(reqVal),
80  					notificationSuppression.getSuppressNotifyNodeStateKeys(reqDTO)));
81  
82  			// test that changing the responsible party changes the key
83  
84  			reqDTO.setPrincipalId("asdf");
85  			assertFalse(CollectionUtils.isEqualCollection(notificationSuppression.getSuppressNotifyNodeStateKeys(reqVal),
86  					notificationSuppression.getSuppressNotifyNodeStateKeys(reqDTO)));
87  		}
88  		assertTrue(atLeastOne);
89  
90  	}
91  	
92  	/**
93  	 * test that ActionItemS are filtered when a corresponding notification suppression NodeState is present
94  	 * in the related RouteNodeInstance
95  	 * 
96  	 * @throws Exception
97  	 */
98  	@Test public void testActionItemFiltering() throws Exception {
99  		WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), TEST_DOC_TYPE);
100 		document.routeDocument("");
101 		ActionRequestDTO[] requests = document.getActionRequests();
102 		assertTrue("there must be ActionRequestDTOs to test!", requests != null && requests.length > 0);
103 		
104 		NotificationSuppression notificationSuppression = new NotificationSuppression();
105 
106 		boolean atLeastOne = false;
107 		for (ActionRequestDTO reqDTO : requests) if (reqDTO.getParentActionRequestId() == null) {
108 			atLeastOne = true;
109 			
110 			ActionRequestValue reqVal = DTOConverter.convertActionRequestDTO(reqDTO);
111 
112 			List<ActionItem> actionItems = new ArrayList<ActionItem>();
113 			actionItems.add(KEWServiceLocator.getActionListService().createActionItemForActionRequest(reqVal));
114 			
115 			RouteNodeInstance routeNodeInstance = new RouteNodeInstance();
116 			
117 			// if there is no notification suppression state, nothing should be filtered
118 			int actionItemsCount = actionItems.size();
119 			notificationSuppression.filterNotificationSuppressedActionItems(actionItems, routeNodeInstance);
120 			assertTrue(actionItemsCount == actionItems.size());
121 			
122 			// if there is a suppression state for this ActionRequestValue, the ActionItem(s) should be filtered
123 			notificationSuppression.addNotificationSuppression(routeNodeInstance, reqVal);
124 			notificationSuppression.filterNotificationSuppressedActionItems(actionItems, routeNodeInstance);
125 			assertTrue(actionItems.size() == 0);
126 		}
127 		assertTrue(atLeastOne);
128 		
129 	}
130 	
131 	/**
132 	 * This method tests email suppression soup to nuts by routing / requeueing documents and meddling
133 	 * with the responsible parties.
134 	 * 
135 	 * @throws Exception
136 	 */
137 	@Test public void testSuppression() throws Exception {
138 		WorkflowDocument document = new WorkflowDocument(new NetworkIdDTO("ewestfal"), TEST_DOC_TYPE);
139 		document.routeDocument("");
140 
141 		assertTrue("the responsible party should have been notified",
142 				1 == getMockEmailService().immediateReminderEmailsSent("user1", document.getRouteHeaderId(), 
143 				KEWConstants.ACTION_REQUEST_COMPLETE_REQ));
144 		
145 		getMockEmailService().resetReminderCounts();
146 		
147 		List<RuleBaseValues> existingRules = 
148 			KEWServiceLocator.getRuleService().fetchAllCurrentRulesForTemplateDocCombination(TEST_RULE_TEMPLATE, TEST_DOC_TYPE);
149 		assertNotNull(existingRules);
150 		assertEquals(1, existingRules.size());
151 
152 		RuleBaseValues originalRule = existingRules.get(0);
153 		assertTrue("Original rule should be current.", originalRule.getCurrentInd());
154 
155 		List<RuleResponsibility> originalResps = originalRule.getResponsibilities();
156 		assertEquals(1, originalResps.size());
157 
158 		RuleResponsibility originalResp = originalResps.get(0);
159 
160 		RuleTemplate ruleTemplate = KEWServiceLocator.getRuleTemplateService().findByRuleTemplateName(TEST_RULE_TEMPLATE);
161 		assertNotNull(ruleTemplate);
162 		assertNotNull(ruleTemplate.getRuleTemplateId());
163 		assertFalse(StringUtils.isEmpty(ruleTemplate.getName()));
164 
165 		// save a new rule delegation
166 		RuleDelegation ruleDelegation = new RuleDelegation();
167 		ruleDelegation.setResponsibilityId(originalResp.getResponsibilityId());
168 		ruleDelegation.setDelegationType(KEWConstants.DELEGATION_PRIMARY);
169 		RuleBaseValues rule = new RuleBaseValues();
170 		ruleDelegation.setDelegationRuleBaseValues(rule);
171 		rule.setDelegateRule(true);
172 		rule.setActiveInd(true);
173 		rule.setCurrentInd(true);
174 		rule.setDocTypeName(originalRule.getDocTypeName());
175 		rule.setRuleTemplateId(ruleTemplate.getDelegationTemplateId());
176 		rule.setRuleTemplate(ruleTemplate);
177 		rule.setDescription("Description of this delegate rule");
178 		rule.setForceAction(true);
179 		RuleResponsibility delegationResponsibility = new RuleResponsibility();
180 		rule.getResponsibilities().add(delegationResponsibility);
181 		delegationResponsibility.setRuleBaseValues(rule);
182 		delegationResponsibility.setRuleResponsibilityName("user2");
183 		delegationResponsibility.setRuleResponsibilityType(KEWConstants.RULE_RESPONSIBILITY_WORKFLOW_ID);
184 
185 		// reset mock service test data
186 		getMockEmailService().resetReminderCounts();
187 		MockDocumentRequeuerImpl.clearRequeuedDocumentIds();
188 		
189 		// this *SHOULD* requeue
190 		KEWServiceLocator.getRuleService().saveRuleDelegation(ruleDelegation, true);
191 
192 		assertTrue("document should have been requeued",
193 				MockDocumentRequeuerImpl.getRequeuedDocumentIds().contains(document.getRouteHeaderId()));
194 		
195 		assertTrue("should have notified user2", 
196 				1 == getMockEmailService().immediateReminderEmailsSent("user2", document.getRouteHeaderId(), 
197 				KEWConstants.ACTION_REQUEST_COMPLETE_REQ));
198 		assertTrue("the responsible party that is delegating should not be notified",
199 				0 == getMockEmailService().immediateReminderEmailsSent("user1", document.getRouteHeaderId(), 
200 				KEWConstants.ACTION_REQUEST_COMPLETE_REQ));
201 
202 		getMockEmailService().resetReminderCounts();
203 
204 		// now if we requeue, nobody should get notified
205 		new DocumentRequeuerImpl().requeueDocument(document.getRouteHeaderId());
206 
207 		assertTrue("nobody should have been notified", 
208 				0 == getMockEmailService().immediateReminderEmailsSent("user2", document.getRouteHeaderId(), 
209 				KEWConstants.ACTION_REQUEST_COMPLETE_REQ));
210 		assertTrue("nobody should have been notified",
211 				0 == getMockEmailService().immediateReminderEmailsSent("user1", document.getRouteHeaderId(), 
212 				KEWConstants.ACTION_REQUEST_COMPLETE_REQ));
213 		
214 		getMockEmailService().resetReminderCounts();
215 	}
216 	
217     private MockEmailNotificationService getMockEmailService() {
218         return (MockEmailNotificationService)KEWServiceLocator.getActionListEmailService();
219     }
220 }