package ru.orangesoftware.financisto2.test.service;
import android.content.Context;
import android.test.AndroidTestCase;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import ru.orangesoftware.financisto2.db.DatabaseAdapter;
import ru.orangesoftware.financisto2.model.RestoredTransaction;
import ru.orangesoftware.financisto2.model.TransactionInfo;
import ru.orangesoftware.financisto2.service.RecurrenceScheduler;
import ru.orangesoftware.financisto2.test.builders.DateTime;
public class RecurrenceSchedulerTest extends AndroidTestCase {
private static final long ONE_DAY_MS = 1*24*60*60*1000L;
public void testShouldRestoreMissedOneTimeSchedule() throws Exception {
assertRestored(Arrays.asList(yesterday()), System.currentTimeMillis(), 1);
}
public void testShouldRestoreMissedRecurrenceSchedule() throws Exception {
assertRestored(Arrays.asList(everyDay()), fifthOfOctober(2010), 2,2,2,2,2);
}
public void test_should_not_restore_missed_schedule_the_same_day() throws Exception {
TransactionInfo t = everyDayAtNoon();
t.lastRecurrence = DateTime.date(2010, 10, 2).atNoon().asLong();
assertRestored(Arrays.asList(t), DateTime.date(2010, 10, 2).at(13, 0, 0, 0).asLong());
}
public void testShouldRestoreMissedSchedules() throws Exception {
assertRestored(Arrays.asList(on4thOfOctober(2010), everyDay(), every2Days()), fifthOfOctober(2010), 1,2,2,2,2,2,3,3);
}
public void testShouldRestoreNoMoreThan1000MissedSchedules() throws Exception {
assertRestoredSize(Arrays.asList(everyDay()), fifthOfOctober(2013), 1000);
}
private long fifthOfOctober(int year) {
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, 5);
c.set(Calendar.MONTH, Calendar.OCTOBER);
c.set(Calendar.YEAR, year);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
return c.getTimeInMillis();
}
private void assertRestored(List<TransactionInfo> schedules, long now, long...ids) {
List<RestoredTransaction> restored = assertRestoredSize(schedules, now, ids.length);
for (int i=0; i<ids.length; i++) {
assertEquals(ids[i], restored.get(i).transactionId);
}
}
private List<RestoredTransaction> assertRestoredSize(List<TransactionInfo> schedules, long now, int count) {
// given
ArrayList<TransactionInfo> scheduled = new ArrayList<TransactionInfo>(schedules);
RecurrenceScheduler scheduler = new RecurrenceScheduler();
scheduler.db = new FakeDatabaseAdapter(getContext(), scheduled);
// when
List<RestoredTransaction> missed = scheduler.getMissedSchedules(now);
// then
assertNotNull(missed);
assertEquals(count, missed.size());
return missed;
}
private TransactionInfo yesterday() {
TransactionInfo t = new TransactionInfo();
t.id = 1;
t.recurrence = null;
t.dateTime = System.currentTimeMillis()-ONE_DAY_MS;
return t;
}
private TransactionInfo on4thOfOctober(int year) {
TransactionInfo t = new TransactionInfo();
t.id = 1;
t.recurrence = null;
t.dateTime = fifthOfOctober(year)-ONE_DAY_MS;
return t;
}
private TransactionInfo everyDay() {
TransactionInfo t = new TransactionInfo();
t.id = 2;
t.recurrence = "2010-10-01T00:00:00~DAILY:interval@1#~INDEFINETELY:null";
t.lastRecurrence = 1;
return t;
}
private TransactionInfo everyDayAtNoon() {
TransactionInfo t = new TransactionInfo();
t.id = 2;
t.recurrence = "2010-10-01T12:00:00~DAILY:interval@1#~INDEFINETELY:null";
t.lastRecurrence = 1;
return t;
}
private TransactionInfo every2Days() {
TransactionInfo t = new TransactionInfo();
t.id = 3;
t.recurrence = "2010-10-01T00:10:00~DAILY:interval@2#~EXACTLY_TIMES:count@3#";
t.lastRecurrence = 1;
return t;
}
static class FakeDatabaseAdapter extends DatabaseAdapter {
private final ArrayList<TransactionInfo> scheduledTransactions;
public FakeDatabaseAdapter(Context context, ArrayList<TransactionInfo> scheduledTransactions) {
super(context);
this.scheduledTransactions = scheduledTransactions;
}
@Override
public ArrayList<TransactionInfo> getAllScheduledTransactions() {
return scheduledTransactions;
}
}
}