/** * Copyright (c) 2012 Todoroo Inc * * See the file "LICENSE" for the full license governing this code. */ package com.todoroo.astrid.reminders; import java.util.Date; import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.reminders.ReminderService.AlarmScheduler; import com.todoroo.astrid.test.DatabaseTestCase; import com.todoroo.astrid.utility.AstridPreferences; public class ReminderServiceTests extends DatabaseTestCase { ReminderService service; AlarmScheduler original; @Autowired TaskDao taskDao; @Override protected void setUp() throws Exception { super.setUp(); service = ReminderService.getInstance(); original = service.getScheduler(); AstridPreferences.setPreferenceDefaults(); } @Override protected void tearDown() throws Exception { super.tearDown(); service.setScheduler(original); } /** tests with no alarms */ public void testNoReminders() { service.setScheduler(new NoAlarmExpected()); Task task = new Task(); task.setValue(Task.TITLE, "water"); task.setValue(Task.REMINDER_FLAGS, 0); task.setValue(Task.REMINDER_PERIOD, 0L); taskDao.save(task); service.scheduleAlarm(task); } /** tests with due date */ public void testDueDates() { service.setScheduler(new AlarmExpected() { @Override public void createAlarm(Task task, long time, int type) { if (time == ReminderService.NO_ALARM) return; super.createAlarm(task, time, type); assertEquals((long)task.getValue(Task.DUE_DATE), time); assertEquals(type, ReminderService.TYPE_DUE); } }); // test due date in the past final Task task = new Task(); task.setValue(Task.TITLE, "water"); task.setValue(Task.DUE_DATE, DateUtilities.now() - DateUtilities.ONE_DAY); task.setValue(Task.REMINDER_FLAGS, Task.NOTIFY_AT_DEADLINE); taskDao.save(task); // test due date in the future task.setValue(Task.DUE_DATE, DateUtilities.now() + DateUtilities.ONE_DAY); taskDao.save(task); assertTrue(((AlarmExpected)service.getScheduler()).alarmCreated); } /** tests with random */ public void testRandom() { // test random final Task task = new Task(); task.setValue(Task.TITLE, "water"); task.setValue(Task.REMINDER_PERIOD, DateUtilities.ONE_WEEK); service.setScheduler(new AlarmExpected() { @Override public void createAlarm(Task task, long time, int type) { if (time == ReminderService.NO_ALARM) return; super.createAlarm(task, time, type); assertTrue(time > DateUtilities.now()); assertTrue(time < DateUtilities.now() + 1.2 * DateUtilities.ONE_WEEK); assertEquals(type, ReminderService.TYPE_RANDOM); } }); taskDao.save(task); assertTrue(((AlarmExpected)service.getScheduler()).alarmCreated); } /** tests with overdue */ public void testOverdue() { // test due date in the future service.setScheduler(new AlarmExpected() { @Override public void createAlarm(Task task, long time, int type) { if (time == ReminderService.NO_ALARM) return; super.createAlarm(task, time, type); assertTrue(time > task.getValue(Task.DUE_DATE)); assertTrue(time < task.getValue(Task.DUE_DATE) + DateUtilities.ONE_DAY); assertEquals(type, ReminderService.TYPE_OVERDUE); } }); final Task task = new Task(); task.setValue(Task.TITLE, "water"); task.setValue(Task.DUE_DATE, DateUtilities.now() + DateUtilities.ONE_DAY); task.setValue(Task.REMINDER_FLAGS, Task.NOTIFY_AFTER_DEADLINE); taskDao.save(task); // test due date in the past task.setValue(Task.DUE_DATE, DateUtilities.now() - DateUtilities.ONE_DAY); service.setScheduler(new AlarmExpected() { @Override public void createAlarm(Task task, long time, int type) { if (time == ReminderService.NO_ALARM) return; super.createAlarm(task, time, type); assertTrue(time > DateUtilities.now() - 1000L); assertTrue(time < DateUtilities.now() + 2 * DateUtilities.ONE_DAY); assertEquals(type, ReminderService.TYPE_OVERDUE); } }); taskDao.save(task); assertTrue(((AlarmExpected)service.getScheduler()).alarmCreated); // test due date in the past, but recently notified task.setValue(Task.REMINDER_LAST, DateUtilities.now()); service.setScheduler(new AlarmExpected() { @Override public void createAlarm(Task task, long time, int type) { if (time == ReminderService.NO_ALARM) return; super.createAlarm(task, time, type); assertTrue(time > DateUtilities.now() + DateUtilities.ONE_HOUR); assertTrue(time < DateUtilities.now() + DateUtilities.ONE_DAY); assertEquals(type, ReminderService.TYPE_OVERDUE); } }); taskDao.save(task); assertTrue(((AlarmExpected)service.getScheduler()).alarmCreated); } /** tests with multiple */ public void testMultipleReminders() { // test due date in the future, enable random final Task task = new Task(); task.setValue(Task.TITLE, "water"); task.setValue(Task.DUE_DATE, DateUtilities.now() + DateUtilities.ONE_WEEK); task.setValue(Task.REMINDER_FLAGS, Task.NOTIFY_AT_DEADLINE); task.setValue(Task.REMINDER_PERIOD, DateUtilities.ONE_HOUR); service.setScheduler(new AlarmExpected() { @Override public void createAlarm(Task task, long time, int type) { if (time == ReminderService.NO_ALARM) return; super.createAlarm(task, time, type); assertTrue(time > DateUtilities.now()); assertTrue(time < DateUtilities.now() + DateUtilities.ONE_DAY); assertEquals(type, ReminderService.TYPE_RANDOM); } }); taskDao.save(task); assertTrue(((AlarmExpected)service.getScheduler()).alarmCreated); // now set the due date in the past task.setValue(Task.DUE_DATE, DateUtilities.now() - DateUtilities.ONE_WEEK); ((AlarmExpected)service.getScheduler()).alarmCreated = false; service.scheduleAlarm(task); assertTrue(((AlarmExpected)service.getScheduler()).alarmCreated); // now set the due date before the random task.setValue(Task.DUE_DATE, DateUtilities.now() + DateUtilities.ONE_HOUR); service.setScheduler(new AlarmExpected() { @Override public void createAlarm(Task task, long time, int type) { if (time == ReminderService.NO_ALARM) return; super.createAlarm(task, time, type); assertEquals((long)task.getValue(Task.DUE_DATE), time); assertEquals(type, ReminderService.TYPE_DUE); } }); taskDao.save(task); assertTrue(((AlarmExpected)service.getScheduler()).alarmCreated); } /** tests with snooze */ public void testSnoozeReminders() { // test due date and snooze in the future final Task task = new Task(); task.setValue(Task.TITLE, "spacemen"); task.setValue(Task.DUE_DATE, DateUtilities.now() + 5000L); task.setValue(Task.REMINDER_FLAGS, Task.NOTIFY_AT_DEADLINE); task.setValue(Task.REMINDER_SNOOZE, DateUtilities.now() + DateUtilities.ONE_WEEK); service.setScheduler(new AlarmExpected() { @Override public void createAlarm(Task task, long time, int type) { if (time == ReminderService.NO_ALARM) return; super.createAlarm(task, time, type); assertTrue(time > DateUtilities.now() + DateUtilities.ONE_WEEK - 1000L); assertTrue(time < DateUtilities.now() + DateUtilities.ONE_WEEK + 1000L); assertEquals(type, ReminderService.TYPE_SNOOZE); } }); taskDao.save(task); assertTrue(((AlarmExpected)service.getScheduler()).alarmCreated); // snooze in the past task.setValue(Task.REMINDER_SNOOZE, DateUtilities.now() - DateUtilities.ONE_WEEK); service.setScheduler(new AlarmExpected() { @Override public void createAlarm(Task task, long time, int type) { if (time == ReminderService.NO_ALARM) return; super.createAlarm(task, time, type); assertTrue(time > DateUtilities.now() - 1000L); assertTrue(time < DateUtilities.now() + 5000L); assertEquals(type, ReminderService.TYPE_DUE); } }); taskDao.save(task); assertTrue(((AlarmExpected)service.getScheduler()).alarmCreated); } // --- helper classes public class NoAlarmExpected implements AlarmScheduler { public void createAlarm(Task task, long time, int type) { if(time == 0 || time == Long.MAX_VALUE) return; fail("created alarm, no alarm expected (" + type + ": " + new Date(time)); } } public class AlarmExpected implements AlarmScheduler { public boolean alarmCreated = false; public void createAlarm(Task task, long time, int type) { alarmCreated = true; } } }