package de.geeksfactory.opacclient.reminder; import android.annotation.SuppressLint; import android.app.AlarmManager; import android.app.NotificationManager; import android.content.Context; import android.content.SharedPreferences; import android.support.annotation.NonNull; import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.LocalDate; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentMatcher; import java.util.ArrayList; import de.geeksfactory.opacclient.OpacClient; import de.geeksfactory.opacclient.objects.LentItem; import de.geeksfactory.opacclient.storage.AccountDataSource; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; public class ReminderHelperTest { private ReminderHelper rh; private OpacClient app; private SharedPreferences sp; private AccountDataSource data; private NotificationManager notificationManager; private AlarmManager alarmManager; @Before public void setUp() throws Exception { app = mock(OpacClient.class); sp = mock(SharedPreferences.class); data = mock(AccountDataSource.class); rh = new ReminderHelper(app, sp, data); notificationManager = mock(NotificationManager.class); when(app.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager); alarmManager = mock(AlarmManager.class); when(app.getSystemService(Context.ALARM_SERVICE)).thenReturn(alarmManager); when(sp.getString(eq("notification_warning"), anyString())).thenReturn("3"); } @Test public void shouldOnlyResetNotifiedOnReminderOff() throws Exception { setNotificationsEnabled(false); rh.generateAlarms(); verify(data, times(1)).resetNotifiedOnAllAlarams(); verifyNoMoreInteractions(data); } @Test public void shouldNotCreateAlarmsWithoutLentItems() throws Exception { setNotificationsEnabled(true); when(data.getAllLentItems()).thenReturn(new ArrayList<LentItem>()); rh.generateAlarms(); verify(data, never()) .addAlarm(any(LocalDate.class), any(long[].class), any(DateTime.class)); } @Test public void shouldCreateAlarmForLentItem() throws Exception { setNotificationsEnabled(true); LocalDate date = LocalDate.now(); long dbId = 1L; stubLentItem(date, dbId); rh.generateAlarms(); verify(data, times(1)).addAlarm(date, new long[]{dbId}, date.toDateTimeAtStartOfDay().minus(Days.days(3))); } @Test public void shouldRemoveAlarmForRemovedItem() throws Exception { setNotificationsEnabled(true); when(data.getAllLentItems()).thenReturn(new ArrayList<LentItem>()); Alarm alarm = stubAlarm(); rh.generateAlarms(); verify(data, times(1)).removeAlarm(alarm); } @Test public void shouldUpdateAlarmForChangedItemIds() throws Exception { setNotificationsEnabled(true); stubLentItem(LocalDate.now(), 2L); stubAlarm(); rh.generateAlarms(); verify(data, times(1)).updateAlarm(argThat(new ArgumentMatcher<Alarm>() { @Override public boolean matches(Object argument) { Alarm alarm = (Alarm) argument; return alarm.media.length == 1 && alarm.media[0] == 2L; } })); } @SuppressLint("CommitPrefEdits") @Test public void shouldUpdateWarningPeriodFromMillisToDays() { SharedPreferences.Editor editor = mock(SharedPreferences.Editor.class); when(sp.getString(eq("notification_warning"), anyString())).thenReturn("259200000"); when(data.getAllLentItems()).thenReturn(new ArrayList<LentItem>()); when(editor.putString(anyString(), anyString())).thenReturn(editor); when(sp.edit()).thenReturn(editor); rh.generateAlarms(); verify(editor).putString("notification_warning", "3"); verify(editor).apply(); verifyNoMoreInteractions(editor); } private void setNotificationsEnabled(boolean on) { when(sp.getBoolean(eq("notification_service"), anyBoolean())).thenReturn(on); } private LentItem stubLentItem(LocalDate date, long dbId) { ArrayList<LentItem> lentItems = new ArrayList<>(); LentItem item = new LentItem(); item.setDeadline(date); item.setDbId(dbId); lentItems.add(item); when(data.getAllLentItems()).thenReturn(lentItems); return item; } @NonNull private Alarm stubAlarm() { ArrayList<Alarm> alarms = new ArrayList<>(); Alarm alarm = new Alarm(); alarm.deadline = LocalDate.now(); alarm.finished = false; alarm.notified = false; alarm.id = 1L; alarm.media = new long[]{1L}; alarm.notificationTime = DateTime.now(); alarms.add(alarm); when(data.getAllAlarms()).thenReturn(alarms); when(data.getAlarmByDeadline(alarm.deadline)).thenReturn(alarm); return alarm; } }