001    /**
002     * Copyright 2005-2013 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.mail;
017    
018    import mocks.MockEmailNotificationService;
019    import mocks.MockEmailNotificationServiceImpl;
020    import org.junit.Test;
021    import org.kuali.rice.core.api.config.property.ConfigContext;
022    import org.kuali.rice.kew.api.KewApiServiceLocator;
023    import org.kuali.rice.kew.api.WorkflowDocument;
024    import org.kuali.rice.kew.api.WorkflowDocumentFactory;
025    import org.kuali.rice.kew.api.action.ActionRequestType;
026    import org.kuali.rice.kew.api.preferences.Preferences;
027    import org.kuali.rice.kew.service.KEWServiceLocator;
028    import org.kuali.rice.kew.test.KEWTestCase;
029    import org.kuali.rice.kew.api.KewApiConstants;
030    
031    import static org.junit.Assert.*;
032    
033    public class EmailReminderLifecycleTest extends KEWTestCase {
034        protected final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(getClass());
035    
036        private static final String DEFAULT_EMAIL_CRON_WEEKLY = "0 0 2 ? * 2";
037        private static final String DEFAULT_EMAIL_CRON_DAILY = "0 0 1 * * ?";
038    
039            private EmailReminderLifecycle emailReminderLifecycle;
040    
041            /**
042             * This method used to reset email sending to false for both daily and weekly reminders
043             *
044             * @see org.kuali.rice.test.RiceTestCase#tearDown()
045             */
046            @Override
047            public void tearDown() throws Exception {
048            ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.DAILY_EMAIL_ACTIVE, "false");
049            ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.WEEKLY_EMAIL_ACTIVE, "false");
050                super.tearDown();
051            }
052    
053            @Test public void testDailyEmails() throws Exception {
054                    // fire daily every 2 seconds
055                    ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.DAILY_EMAIL_CRON_EXPRESSION, "0/2 * * * * ?");
056                    // turn daily on and weekly off
057                    ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.DAILY_EMAIL_ACTIVE, "true");
058                    ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.WEEKLY_EMAIL_ACTIVE, "false");
059    
060                    String ewestfalPrincipalId = getPrincipalIdForName("ewestfal");
061                    String rkirkendPrincipalId = getPrincipalIdForName("rkirkend");
062                    
063                    // setup ewestfal to recieve daily emails
064                    Preferences prefs = KewApiServiceLocator.getPreferencesService().getPreferences(ewestfalPrincipalId);
065            Preferences.Builder builder = Preferences.Builder.create(prefs);
066                    builder.setEmailNotification(KewApiConstants.DAILY);
067                    KewApiServiceLocator.getPreferencesService().savePreferences(ewestfalPrincipalId, builder.build());
068    
069                    WorkflowDocument document = WorkflowDocumentFactory.createDocument(rkirkendPrincipalId, "TestDocumentType");
070                    document.adHocToPrincipal(ActionRequestType.APPROVE, "", ewestfalPrincipalId, "", Boolean.TRUE);
071                    document.route("");
072    
073                    document = WorkflowDocumentFactory.loadDocument(ewestfalPrincipalId, document.getDocumentId());
074                    assertTrue(document.isApprovalRequested());
075    
076                    int emailsSent = getMockEmailService().immediateReminderEmailsSent("ewestfal", document.getDocumentId(), KewApiConstants.ACTION_REQUEST_APPROVE_REQ);
077                    assertEquals("ewestfal should have no emails.", 0, emailsSent);
078    
079                    // let's fire up the lifecycle
080                    emailReminderLifecycle = new EmailReminderLifecycle();
081                    LOG.info("testDailyEmails(): Starting EmailReminderLifeCycle");
082                    emailReminderLifecycle.start();
083    
084                    // sleep for 10 seconds
085                    Thread.sleep(10000);
086    
087                    // send daily reminder should have now been called
088                    assertTrue("daily reminder should have been called.", getMockEmailService().wasDailyReminderSent());
089    
090                    LOG.info("testDailyEmails(): Stopping EmailReminderLifeCycle");
091                    emailReminderLifecycle.stop();
092    
093                    // setting cron to empty so job will cease
094                    ConfigContext.getCurrentContextConfig().putProperty(KewApiConstants.DAILY_EMAIL_CRON_EXPRESSION, DEFAULT_EMAIL_CRON_DAILY);
095    
096                    // try restarting to verify rescheduling of tasks
097                    emailReminderLifecycle.start();
098                    emailReminderLifecycle.stop();
099            }
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    }