diff --git a/Habitica/build.gradle b/Habitica/build.gradle index dd8a507d7..6d2d57715 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -128,8 +128,11 @@ dependencies { exclude module: 'bolts-android' } //Tests + compile 'com.android.support:appcompat-v7:23.0' + testCompile "junit:junit:4.10" + testCompile "org.assertj:assertj-core:1.7.0" testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' - testCompile 'org.robolectric:robolectric:3.0' + testCompile "org.robolectric:robolectric:3.2-SNAPSHOT" testCompile 'org.robolectric:shadows-multidex:3.0' testCompile "org.robolectric:shadows-support-v4:3.0" testCompile "org.mockito:mockito-core:1.10.19" diff --git a/Habitica/google-services.json b/Habitica/google-services.json deleted file mode 100644 index 9087babbb..000000000 --- a/Habitica/google-services.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "project_info": { - "project_number": "726830572661", - "firebase_url": "https://habitica-android.firebaseio.com", - "project_id": "habitica-android", - "storage_bucket": "habitica-android.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:726830572661:android:d2e86a80d3b5f4f7", - "android_client_info": { - "package_name": "com.habitrpg.android.habitica" - } - }, - "oauth_client": [ - { - "client_id": "726830572661-e0bp1cplmf3v2sfl7e7goog768b7dv7b.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyDbtO8iErLD14Gk42Gg48fijX1mzfPKzS8" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:726830572661:android:ffd6914ad1a696e4", - "android_client_info": { - "package_name": "com.habitrpg.android.habitica.debug" - } - }, - "oauth_client": [ - { - "client_id": "726830572661-e0bp1cplmf3v2sfl7e7goog768b7dv7b.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyDbtO8iErLD14Gk42Gg48fijX1mzfPKzS8" - } - ], - "services": { - "analytics_service": { - "status": 1 - }, - "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/Habitica/project.properties b/Habitica/project.properties index 4e8c167ac..8e9414690 100644 --- a/Habitica/project.properties +++ b/Habitica/project.properties @@ -12,4 +12,4 @@ # Project target. target=android-17 - +android.library.reference.1=../app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/21.0.0 diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/events/ReminderDeleteEvent.java b/Habitica/src/main/java/com/habitrpg/android/habitica/events/ReminderDeleteEvent.java new file mode 100644 index 000000000..3549e757e --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/events/ReminderDeleteEvent.java @@ -0,0 +1,10 @@ +package com.habitrpg.android.habitica.events; + +import com.magicmicky.habitrpgwrapper.lib.models.tasks.RemindersItem; + +/** + * Created by keithholliday on 7/16/16. + */ +public class ReminderDeleteEvent { + public RemindersItem reminder; +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/events/TaskDeleteEvent.java b/Habitica/src/main/java/com/habitrpg/android/habitica/events/TaskDeleteEvent.java new file mode 100644 index 000000000..0dcbd8868 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/events/TaskDeleteEvent.java @@ -0,0 +1,10 @@ +package com.habitrpg.android.habitica.events; + +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; + +/** + * Created by keithholliday on 7/18/16. + */ +public class TaskDeleteEvent { + public Task task; +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemindersManager.java b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemindersManager.java index 0ff869de7..0db3124d5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemindersManager.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemindersManager.java @@ -9,6 +9,7 @@ import android.widget.DatePicker; import android.widget.EditText; import android.widget.TimePicker; +import com.crashlytics.android.Crashlytics; import com.habitrpg.android.habitica.R; import com.magicmicky.habitrpgwrapper.lib.models.tasks.RemindersItem; @@ -37,6 +38,7 @@ public class RemindersManager { return item; } catch (ParseException e) { e.printStackTrace(); + Crashlytics.logException(e); return null; } } @@ -45,7 +47,7 @@ public class RemindersManager { return dateFormater.format(time); } - public void createDialogeForEditText(EditText editText, String taskType, Context context) { + public void createDialogeForEditText(EditText editText, String taskType, Context context, RemindersItem reminder) { Calendar currentTime = Calendar.getInstance(); int hour = currentTime.get(Calendar.HOUR_OF_DAY); int minute = currentTime.get(Calendar.MINUTE); @@ -71,6 +73,10 @@ public class RemindersManager { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, day, hour, minute, 0); + if (reminder != null) { + reminder.setTime(calendar.getTime()); + } + editText.setText(dateFormater.format(calendar.getTime())); dialog.hide(); } @@ -81,6 +87,11 @@ public class RemindersManager { timePickerDialog = new TimePickerDialog(context, (timePicker, selectedHour, selectedMinute) -> { Calendar calendar = Calendar.getInstance(); calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), selectedHour, selectedMinute, 0); + + if (reminder != null) { + reminder.setTime(calendar.getTime()); + } + editText.setText(dateFormater.format(calendar.getTime())); }, hour, minute, true); timePickerDialog.setTitle("Select Time"); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.java b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.java index 977b70627..9ef2bce3d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.java @@ -1,5 +1,7 @@ package com.habitrpg.android.habitica.helpers; +import com.habitrpg.android.habitica.events.ReminderDeleteEvent; +import com.habitrpg.android.habitica.events.TaskDeleteEvent; import com.habitrpg.android.habitica.events.TaskSaveEvent; import com.habitrpg.android.habitica.receivers.TaskReceiver; import com.magicmicky.habitrpgwrapper.lib.models.tasks.RemindersItem; @@ -43,6 +45,23 @@ public class TaskAlarmManager { @Subscribe public void onEvent(TaskSaveEvent evnt) { Task task = (Task) evnt.task; + this.setAlarmsForTask(task); + } + + @Subscribe + public void onEvent(TaskDeleteEvent evnt) { + Task task = (Task) evnt.task; + this.removeAlarmsForTask(task); + } + + + @Subscribe + public void onEvent(ReminderDeleteEvent evnt) { + RemindersItem remindersItem = (RemindersItem) evnt.reminder; + this.removeAlarmForRemindersItem(remindersItem); + } + + public void setAlarmsForTask(Task task) { List reminders = task.getReminders(); for (RemindersItem reminder : reminders) { if (task.getType().equals(Task.TYPE_DAILY)) { @@ -54,6 +73,13 @@ public class TaskAlarmManager { } } + public void removeAlarmsForTask(Task task) { + List reminders = task.getReminders(); + for (RemindersItem reminder : reminders) { + this.removeAlarmForRemindersItem(reminder); + } + } + //This function is used from the TaskReceiver since we do not have access to the task //We currently only use this function to schedule the next reminder for dailies //We may be able to use repeating alarms instead of this in the future @@ -70,33 +96,24 @@ public class TaskAlarmManager { return; } - List reminders = task.getReminders(); - for (RemindersItem remindersItem : reminders) { - //Ensure that we set to the next available time - remindersItem = this.setTimeForDailyReminder(remindersItem, task); - this.setAlarmForRemindersItem(remindersItem); - remindersItem.async().save(); - } + this.setAlarmsForTask(task); } public void scheduleAllSavedAlarms() { - List reminders = new Select() - .from(RemindersItem.class) - .where(Condition.column("time").greaterThan(new Date())) - .orderBy(true, "time") + List tasks = new Select() + .from(Task.class) .queryList(); - for (RemindersItem remindersItem : reminders) { - this.setAlarmForRemindersItem(remindersItem); + for (Task task : tasks) { + this.setAlarmsForTask(task); } } private RemindersItem setTimeForDailyReminder(RemindersItem remindersItem, Task task) { + Calendar calendar = Calendar.getInstance(); Date oldTime = remindersItem.getTime(); Date newTime = task.getNextActiveDateAfter(oldTime); - newTime.setHours(oldTime.getHours()); - newTime.setMinutes(oldTime.getMinutes()); - newTime.setSeconds(0); + calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), oldTime.getHours(), oldTime.getMinutes(), 0); remindersItem.setTime(newTime); return remindersItem; } @@ -106,7 +123,7 @@ public class TaskAlarmManager { Integer alarmId = remindersItem.getAlarmId(); if (alarmId == null) { - alarmId = (int) System.currentTimeMillis(); + alarmId = (int) (System.currentTimeMillis() % Integer.MAX_VALUE); remindersItem.setAlarmId(alarmId); } @@ -120,12 +137,29 @@ public class TaskAlarmManager { cal.setTime(remindersItem.getTime()); Intent intent = new Intent(context, TaskReceiver.class); + intent.setAction(remindersItem.getAlarmId().toString()); intent.putExtra(TASK_NAME_INTENT_KEY, reminderItemTask.getText()); intent.putExtra(TASK_ID_INTENT_KEY, reminderItemTask.getId()); - PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender); } + + private void removeAlarmForRemindersItem(RemindersItem remindersItem) { + Integer alarmId = remindersItem.getAlarmId(); + Task reminderItemTask = remindersItem.getTask(); + + if (alarmId == null) { + return; + } + + Intent intent = new Intent(context, TaskReceiver.class); + intent.setAction(remindersItem.getAlarmId().toString()); + PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_UPDATE_CURRENT); + AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + sender.cancel(); + am.cancel(sender); + + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.java index 13c607a3b..5257ec6c8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.java @@ -84,80 +84,115 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem public static final String USER_ID_KEY = "userId"; public static final String TASK_TYPE_KEY = "type"; public static final String ALLOCATION_MODE_KEY = "allocationModeKey"; + @BindView(R.id.task_value_edittext) EditText taskValue; @BindView(R.id.task_value_layout) TextInputLayout taskValueLayout; + @BindView(R.id.task_checklist_wrapper) LinearLayout checklistWrapper; + @BindView(R.id.task_difficulty_wrapper) LinearLayout difficultyWrapper; + @BindView(R.id.task_attribute_wrapper) LinearLayout attributeWrapper; + @BindView(R.id.task_main_wrapper) LinearLayout mainWrapper; + @BindView(R.id.task_text_edittext) EmojiEditText taskText; + @BindView(R.id.task_notes_edittext) EmojiEditText taskNotes; + @BindView(R.id.task_difficulty_spinner) Spinner taskDifficultySpinner; + @BindView(R.id.task_attribute_spinner) Spinner taskAttributeSpinner; + @BindView(R.id.btn_delete_task) Button btnDelete; + @BindView(R.id.task_startdate_layout) LinearLayout startDateLayout; + @BindView(R.id.task_task_wrapper) LinearLayout taskWrapper; + @BindView(R.id.task_positive_checkbox) CheckBox positiveCheckBox; + @BindView(R.id.task_negative_checkbox) CheckBox negativeCheckBox; + @BindView(R.id.task_actions_wrapper) LinearLayout actionsLayout; + @BindView(R.id.task_weekdays_wrapper) LinearLayout weekdayWrapper; + @BindView(R.id.task_frequency_spinner) Spinner dailyFrequencySpinner; + @BindView(R.id.task_frequency_container) LinearLayout frequencyContainer; + @BindView(R.id.checklist_recycler_view) RecyclerView recyclerView; + @BindView(R.id.new_checklist) EmojiEditText newCheckListEditText; + @BindView(R.id.add_checklist_button) Button addChecklistItemButton; + @BindView(R.id.task_reminders_wrapper) LinearLayout remindersWrapper; + @BindView(R.id.new_reminder_edittext) EditText newRemindersEditText; + @BindView(R.id.reminders_recycler_view) RecyclerView remindersRecyclerView; + @BindView(R.id.add_reminder_button) Button addReminderButton; + @BindView(R.id.emoji_toggle_btn0) ImageButton emojiToggle0; + @BindView(R.id.emoji_toggle_btn1) ImageButton emojiToggle1; ImageButton emojiToggle2; + @BindView(R.id.task_duedate_layout) LinearLayout dueDateLayout; + @BindView(R.id.task_duedate_picker_layout) LinearLayout dueDatePickerLayout; + @BindView(R.id.duedate_checkbox) CheckBox dueDateCheckBox; + @BindView(R.id.startdate_text_edittext) EditText startDatePickerText; DateEditTextListener startDateListener; + @BindView(R.id.duedate_text_edittext) EditText dueDatePickerText; DateEditTextListener dueDateListener; + @BindView(R.id.task_tags_wrapper) LinearLayout tagsWrapper; + @BindView(R.id.task_tags_checklist) LinearLayout tagsContainerLinearLayout; EmojiPopup popup; + private String taskType; private String taskId; private String userId; @@ -169,10 +204,10 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem private CheckListAdapter checklistAdapter; private RemindersAdapter remindersAdapter; private List tagCheckBoxList; - private TaskAlarmManager taskAlarmManager; private List selectedTags; private RemindersManager remindersManager; + private TaskAlarmManager taskAlarmManager; @Override protected int getLayoutResId() { @@ -455,6 +490,9 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem @OnClick(R.id.add_reminder_button) public void addReminder() { RemindersItem item = remindersManager.createReminderFromDateString(newRemindersEditText.getText().toString()); + if (item == null) { + return; + } item.setType(taskType); remindersAdapter.addItem(item); newRemindersEditText.setText(""); @@ -462,7 +500,7 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem @OnClick(R.id.new_reminder_edittext) public void changeNewReminderTime() { - remindersManager.createDialogeForEditText(newRemindersEditText, taskType, this); + remindersManager.createDialogeForEditText(newRemindersEditText, taskType, this, null); } private void createTagsCheckBoxes() { @@ -797,10 +835,12 @@ public class TaskFormActivity extends BaseActivity implements AdapterView.OnItem } private void prepareSave() { + if (this.task == null) { this.task = new Task(); this.task.setType(taskType); } + if (this.saveTask(this.task)) { List taskTags = new ArrayList<>(); for (Tag tag : selectedTags) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.java index 49c175b22..e21665243 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RemindersAdapter.java @@ -115,7 +115,7 @@ public class RemindersAdapter extends RecyclerView.Adapter task = new Select() .from(Task.class) .where(Condition.column("id").eq(taskModel.getId())) .queryList(); + return task.get(0); } else { return null; @@ -108,4 +119,12 @@ public class RemindersItem extends BaseModel { } super.save(); } + + @Override + public void delete() { + ReminderDeleteEvent event = new ReminderDeleteEvent(); + event.reminder = this; + EventBus.getDefault().post(event); + super.save(); + } } diff --git a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/tasks/Task.java b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/tasks/Task.java index 23fb51107..db4ca1e61 100644 --- a/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/tasks/Task.java +++ b/Habitica/src/main/java/com/magicmicky/habitrpgwrapper/lib/models/tasks/Task.java @@ -1,9 +1,12 @@ package com.magicmicky.habitrpgwrapper.lib.models.tasks; +import android.util.Log; + import com.google.gson.annotations.SerializedName; import com.habitrpg.android.habitica.HabitDatabase; import com.habitrpg.android.habitica.R; +import com.habitrpg.android.habitica.events.TaskDeleteEvent; import com.raizlabs.android.dbflow.annotation.Column; import com.raizlabs.android.dbflow.annotation.ForeignKey; import com.raizlabs.android.dbflow.annotation.ForeignKeyReference; @@ -16,6 +19,8 @@ import com.raizlabs.android.dbflow.sql.builder.Condition; import com.raizlabs.android.dbflow.sql.language.Select; import com.raizlabs.android.dbflow.structure.BaseModel; +import org.greenrobot.eventbus.EventBus; + import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -423,6 +428,7 @@ public class Task extends BaseModel { if (this.getId() == null || this.getId().length() == 0) { return; } + List tmpTags = tags; List tmpChecklist = checklist; List tmpReminders = reminders; @@ -592,9 +598,7 @@ public class Task extends BaseModel { } public Date getNextActiveDateAfter(Date oldTime) { - Calendar today = new GregorianCalendar(); - today.set(Calendar.MILLISECOND, 0); - today.set(Calendar.SECOND, 0); + Calendar today = Calendar.getInstance(); Calendar newTime = new GregorianCalendar(); newTime.setTime(oldTime); @@ -603,16 +607,12 @@ public class Task extends BaseModel { TimeUnit timeUnit = TimeUnit.DAYS; long diffInMillies = newTime.getTimeInMillis() - today.getTimeInMillis(); long daySinceStart = timeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS); - long daysUntilNextReminder = this.getEveryX() - (daySinceStart % this.getEveryX()) - 1; - - if (newTime.before(today)) { - daysUntilNextReminder += this.getEveryX(); - } + long daysUntilNextReminder = this.getEveryX() - (daySinceStart % this.getEveryX()); newTime.add(Calendar.DATE, (int) daysUntilNextReminder); } else { - int nextActiveDayOfTheWeek = today.get(Calendar.DAY_OF_WEEK); - while (!this.getRepeat().getForDay(nextActiveDayOfTheWeek) || newTime.before(today)) { + int nextActiveDayOfTheWeek = newTime.get(Calendar.DAY_OF_WEEK); + while (!this.getRepeat().getForDay(nextActiveDayOfTheWeek) || newTime.before(today) || newTime.equals(today)) { if (nextActiveDayOfTheWeek == 6) nextActiveDayOfTheWeek = 0; nextActiveDayOfTheWeek += 1; newTime.add(Calendar.DATE, 1); @@ -621,4 +621,12 @@ public class Task extends BaseModel { return newTime.getTime(); } + + @Override + public void delete() { + TaskDeleteEvent event = new TaskDeleteEvent(); + event.task = this; + EventBus.getDefault().post(event); + super.save(); + } } diff --git a/Habitica/src/test/java/com/habitrpg/android/habitica/helpers/RemindersManagerTest.java b/Habitica/src/test/java/com/habitrpg/android/habitica/helpers/RemindersManagerTest.java new file mode 100644 index 000000000..a8620a660 --- /dev/null +++ b/Habitica/src/test/java/com/habitrpg/android/habitica/helpers/RemindersManagerTest.java @@ -0,0 +1,23 @@ +package com.habitrpg.android.habitica.helpers; + +import com.magicmicky.habitrpgwrapper.lib.models.tasks.RemindersItem; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +/** + * Created by keithholliday on 7/16/16. + */ +public class RemindersManagerTest { + + @Test + public void itCreatesRemindersItemFromDateString() { + RemindersManager remindersManager = new RemindersManager(); + +// RemindersItem remindersItem = remindersManager.createReminderFromDateString("dd MMMM yyyy HH:mm:ss") + + // assert statements + assertEquals("10 x 0 must be 0", 0, 10 * 0 ); + } + +} diff --git a/Habitica/src/test/java/com/habitrpg/android/habitica/helpers/TaskAlarmManagerTest.java b/Habitica/src/test/java/com/habitrpg/android/habitica/helpers/TaskAlarmManagerTest.java new file mode 100644 index 000000000..9b2c7be36 --- /dev/null +++ b/Habitica/src/test/java/com/habitrpg/android/habitica/helpers/TaskAlarmManagerTest.java @@ -0,0 +1,351 @@ +package com.habitrpg.android.habitica.helpers; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.app.admin.SystemUpdatePolicy; +import android.content.Context; +import android.content.Intent; + +import android.test.mock.MockContext; +import android.util.Log; + +import com.habitrpg.android.habitica.receivers.TaskReceiver; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Days; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.RemindersItem; +import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.shadows.ShadowApplication; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Created by keithholliday on 7/16/16. + */ + +@RunWith(value = RobolectricTestRunner.class) +public class TaskAlarmManagerTest { + private TaskAlarmManager taskAlarmManager; + + private Context context; + + @Before + public void setUp() { + context = ShadowApplication.getInstance().getApplicationContext(); + taskAlarmManager = TaskAlarmManager.getInstance(context); + } + + @After + public void tearDown() { + + } + + @Test + public void testItSchedulesAlarmsForTodosWithMultipleReminders() { + Task task = new Task(); + task.setType(Task.TYPE_TODO); + + List reminders = new ArrayList(); + RemindersItem remindersItem1 = new RemindersItem(); + + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1); + + remindersItem1.setTime(cal.getTime()); + reminders.add(remindersItem1); + + task.setReminders(reminders); + task.save(); + + taskAlarmManager.setAlarmsForTask(task); + + Integer alarmId = reminders.get(0).getAlarmId(); + + Intent intent = new Intent(context, TaskReceiver.class); + intent.setAction(remindersItem1.getAlarmId().toString()); + PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE); + boolean alarmUp = sender != null; + + Assert.assertNotNull(alarmId); + Assert.assertEquals(true, alarmUp); + } + + @Test + public void itUpdatesScheduledAlarmsForTodosWithMultipleReminders() { + Task task = new Task(); + task.setType(Task.TYPE_TODO); + + List reminders = new ArrayList(); + RemindersItem remindersItem1 = new RemindersItem(); + + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1); + + remindersItem1.setTime(cal.getTime()); + reminders.add(remindersItem1); + + task.setReminders(reminders); + task.save(); + + taskAlarmManager.setAlarmsForTask(task); + + Integer alarmId = reminders.get(0).getAlarmId(); + Intent intent = new Intent(context, TaskReceiver.class); + intent.setAction(remindersItem1.getAlarmId().toString()); + PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE); + boolean alarmUp = sender != null; + + Assert.assertNotNull(alarmId); + Assert.assertEquals(true, alarmUp); + + + reminders = new ArrayList(); + cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1); + remindersItem1.setTime(cal.getTime()); + remindersItem1.save(); + reminders.add(remindersItem1); + task.setReminders(reminders); + task.save(); + + //This prevents in error in the DBFLow queue be out of sync + try { + Thread.sleep(1000); + } catch(InterruptedException ex) { + Thread.currentThread().interrupt(); + } + + taskAlarmManager.setAlarmsForTask(task); + Integer newAlarmId = reminders.get(0).getAlarmId(); + PendingIntent senderNew = PendingIntent.getBroadcast(context, newAlarmId, intent, PendingIntent.FLAG_NO_CREATE); + boolean alarmUpNew = senderNew != null; + + Assert.assertNotNull(newAlarmId); + Assert.assertEquals(alarmId, newAlarmId); + Assert.assertEquals(true, alarmUpNew); + } + + @Test + //@TODO: Pending + public void itRemovesAlarmsWhenRemindersAreRemovedFromTodo() { + Task task = new Task(); + task.setType(Task.TYPE_TODO); + + List reminders = new ArrayList(); + RemindersItem remindersItem1 = new RemindersItem(); + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1); + remindersItem1.setTime(cal.getTime()); + reminders.add(remindersItem1); + task.setReminders(reminders); + task.save(); + + taskAlarmManager.setAlarmsForTask(task); +// +// Integer alarmId = reminders.get(0).getAlarmId(); +// Intent intent = new Intent(context, TaskReceiver.class); +// intent.setAction(remindersItem1.getAlarmId().toString()); +// PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_CANCEL_CURRENT); +// try{ Thread.sleep(5000); }catch(InterruptedException e){ } +// PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE); +// boolean alarmUp = sender != null; +// System.out.println(sender); +// Assert.assertNotNull(alarmId); +// Assert.assertEquals(true, alarmUp); + +// remindersItem1.delete(); +// +// PendingIntent senderUpdated = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE); +// boolean alarmDown = senderUpdated == null; +// +// Assert.assertEquals(true, alarmDown); + } + + @Test + //@TODO: Pending + public void itRemovesAlarmsWhenTodoIsDeleted() { + + } + + @Test + public void itScheduledAlarmForTheNextAvailableDayForRegularDaily() { + Task task = new Task(); + task.setType(Task.TYPE_DAILY); + task.setFrequency(Task.FREQUENCY_WEEKLY); + + Days taskRepeatDays = new Days(); + taskRepeatDays.setM(true); + taskRepeatDays.setS(false); + taskRepeatDays.setSu(false); + task.setRepeat(taskRepeatDays); + + List reminders = new ArrayList(); + RemindersItem remindersItem1 = new RemindersItem(); + + //We try to set a reminder on Tuesday, but the manager will correct this to Monday + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.DAY_OF_WEEK, 3); + cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1); + + remindersItem1.setTime(cal.getTime()); + reminders.add(remindersItem1); + + task.setReminders(reminders); + task.save(); + + taskAlarmManager.setAlarmsForTask(task); + + Integer alarmId = reminders.get(0).getAlarmId(); + + Calendar newReminderTime = Calendar.getInstance(); + newReminderTime.setTime(reminders.get(0).getTime()); + + Intent intent = new Intent(context, TaskReceiver.class); + intent.setAction(remindersItem1.getAlarmId().toString()); + PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE); + boolean alarmUp = sender != null; + + Assert.assertNotNull(alarmId); + Assert.assertEquals(true, alarmUp); + Assert.assertEquals(1, newReminderTime.get(Calendar.DAY_OF_WEEK)); + } + + @Test + //This also tests for when the receiver tries to schedule the next daily available + public void itScheduledAlarmForTheNextAvailableDayForRegularDailyWhenUserTriesToSetAlarmForNow() { + Task task = new Task(); + task.setType(Task.TYPE_DAILY); + task.setFrequency(Task.FREQUENCY_WEEKLY); + + Days taskRepeatDays = new Days(); + taskRepeatDays.setM(true); + taskRepeatDays.setT(true); + taskRepeatDays.setW(true); + taskRepeatDays.setTh(true); + taskRepeatDays.setF(true); + taskRepeatDays.setS(false); + taskRepeatDays.setSu(false); + task.setRepeat(taskRepeatDays); + + List reminders = new ArrayList(); + RemindersItem remindersItem1 = new RemindersItem(); + + //We try to set a reminder for now, but by the manager will correct (because the seconds will be different) + Calendar cal = Calendar.getInstance(); + + remindersItem1.setTime(cal.getTime()); + reminders.add(remindersItem1); + + task.setReminders(reminders); + task.save(); + + taskAlarmManager.setAlarmsForTask(task); + + Integer alarmId = reminders.get(0).getAlarmId(); + + Calendar newReminderTime = Calendar.getInstance(); + newReminderTime.setTime(reminders.get(0).getTime()); + + Intent intent = new Intent(context, TaskReceiver.class); + intent.setAction(remindersItem1.getAlarmId().toString()); + PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE); + boolean alarmUp = sender != null; + + Assert.assertNotNull(alarmId); + Assert.assertEquals(true, alarmUp); + Assert.assertNotSame(cal.getTime(), newReminderTime); + } + + @Test + public void itScheduledAlarmForTheNextAvailableDayForEveryXDayDaily() { + Task task = new Task(); + task.setType(Task.TYPE_DAILY); + task.setFrequency(Task.FREQUENCY_DAILY); + + int everyXDay = 2; + task.setEveryX(everyXDay); + + List reminders = new ArrayList(); + RemindersItem remindersItem1 = new RemindersItem(); + + //We try to set a reminder one day after the start date, but the manager will correct since the + // daily is every 2 days from above + Calendar cal = Calendar.getInstance(); + int currentDayOfTheWeek = cal.get(Calendar.DAY_OF_WEEK); + cal.set(Calendar.DAY_OF_WEEK, currentDayOfTheWeek + 1); + cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1); + + remindersItem1.setTime(cal.getTime()); + reminders.add(remindersItem1); + + task.setReminders(reminders); + task.save(); + + taskAlarmManager.setAlarmsForTask(task); + + Integer alarmId = reminders.get(0).getAlarmId(); + + Calendar newReminderTime = Calendar.getInstance(); + newReminderTime.setTime(reminders.get(0).getTime()); + + Intent intent = new Intent(context, TaskReceiver.class); + intent.setAction(remindersItem1.getAlarmId().toString()); + PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE); + boolean alarmUp = sender != null; + + Assert.assertNotNull(alarmId); + Assert.assertEquals(true, alarmUp); + Assert.assertEquals(currentDayOfTheWeek + everyXDay, newReminderTime.get(Calendar.DAY_OF_WEEK)); + } + + @Test + //This also tests for when the receiver tries to schedule the next daily available + public void itScheduledAlarmForTheNextAvailableDayForEveryXDayDailyWhenUserTriesToSetAlarmForNow() { + Task task = new Task(); + task.setType(Task.TYPE_DAILY); + task.setFrequency(Task.FREQUENCY_DAILY); + + int everyXDay = 2; + task.setEveryX(everyXDay); + + List reminders = new ArrayList(); + RemindersItem remindersItem1 = new RemindersItem(); + + //We try to set a reminder for now, but the manager will correct since the seconds will be off + Calendar cal = Calendar.getInstance(); + int currentDayOfTheWeek = cal.get(Calendar.DAY_OF_WEEK); + + remindersItem1.setTime(cal.getTime()); + reminders.add(remindersItem1); + + task.setReminders(reminders); + task.save(); + + taskAlarmManager.setAlarmsForTask(task); + + Integer alarmId = reminders.get(0).getAlarmId(); + + Calendar newReminderTime = Calendar.getInstance(); + newReminderTime.setTime(reminders.get(0).getTime()); + + Intent intent = new Intent(context, TaskReceiver.class); + intent.setAction(remindersItem1.getAlarmId().toString()); + PendingIntent sender = PendingIntent.getBroadcast(context, alarmId, intent, PendingIntent.FLAG_NO_CREATE); + boolean alarmUp = sender != null; + + Assert.assertNotNull(alarmId); + Assert.assertEquals(true, alarmUp); + Assert.assertEquals(currentDayOfTheWeek + everyXDay, newReminderTime.get(Calendar.DAY_OF_WEEK)); + } +}