1 /**
2 * Copyright 2005-2014 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.mail;
17
18 import mocks.MockEmailNotificationService;
19 import mocks.MockEmailNotificationServiceImpl;
20 import org.junit.Test;
21 import org.kuali.rice.core.api.config.property.ConfigContext;
22 import org.kuali.rice.kew.api.KewApiServiceLocator;
23 import org.kuali.rice.kew.api.WorkflowDocument;
24 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
25 import org.kuali.rice.kew.api.action.ActionRequestType;
26 import org.kuali.rice.kew.api.preferences.Preferences;
27 import org.kuali.rice.kew.service.KEWServiceLocator;
28 import org.kuali.rice.kew.test.KEWTestCase;
29 import org.kuali.rice.kew.api.KewApiConstants;
30
31 import static org.junit.Assert.*;
32
33 public class EmailReminderLifecycleTest extends KEWTestCase {
34 protected final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(getClass());
35
36 private static final String DEFAULT_EMAIL_CRON_WEEKLY = "0 0 2 ? * 2";
37 private static final String DEFAULT_EMAIL_CRON_DAILY = "0 0 1 * * ?";
38
39 private EmailReminderLifecycle emailReminderLifecycle;
40
41 /**
42 * This method used to reset email sending to false for both daily and weekly reminders
43 *
44 * @see org.kuali.rice.test.RiceTestCase#tearDown()
45 */
46 @Override
47 public void tearDown() throws Exception {
48 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.DAILY_EMAIL_ACTIVE, "false");
49 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.WEEKLY_EMAIL_ACTIVE, "false");
50 super.tearDown();
51 }
52
53 @Test public void testDailyEmails() throws Exception {
54 // fire daily every 2 seconds
55 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.DAILY_EMAIL_CRON_EXPRESSION, "0/2 * * * * ?");
56 // turn daily on and weekly off
57 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.DAILY_EMAIL_ACTIVE, "true");
58 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.WEEKLY_EMAIL_ACTIVE, "false");
59
60 String ewestfalPrincipalId = getPrincipalIdForName("ewestfal");
61 String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
62
63 // setup ewestfal to recieve daily emails
64 Preferences prefs = KewApiServiceLocator.getPreferencesService().getPreferences(ewestfalPrincipalId);
65 Preferences.Builder builder = Preferences.Builder.create(prefs);
66 builder.setEmailNotification(KewApiConstants.DAILY);
67 KewApiServiceLocator.getPreferencesService().savePreferences(ewestfalPrincipalId, builder.build());
68
69 WorkflowDocument document = WorkflowDocumentFactory.createDocument(rkirkendPrincipalId, "TestDocumentType");
70 document.adHocToPrincipal(ActionRequestType.APPROVE, "", ewestfalPrincipalId, "", Boolean.TRUE);
71 document.route("");
72
73 document = WorkflowDocumentFactory.loadDocument(ewestfalPrincipalId, document.getDocumentId());
74 assertTrue(document.isApprovalRequested());
75
76 int emailsSent = getMockEmailService().immediateReminderEmailsSent("ewestfal", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_APPROVE_REQ);
77 assertEquals("ewestfal should have no emails.", 0, emailsSent);
78
79 // let's fire up the lifecycle
80 emailReminderLifecycle = new EmailReminderLifecycle();
81 LOG.info("testDailyEmails(): Starting EmailReminderLifeCycle");
82 emailReminderLifecycle.start();
83
84 // sleep for 10 seconds
85 Thread.sleep(10000);
86
87 // send daily reminder should have now been called
88 assertTrue("daily reminder should have been called.", getMockEmailService().wasDailyReminderSent());
89
90 LOG.info("testDailyEmails(): Stopping EmailReminderLifeCycle");
91 emailReminderLifecycle.stop();
92
93 // setting cron to empty so job will cease
94 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.DAILY_EMAIL_CRON_EXPRESSION, DEFAULT_EMAIL_CRON_DAILY);
95
96 // try restarting to verify rescheduling of tasks
97 emailReminderLifecycle.start();
98 emailReminderLifecycle.stop();
99 }
100
101 @Test public void testWeeklyEmails() throws Exception {
102 // fire daily every 2 seconds
103 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.WEEKLY_EMAIL_CRON_EXPRESSION, "0/2 * * * * ?");
104 // turn weekly on and daily off
105 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.WEEKLY_EMAIL_ACTIVE, "true");
106 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.DAILY_EMAIL_ACTIVE, "false");
107
108 String ewestfalPrincipalId = getPrincipalIdForName("ewestfal");
109 String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
110
111 // setup ewestfal to recieve weekly emails
112 Preferences prefs = KewApiServiceLocator.getPreferencesService().getPreferences(ewestfalPrincipalId);
113 Preferences.Builder builder = Preferences.Builder.create(prefs);
114 builder.setEmailNotification(KewApiConstants.WEEKLY);
115 KewApiServiceLocator.getPreferencesService().savePreferences(ewestfalPrincipalId, builder.build());
116
117 WorkflowDocument document = WorkflowDocumentFactory.createDocument(rkirkendPrincipalId, "TestDocumentType");
118 document.adHocToPrincipal(ActionRequestType.APPROVE, "", ewestfalPrincipalId, "", Boolean.TRUE);
119 document.route("");
120
121 document = WorkflowDocumentFactory.loadDocument(ewestfalPrincipalId, document.getDocumentId());
122 assertTrue(document.isApprovalRequested());
123
124 int emailsSent = getMockEmailService().immediateReminderEmailsSent("ewestfal", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_APPROVE_REQ);
125 assertEquals("ewestfal should have no emails.", 0, emailsSent);
126
127 // let's fire up the lifecycle
128 emailReminderLifecycle = new EmailReminderLifecycle();
129 LOG.info("testWeeklyEmails(): Starting EmailReminderLifeCycle");
130 emailReminderLifecycle.start();
131
132 assertTrue("EmailReminderLifecycle should have been started", emailReminderLifecycle.isStarted());
133
134 // sleep for 10 seconds
135 Thread.sleep(10000);
136
137 // send weekly reminder should have now been called
138 assertTrue("weekly reminder should have been called.", getMockEmailService().wasWeeklyReminderSent());
139
140 LOG.info("testWeeklyEmails(): Stopping EmailReminderLifeCycle");
141 emailReminderLifecycle.stop();
142
143 // setting cron to empty so job will cease
144 ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.WEEKLY_EMAIL_CRON_EXPRESSION, DEFAULT_EMAIL_CRON_WEEKLY);
145
146 // try restarting to verify rescheduling of tasks
147 emailReminderLifecycle.start();
148 emailReminderLifecycle.stop();
149 }
150
151 // /**
152 // * Verify that no more messages are put in the queue if there are already weekly and daily reminders in the
153 // * queue
154 // * @throws Exception
155 // */
156 // @Test
157 // public void testEmailMessagesInQueue() throws Exception {
158 //
159 // setUpConfigForEmail();
160 //
161 // PersistedMessageBO dailyMessage = getMockDailyMessage();
162 // PersistedMessageBO weeklyMessage = getMockWeeklyMessage();
163 // KEWServiceLocator.getRouteQueueService().save(dailyMessage);
164 // KEWServiceLocator.getRouteQueueService().save(weeklyMessage);
165 //
166 // Collection messages = KEWServiceLocator.getRouteQueueService().findAll();
167 // assertEquals("Should only be 2 items present in queue", 2, messages.size());
168 //
169 // emailReminderLifecycle.start();
170 //
171 // messages = KEWServiceLocator.getRouteQueueService().findAll();
172 // assertEquals("Should only be 2 items present in queue", 2, messages.size());
173 //
174 // PersistedMessageBO fetchedDaily = null;
175 // PersistedMessageBO fetchedWeekly = null;
176 //
177 // for (Iterator iter = messages.iterator(); iter.hasNext();) {
178 // PersistedMessageBO fetchedMessage = (PersistedMessageBO) iter.next();
179 // if (fetchedMessage.getMethodName().equals("sendDailyReminder")) {
180 // fetchedDaily = fetchedMessage;
181 // } else {
182 // fetchedWeekly = fetchedMessage;
183 // }
184 // }
185 // assertEquals("Daily message was re-inserted or removed when it should have been allowed to stay in queue for later processing", dailyMessage.getRouteQueueId(), fetchedDaily.getRouteQueueId());
186 // assertEquals("Weekly message was re-inserted or removed when it should have been allowed to stay in queue for later processing", weeklyMessage.getRouteQueueId(), fetchedWeekly.getRouteQueueId());
187 // assertTrue("Lifecycle should report itself as started", emailReminderLifecycle.isStarted());
188 // }
189 //
190 // /**
191 // * If only a daily is in the queue then the other reminder should be put in the queue
192 // *
193 // * @throws Exception
194 // */
195 // @Test public void testOnlyDailyReminderInQueue() throws Exception {
196 //
197 // setUpConfigForEmail();
198 //
199 // PersistedMessageBO dailyMessage = getMockDailyMessage();
200 // KEWServiceLocator.getRouteQueueService().save(dailyMessage);
201 //
202 // Collection messages = KEWServiceLocator.getRouteQueueService().findAll();
203 // assertEquals("Should only be 1 items present in queue", 1, messages.size());
204 //
205 // emailReminderLifecycle.start();
206 //
207 // messages = KEWServiceLocator.getRouteQueueService().findAll();
208 // assertEquals("Should only be 2 items present in queue", 2, messages.size());
209 //
210 // PersistedMessageBO fetchedDaily = null;
211 // PersistedMessageBO fetchedWeekly = null;
212 //
213 // for (Iterator iter = messages.iterator(); iter.hasNext();) {
214 // PersistedMessageBO fetchedMessage = (PersistedMessageBO) iter.next();
215 // if (fetchedMessage.getMethodName().equals("sendDailyReminder")) {
216 // fetchedDaily = fetchedMessage;
217 // } else {
218 // fetchedWeekly = fetchedMessage;
219 // }
220 // }
221 // assertEquals("Daily message was re-inserted or removed when it should have been allowed to stay in queue for later processing", dailyMessage.getRouteQueueId(), fetchedDaily.getRouteQueueId());
222 // assertTrue(fetchedWeekly != null);
223 // assertTrue("Lifecycle should report itself as started", emailReminderLifecycle.isStarted());
224 // }
225 //
226 // /**
227 // * If only a weekly reminder is in the queue then the other reminder should be put in the queue
228 // *
229 // * @throws Exception
230 // */
231 // @Test public void testOnlyWeeklyReminderInQueue() throws Exception {
232 //
233 // setUpConfigForEmail();
234 //
235 // PersistedMessageBO weeklyMessage = getMockWeeklyMessage();
236 // KEWServiceLocator.getRouteQueueService().save(weeklyMessage);
237 //
238 // Collection messages = KEWServiceLocator.getRouteQueueService().findAll();
239 // assertEquals("Should only be 1 items present in queue", 1, messages.size());
240 //
241 // emailReminderLifecycle.start();
242 //
243 // messages = KEWServiceLocator.getRouteQueueService().findAll();
244 // assertEquals("Should only be 2 items present in queue", 2, messages.size());
245 //
246 // PersistedMessageBO fetchedDaily = null;
247 // PersistedMessageBO fetchedWeekly = null;
248 //
249 // for (Iterator iter = messages.iterator(); iter.hasNext();) {
250 // PersistedMessageBO fetchedMessage = (PersistedMessageBO) iter.next();
251 // if (fetchedMessage.getMethodName().equals("sendDailyReminder")) {
252 // fetchedDaily = fetchedMessage;
253 // } else {
254 // fetchedWeekly = fetchedMessage;
255 // }
256 // }
257 // assertEquals("Weekly message was re-inserted or removed when it should have been allowed to stay in queue for later processing", weeklyMessage.getRouteQueueId(), fetchedWeekly.getRouteQueueId());
258 // assertTrue("Daily message not sent", fetchedDaily != null);
259 // assertTrue("Lifecycle should report itself as started", emailReminderLifecycle.isStarted());
260 //
261 // }
262 //
263 // /**
264 // * Tests that email reminder calls are sent to the queue when none are present. New messages should
265 // * be set for the proper delay.
266 // *
267 // * @throws Exception
268 // */
269 // @Test public void testNoEmailRemindersInQueue() throws Exception {
270 //
271 // setUpConfigForEmail();
272 //
273 // emailReminderLifecycle.start();
274 // Collection messages = KEWServiceLocator.getRouteQueueService().findAll();
275 // assertEquals("Should only be 2 items present in queue", 2, messages.size());
276 // PersistedMessageBO fetchedDaily = null;
277 // PersistedMessageBO fetchedWeekly = null;
278 //
279 // for (Iterator iter = messages.iterator(); iter.hasNext();) {
280 // PersistedMessageBO fetchedMessage = (PersistedMessageBO) iter.next();
281 // if (fetchedMessage.getMethodName().equals("sendDailyReminder")) {
282 // fetchedDaily = fetchedMessage;
283 // } else {
284 // fetchedWeekly = fetchedMessage;
285 // }
286 // }
287 // assertNotNull("No daily message sent", fetchedDaily);
288 // assertNotNull("No weekly message sent", fetchedWeekly);
289 //
290 // assertTrue("Daily message not sent", fetchedDaily != null);
291 // assertTrue("Weekly message not sent", fetchedWeekly != null);
292 // assertTrue("Lifecycle should report itself as started", emailReminderLifecycle.isStarted());
293 //
294 //
295 // AsynchronousCall methodCall = (AsynchronousCall)KSBServiceLocator.getMessageHelper().deserializeObject(fetchedWeekly.getPayload());
296 // assertEquals("Weekly email not on a weekly delay", EmailReminderLifecycle.WEEKLY_DELAY, methodCall.getRepeatCallTimeIncrement().longValue());
297 //
298 // methodCall = (AsynchronousCall)KSBServiceLocator.getMessageHelper().deserializeObject(fetchedDaily.getPayload());
299 // assertEquals("Weekly email not on a weekly delay", EmailReminderLifecycle.DAILY_DELAY, methodCall.getRepeatCallTimeIncrement().longValue());
300 // }
301 //
302 // /**
303 // * the lifecycle should not blow up if this ip is the designated emailer but no email options are sent. it should
304 // * do nothing and report started.
305 // *
306 // * @throws Exception
307 // */
308 // @Test public void testNoEmailDatesInConfig() throws Exception {
309 // KEWServiceLocator.getApplicationConstantsService().save(new ApplicationConstant(KewApiConstants.APP_CONST_EMAIL_FIRST_SEND_IP_KEY, Utilities.getIpNumber()));
310 //
311 // Config config = ConfigContext.getCurrentContextConfig();
312 // config.getProperties().remove(Config.FIRST_DAILY_EMAIL_DELIVERY_DATE);
313 // config.getProperties().remove(Config.FIRST_WEEKLY_EMAIL_DELIVERY_DATE);
314 // emailReminderLifecycle.start();
315 // Collection messages = KEWServiceLocator.getRouteQueueService().findAll();
316 // assertEquals("Should not be items present in queue", 0, messages.size());
317 //
318 // assertTrue("Lifecycle should report itself as started", emailReminderLifecycle.isStarted());
319 // emailReminderLifecycle.stop();
320 // assertFalse("Lifecycle should not report itself as started", emailReminderLifecycle.isStarted());
321 // }
322 //
323 // /**
324 // * Keep the threadpool on and synchronous. Start the lifecycle and verify that
325 // * the action list email service got called.
326 // * @throws Exception
327 // */
328 // @Test public void testActionListEmailServiceBeingCalled() throws Exception {
329 // KEWServiceLocator.getApplicationConstantsService().save(new ApplicationConstant(KewApiConstants.APP_CONST_EMAIL_FIRST_SEND_IP_KEY, Utilities.getIpNumber()));
330 // Config config = ConfigContext.getCurrentContextConfig();
331 // config.overrideProperty(Config.FIRST_DAILY_EMAIL_DELIVERY_DATE, DAILY_REMINDER_DATE);
332 // config.overrideProperty(Config.FIRST_WEEKLY_EMAIL_DELIVERY_DATE, WEEKLY_REMINDER_DATE);
333 // emailReminderLifecycle.start();
334 // assertTrue("Send daily not called on email notification service", MockEmailNotificationServiceImpl.SEND_DAILY_REMINDER_CALLED);
335 // assertTrue("Send weekly not called on email notification service", MockEmailNotificationServiceImpl.SEND_WEEKLY_REMINDER_CALLED);
336 // }
337 //
338 // private void setUpConfigForEmail() throws Exception {
339 // KEWServiceLocator.getApplicationConstantsService().save(new ApplicationConstant(KewApiConstants.APP_CONST_EMAIL_FIRST_SEND_IP_KEY, Utilities.getIpNumber()));
340 //
341 // Config config = ConfigContext.getCurrentContextConfig();
342 // config.overrideProperty(Config.FIRST_DAILY_EMAIL_DELIVERY_DATE, DAILY_REMINDER_DATE);
343 // config.overrideProperty(Config.FIRST_WEEKLY_EMAIL_DELIVERY_DATE, WEEKLY_REMINDER_DATE);
344 //
345 // }
346 //
347 //
348 // private PersistedMessageBO getMockDailyMessage() throws Exception {
349 // PersistedMessageBO dailyMessage = new PersistedMessageBO();
350 // dailyMessage.setServiceName(emailReminderLifecycle.getEmailServiceName().toString());
351 // dailyMessage.setMethodName("sendDailyReminder");
352 // dailyMessage.setQueueDate(new Timestamp(System.currentTimeMillis()));
353 // dailyMessage.setQueuePriority(1);
354 // dailyMessage.setQueueStatus("Q");
355 // dailyMessage.setRetryCount(1);
356 // dailyMessage.setIpNumber(Utilities.getIpNumber());
357 // dailyMessage.setApplicationId("KEW");
358 // dailyMessage.setPayload(KSBServiceLocator.getMessageHelper().serializeObject("payload"));
359 // return dailyMessage;
360 // }
361 //
362 // private PersistedMessageBO getMockWeeklyMessage() throws Exception {
363 // PersistedMessageBO weeklyMessage = new PersistedMessageBO();
364 // weeklyMessage.setServiceName(emailReminderLifecycle.getEmailServiceName().toString());
365 // weeklyMessage.setQueueDate(new Timestamp(System.currentTimeMillis()));
366 // weeklyMessage.setMethodName("sendWeeklyReminder");
367 // weeklyMessage.setQueuePriority(1);
368 // weeklyMessage.setQueueStatus("Q");
369 // weeklyMessage.setRetryCount(1);
370 // weeklyMessage.setIpNumber(Utilities.getIpNumber());
371 // weeklyMessage.setApplicationId("KEW");
372 // weeklyMessage.setPayload(KSBServiceLocator.getMessageHelper().serializeObject("payload"));
373 // return weeklyMessage;
374 // }
375
376 private MockEmailNotificationService getMockEmailService() {
377 return (MockEmailNotificationService)KEWServiceLocator.getActionListEmailService();
378 }
379
380 }