diff --git a/app/src/androidTest/java/com/todoroo/astrid/repeats/RepeatWithSubtasksTests.kt b/app/src/androidTest/java/com/todoroo/astrid/repeats/RepeatWithSubtasksTests.kt index 2c5b269f7..084406dc7 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/repeats/RepeatWithSubtasksTests.kt +++ b/app/src/androidTest/java/com/todoroo/astrid/repeats/RepeatWithSubtasksTests.kt @@ -1,6 +1,5 @@ package com.todoroo.astrid.repeats -import com.google.ical.values.RRule import com.natpryce.makeiteasy.MakeItEasy.with import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules @@ -12,7 +11,7 @@ import org.tasks.injection.InjectingTestCase import org.tasks.injection.ProductionModule import org.tasks.makers.TaskMaker.COMPLETION_TIME import org.tasks.makers.TaskMaker.PARENT -import org.tasks.makers.TaskMaker.RRULE +import org.tasks.makers.TaskMaker.RECUR import org.tasks.makers.TaskMaker.newTask import org.tasks.time.DateTime import javax.inject.Inject @@ -25,7 +24,7 @@ class RepeatWithSubtasksTests : InjectingTestCase() { @Test fun uncompleteGrandchildren() = runBlocking { - val grandparent = taskDao.createNew(newTask(with(RRULE, RRule("RRULE:FREQ=DAILY")))) + val grandparent = taskDao.createNew(newTask(with(RECUR, "RRULE:FREQ=DAILY"))) val parent = taskDao.createNew(newTask(with(PARENT, grandparent))) val child = taskDao.createNew(newTask( with(PARENT, parent), @@ -39,7 +38,7 @@ class RepeatWithSubtasksTests : InjectingTestCase() { @Test fun uncompleteGoogleTaskChildren() = runBlocking { - val parent = taskDao.createNew(newTask(with(RRULE, RRule("RRULE:FREQ=DAILY")))) + val parent = taskDao.createNew(newTask(with(RECUR, "RRULE:FREQ=DAILY"))) val child = taskDao.createNew(newTask( with(PARENT, parent), with(COMPLETION_TIME, DateTime()) diff --git a/app/src/androidTest/java/com/todoroo/astrid/service/TaskDeleterTest.kt b/app/src/androidTest/java/com/todoroo/astrid/service/TaskDeleterTest.kt index 83c8dcb9f..e741df3bb 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/service/TaskDeleterTest.kt +++ b/app/src/androidTest/java/com/todoroo/astrid/service/TaskDeleterTest.kt @@ -1,6 +1,5 @@ package com.todoroo.astrid.service -import com.google.ical.values.RRule import com.natpryce.makeiteasy.MakeItEasy.with import com.todoroo.astrid.core.BuiltInFilterExposer.Companion.getMyTasksFilter import dagger.hilt.android.testing.HiltAndroidTest @@ -18,7 +17,7 @@ import org.tasks.makers.GoogleTaskMaker.TASK import org.tasks.makers.GoogleTaskMaker.newGoogleTask import org.tasks.makers.TaskMaker.COMPLETION_TIME import org.tasks.makers.TaskMaker.PARENT -import org.tasks.makers.TaskMaker.RRULE +import org.tasks.makers.TaskMaker.RECUR import org.tasks.makers.TaskMaker.newTask import org.tasks.time.DateTime import javax.inject.Inject @@ -41,7 +40,7 @@ class TaskDeleterTest : InjectingTestCase() { @Test fun dontDeleteTaskWithRecurringParent() = runBlocking { - val parent = taskDao.createNew(newTask(with(RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=1")))) + val parent = taskDao.createNew(newTask(with(RECUR, "RRULE:FREQ=DAILY;INTERVAL=1"))) val child = taskDao.createNew(newTask( with(PARENT, parent), with(COMPLETION_TIME, DateTime()) @@ -54,7 +53,7 @@ class TaskDeleterTest : InjectingTestCase() { @Test fun dontDeleteTaskWithRecurringGrandparent() = runBlocking { - val grandparent = taskDao.createNew(newTask(with(RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=1")))) + val grandparent = taskDao.createNew(newTask(with(RECUR, "RRULE:FREQ=DAILY;INTERVAL=1"))) val parent = taskDao.createNew(newTask(with(PARENT, grandparent))) val child = taskDao.createNew(newTask( with(PARENT, parent), @@ -83,7 +82,7 @@ class TaskDeleterTest : InjectingTestCase() { @Test fun clearGrandchildWithCompletedRecurringAncestor() = runBlocking { val grandparent = taskDao.createNew(newTask( - with(RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=1")), + with(RECUR, "RRULE:FREQ=DAILY;INTERVAL=1"), with(COMPLETION_TIME, DateTime()) )) val parent = taskDao.createNew(newTask(with(PARENT, grandparent))) @@ -99,7 +98,7 @@ class TaskDeleterTest : InjectingTestCase() { @Test fun dontClearCompletedGoogleTaskWithRecurringParent() = runBlocking { - val parent = taskDao.createNew(newTask(with(RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=1")))) + val parent = taskDao.createNew(newTask(with(RECUR, "RRULE:FREQ=DAILY;INTERVAL=1"))) val child = taskDao.createNew(newTask(with(COMPLETION_TIME, DateTime()))) googleTaskDao.insert(newGoogleTask(with(TASK, child), with(GoogleTaskMaker.PARENT, parent))) @@ -122,7 +121,7 @@ class TaskDeleterTest : InjectingTestCase() { @Test fun clearCompletedGoogleTaskWithCompletedRecurringParent() = runBlocking { val parent = taskDao.createNew(newTask( - with(RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=1")), + with(RECUR, "RRULE:FREQ=DAILY;INTERVAL=1"), with(COMPLETION_TIME, DateTime()) )) val child = taskDao.createNew(newTask(with(COMPLETION_TIME, DateTime()))) diff --git a/app/src/androidTest/java/com/todoroo/astrid/service/TitleParserTest.kt b/app/src/androidTest/java/com/todoroo/astrid/service/TitleParserTest.kt index b5a148690..28b4eb473 100644 --- a/app/src/androidTest/java/com/todoroo/astrid/service/TitleParserTest.kt +++ b/app/src/androidTest/java/com/todoroo/astrid/service/TitleParserTest.kt @@ -5,13 +5,12 @@ */ package com.todoroo.astrid.service -import com.google.ical.values.Frequency -import com.google.ical.values.RRule import com.todoroo.astrid.data.Task import com.todoroo.astrid.utility.TitleParser import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules import kotlinx.coroutines.runBlocking +import net.fortuna.ical4j.model.Recur.Frequency.* import org.junit.Assert.* import org.junit.Before import org.junit.Ignore @@ -22,6 +21,7 @@ import org.tasks.date.DateTimeUtils import org.tasks.injection.InjectingTestCase import org.tasks.injection.ProductionModule import org.tasks.preferences.Preferences +import org.tasks.repeats.RecurrenceUtils.newRecur import java.util.* import javax.inject.Inject @@ -280,22 +280,22 @@ class TitleParserTest : InjectingTestCase() { fun testDailyWithNoDueDate() = runBlocking { var title = "Jog daily" var task = taskCreator.createWithValues(title) - val rrule = RRule() - rrule.freq = Frequency.DAILY - rrule.interval = 1 - assertEquals(task.recurrence, rrule.toIcal()) + val recur = newRecur() + recur.setFrequency(DAILY.name) + recur.interval = 1 + assertEquals(task.recurrence, "RRULE:$recur") assertFalse(task.hasDueTime()) assertFalse(task.hasDueDate()) title = "Jog every day" task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertFalse(task.hasDueTime()) assertFalse(task.hasDueDate()) for (i in 1..12) { title = "Jog every $i days." - rrule.interval = i + recur.interval = i task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertFalse(task.hasDueTime()) assertFalse(task.hasDueDate()) } @@ -306,22 +306,22 @@ class TitleParserTest : InjectingTestCase() { fun testWeeklyWithNoDueDate() = runBlocking { var title = "Jog weekly" var task = taskCreator.createWithValues(title) - val rrule = RRule() - rrule.freq = Frequency.WEEKLY - rrule.interval = 1 - assertEquals(task.recurrence, rrule.toIcal()) + val recur = newRecur() + recur.setFrequency(WEEKLY.name) + recur.interval = 1 + assertEquals(task.recurrence, "RRULE:$recur") assertFalse(task.hasDueTime()) assertFalse(task.hasDueDate()) title = "Jog every week" task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertFalse(task.hasDueTime()) assertFalse(task.hasDueDate()) for (i in 1..12) { title = "Jog every $i weeks" - rrule.interval = i + recur.interval = i task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertFalse(task.hasDueTime()) assertFalse(task.hasDueDate()) } @@ -332,22 +332,22 @@ class TitleParserTest : InjectingTestCase() { fun testMonthlyFromNoDueDate() = runBlocking { var title = "Jog monthly" var task = taskCreator.createWithValues(title) - val rrule = RRule() - rrule.freq = Frequency.MONTHLY - rrule.interval = 1 - assertEquals(task.recurrence, rrule.toIcal()) + val recur = newRecur() + recur.setFrequency(MONTHLY.name) + recur.interval = 1 + assertEquals(task.recurrence, "RRULE:$recur") assertFalse(task.hasDueTime()) assertFalse(task.hasDueDate()) title = "Jog every month" task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertFalse(task.hasDueTime()) assertFalse(task.hasDueDate()) for (i in 1..12) { title = "Jog every $i months" - rrule.interval = i + recur.interval = i task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertFalse(task.hasDueTime()) assertFalse(task.hasDueDate()) } @@ -357,20 +357,20 @@ class TitleParserTest : InjectingTestCase() { fun testDailyFromDueDate() = runBlocking { var title = "Jog daily starting from today" var task = taskCreator.createWithValues(title) - val rrule = RRule() - rrule.freq = Frequency.DAILY - rrule.interval = 1 - assertEquals(task.recurrence, rrule.toIcal()) + val recur = newRecur() + recur.setFrequency(DAILY.name) + recur.interval = 1 + assertEquals(task.recurrence, "RRULE:$recur") assertTrue(task.hasDueDate()) title = "Jog every day starting from today" task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertTrue(task.hasDueDate()) for (i in 1..12) { title = "Jog every $i days starting from today" - rrule.interval = i + recur.interval = i task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertTrue(task.hasDueDate()) } } @@ -379,20 +379,20 @@ class TitleParserTest : InjectingTestCase() { fun testWeeklyFromDueDate() = runBlocking { var title = "Jog weekly starting from today" var task = taskCreator.createWithValues(title) - val rrule = RRule() - rrule.freq = Frequency.WEEKLY - rrule.interval = 1 - assertEquals(task.recurrence, rrule.toIcal()) + val recur = newRecur() + recur.setFrequency(WEEKLY.name) + recur.interval = 1 + assertEquals(task.recurrence, "RRULE:$recur") assertTrue(task.hasDueDate()) title = "Jog every week starting from today" task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertTrue(task.hasDueDate()) for (i in 1..12) { title = "Jog every $i weeks starting from today" - rrule.interval = i + recur.interval = i task = taskCreator.createWithValues(title) - assertEquals(task.recurrence, rrule.toIcal()) + assertEquals(task.recurrence, "RRULE:$recur") assertTrue(task.hasDueDate()) } } diff --git a/app/src/androidTest/java/org/tasks/opentasks/OpenTasksSynchronizerTest.kt b/app/src/androidTest/java/org/tasks/opentasks/OpenTasksSynchronizerTest.kt index aade198bb..2a7b5497f 100644 --- a/app/src/androidTest/java/org/tasks/opentasks/OpenTasksSynchronizerTest.kt +++ b/app/src/androidTest/java/org/tasks/opentasks/OpenTasksSynchronizerTest.kt @@ -1,6 +1,5 @@ package org.tasks.opentasks -import com.google.ical.values.RRule import com.natpryce.makeiteasy.MakeItEasy.with import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules @@ -16,7 +15,7 @@ import org.tasks.makers.CaldavTaskMaker.CALENDAR import org.tasks.makers.CaldavTaskMaker.REMOTE_ID import org.tasks.makers.CaldavTaskMaker.TASK import org.tasks.makers.CaldavTaskMaker.newCaldavTask -import org.tasks.makers.TaskMaker.RRULE +import org.tasks.makers.TaskMaker.RECUR import org.tasks.makers.TaskMaker.newTask @UninstallModules(ProductionModule::class) @@ -107,7 +106,7 @@ class OpenTasksSynchronizerTest : OpenTasksTest() { @Test fun sanitizeRecurrenceRule() = runBlocking { val (_, list) = openTaskDao.insertList() - val taskId = taskDao.insert(newTask(with(RRULE, RRule("RRULE:FREQ=WEEKLY;COUNT=-1")))) + val taskId = taskDao.insert(newTask(with(RECUR, "RRULE:FREQ=WEEKLY;COUNT=-1"))) caldavDao.insert(newCaldavTask( with(CALENDAR, list.uuid), with(TASK, taskId) diff --git a/app/src/androidTest/java/org/tasks/repeats/RepeatRuleToStringTest.kt b/app/src/androidTest/java/org/tasks/repeats/RepeatRuleToStringTest.kt index 10b3ee463..dafa67844 100644 --- a/app/src/androidTest/java/org/tasks/repeats/RepeatRuleToStringTest.kt +++ b/app/src/androidTest/java/org/tasks/repeats/RepeatRuleToStringTest.kt @@ -1,9 +1,7 @@ package org.tasks.repeats -import com.todoroo.astrid.data.Task.Companion.withoutRRULE import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules -import net.fortuna.ical4j.model.property.RRule import org.junit.Assert.assertEquals import org.junit.Test import org.tasks.TestUtilities.withTZ @@ -110,15 +108,15 @@ class RepeatRuleToStringTest : InjectingTestCase() { } } - private fun toString(rrule: String): String { + private fun toString(rrule: String): String? { return toString(null, rrule) } - private fun toString(language: String?, rrule: String): String { + private fun toString(language: String?, rrule: String): String? { return try { val locale = Locale(java.util.Locale.getDefault(), language) RepeatRuleToString(locale.createConfigurationContext(context), locale, firebase) - .toString(RRule(rrule.withoutRRULE())) + .toString(rrule) } catch (e: ParseException) { throw RuntimeException(e) } diff --git a/app/src/androidTest/java/org/tasks/ui/editviewmodel/RepeatTests.kt b/app/src/androidTest/java/org/tasks/ui/editviewmodel/RepeatTests.kt index d37ab1750..899bcc3bd 100644 --- a/app/src/androidTest/java/org/tasks/ui/editviewmodel/RepeatTests.kt +++ b/app/src/androidTest/java/org/tasks/ui/editviewmodel/RepeatTests.kt @@ -1,6 +1,5 @@ package org.tasks.ui.editviewmodel -import com.google.ical.values.RRule import com.natpryce.makeiteasy.MakeItEasy.with import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules @@ -16,7 +15,7 @@ import org.tasks.makers.TaskMaker.newTask class RepeatTests : BaseTaskEditViewModelTest() { @Test fun changeRepeatAfterCompletion() = runBlocking { - val task = newTask(with(TaskMaker.RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=1"))) + val task = newTask(with(TaskMaker.RECUR, "RRULE:FREQ=DAILY;INTERVAL=1")) setup(task) viewModel.repeatAfterCompletion = true diff --git a/app/src/commonTest/java/org/tasks/makers/TaskMaker.kt b/app/src/commonTest/java/org/tasks/makers/TaskMaker.kt index c79604468..d0e874dec 100644 --- a/app/src/commonTest/java/org/tasks/makers/TaskMaker.kt +++ b/app/src/commonTest/java/org/tasks/makers/TaskMaker.kt @@ -26,7 +26,7 @@ object TaskMaker { val COMPLETION_TIME: Property = newProperty() val DELETION_TIME: Property = newProperty() val SNOOZE_TIME: Property = newProperty() - val RRULE: Property = newProperty() + val RECUR: Property = newProperty() val AFTER_COMPLETE: Property = newProperty() val TITLE: Property = newProperty() val PRIORITY: Property = newProperty() @@ -83,9 +83,9 @@ object TaskMaker { if (randomReminderPeriod > 0) { task.reminderPeriod = randomReminderPeriod } - val rrule = lookup.valueOf(RRULE, null as RRule?) - if (rrule != null) { - task.setRecurrence(rrule, lookup.valueOf(AFTER_COMPLETE, false)) + lookup.valueOf(RECUR, null as String?)?.let { + val rrule = if (it.startsWith("RRULE:")) it else "RRULE:$it" + task.setRecurrence(RRule(rrule), lookup.valueOf(AFTER_COMPLETE, false)) } task.uuid = lookup.valueOf(UUID, NO_UUID) val creationTime = lookup.valueOf(CREATION_TIME, DateTimeUtils.newDateTime()) diff --git a/app/src/main/java/com/todoroo/astrid/repeats/RepeatTaskHelper.kt b/app/src/main/java/com/todoroo/astrid/repeats/RepeatTaskHelper.kt index f42ebc73d..d32ab4258 100644 --- a/app/src/main/java/com/todoroo/astrid/repeats/RepeatTaskHelper.kt +++ b/app/src/main/java/com/todoroo/astrid/repeats/RepeatTaskHelper.kt @@ -12,6 +12,7 @@ import com.todoroo.astrid.alarms.AlarmService import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task.Companion.createDueDate +import com.todoroo.astrid.data.Task.Companion.withoutFrom import com.todoroo.astrid.gcal.GCalHelper import com.todoroo.astrid.service.TaskCompleter import org.tasks.LocalBroadcastManager @@ -38,7 +39,7 @@ class RepeatTaskHelper @Inject constructor( val newDueDate: Long val rrule: RRule try { - rrule = initRRule(task.getRecurrenceWithoutFrom()) + rrule = initRRule(task.recurrence) newDueDate = computeNextDueDate(task, recurrence, repeatAfterCompletion) if (newDueDate == -1L) { return @@ -196,7 +197,9 @@ class RepeatTaskHelper @Inject constructor( /** Initialize RRule instance */ @Throws(ParseException::class) private fun initRRule(recurrence: String?): RRule { - val rrule = RRule(recurrence) + val rrule = RRule(recurrence + ?.let { if (it.startsWith("RRULE:")) it else "RRULE:$it" } + ?.withoutFrom()) if (rrule.count < 0) { rrule.count = 0 diff --git a/app/src/main/java/org/tasks/repeats/RecurrenceUtils.kt b/app/src/main/java/org/tasks/repeats/RecurrenceUtils.kt new file mode 100644 index 000000000..e069d3ede --- /dev/null +++ b/app/src/main/java/org/tasks/repeats/RecurrenceUtils.kt @@ -0,0 +1,19 @@ +package org.tasks.repeats + +import com.todoroo.astrid.data.Task.Companion.withoutFrom +import net.fortuna.ical4j.model.Recur +import net.fortuna.ical4j.model.property.RRule + +object RecurrenceUtils { + private val LEGACY_RRULE_PREFIX = "^RRULE:".toRegex() + + @JvmStatic + fun newRecur(): Recur = Recur.Builder().frequency(Recur.Frequency.DAILY).build() + + @JvmStatic + fun newRecur(rrule: String): Recur = newRRule(rrule).recur + + fun newRRule(rrule: String): RRule = + RRule(rrule.replace(LEGACY_RRULE_PREFIX, "").withoutFrom()) + +} \ No newline at end of file diff --git a/app/src/test/java/com/todoroo/astrid/repeats/AdvancedRepeatTest.kt b/app/src/test/java/com/todoroo/astrid/repeats/AdvancedRepeatTest.kt index 25fda8b6c..7c57020fe 100644 --- a/app/src/test/java/com/todoroo/astrid/repeats/AdvancedRepeatTest.kt +++ b/app/src/test/java/com/todoroo/astrid/repeats/AdvancedRepeatTest.kt @@ -5,16 +5,17 @@ */ package com.todoroo.astrid.repeats -import com.google.ical.values.Frequency -import com.google.ical.values.RRule -import com.google.ical.values.Weekday -import com.google.ical.values.WeekdayNum import com.todoroo.andlib.utility.DateUtilities import com.todoroo.astrid.data.Task +import net.fortuna.ical4j.model.Recur +import net.fortuna.ical4j.model.Recur.Frequency +import net.fortuna.ical4j.model.WeekDay +import net.fortuna.ical4j.model.WeekDay.* import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test import org.tasks.date.DateTimeUtils +import org.tasks.repeats.RecurrenceUtils.newRecur import org.tasks.time.DateTime import org.tasks.time.DateTimeUtils.printTimestamp import java.text.ParseException @@ -25,27 +26,27 @@ import kotlin.math.min class AdvancedRepeatTest { private var task: Task? = null private var nextDueDate: Long = 0 - private var rrule: RRule? = null + private var recur: Recur? = null // --- date with time tests @Before fun setUp() { task = Task() task!!.completionDate = DateUtilities.now() - rrule = RRule() + recur = newRecur() } @Test @Throws(ParseException::class) fun testDueDateSpecificTime() { - buildRRule(1, Frequency.DAILY) + buildRecur(1, Frequency.DAILY) // test specific day & time val dayWithTime = Task.createDueDate( Task.URGENCY_SPECIFIC_DAY_TIME, DateTime(2010, 8, 1, 10, 4, 0).millis) task!!.dueDate = dayWithTime val nextDayWithTime = dayWithTime + DateUtilities.ONE_DAY - nextDueDate = RepeatTaskHelper.computeNextDueDate(task!!, rrule!!.toIcal(), false) + nextDueDate = RepeatTaskHelper.computeNextDueDate(task!!, recur!!.toString(), false) assertDateTimeEquals(nextDayWithTime, nextDueDate) } @@ -53,7 +54,7 @@ class AdvancedRepeatTest { @Test @Throws(ParseException::class) fun testCompletionDateSpecificTime() { - buildRRule(1, Frequency.DAILY) + buildRecur(1, Frequency.DAILY) // test specific day & time val dayWithTime = Task.createDueDate( @@ -63,7 +64,7 @@ class AdvancedRepeatTest { var nextDayWithTimeLong = todayWithTime.millis nextDayWithTimeLong += DateUtilities.ONE_DAY nextDayWithTimeLong = nextDayWithTimeLong / 1000L * 1000 - nextDueDate = RepeatTaskHelper.computeNextDueDate(task!!, rrule!!.toIcal(), true) + nextDueDate = RepeatTaskHelper.computeNextDueDate(task!!, recur!!.toString(), true) assertDateTimeEquals(nextDayWithTimeLong, nextDueDate) } @@ -71,7 +72,7 @@ class AdvancedRepeatTest { @Test @Throws(Exception::class) fun testDueDateInPastSingleWeekMultiDay() { - buildRRule(1, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR) + buildRecur(1, Frequency.WEEKLY, MO, WE, FR) setTaskDueDate(THIS, Calendar.SUNDAY) computeNextDueDate(false) assertDueDate(nextDueDate, THIS, Calendar.MONDAY) @@ -87,7 +88,7 @@ class AdvancedRepeatTest { @Test @Throws(Exception::class) fun testDueDateSingleDay() { - buildRRule(1, Frequency.WEEKLY, Weekday.MO) + buildRecur(1, Frequency.WEEKLY, MO) setTaskDueDate(PREV_PREV, Calendar.MONDAY) computeNextDueDate(false) assertDueDate(nextDueDate, NEXT, Calendar.MONDAY) @@ -112,7 +113,7 @@ class AdvancedRepeatTest { @Test @Throws(Exception::class) fun testDueDateSingleWeekMultiDay() { - buildRRule(1, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR) + buildRecur(1, Frequency.WEEKLY, MO, WE, FR) setTaskDueDate(THIS, Calendar.SUNDAY) computeNextDueDate(false) assertDueDate(nextDueDate, THIS, Calendar.MONDAY) @@ -128,7 +129,7 @@ class AdvancedRepeatTest { @Test @Throws(Exception::class) fun testDueDateMultiWeekMultiDay() { - buildRRule(2, Frequency.WEEKLY, Weekday.MO, Weekday.WE, Weekday.FR) + buildRecur(2, Frequency.WEEKLY, MO, WE, FR) setTaskDueDate(THIS, Calendar.SUNDAY) computeNextDueDate(false) assertDueDate(nextDueDate, NEXT, Calendar.MONDAY) @@ -144,21 +145,21 @@ class AdvancedRepeatTest { @Test @Throws(Exception::class) fun testCompleteDateSingleWeek() { - for (wday in Weekday.values()) { - buildRRule(1, Frequency.WEEKLY, wday) + for (wday in weekdays) { + buildRecur(1, Frequency.WEEKLY, wday) computeNextDueDate(true) - val expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday.javaDayNum) + val expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, getCalendarDay(wday)) nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate) assertEquals(expected, nextDueDate) } - for (wday1 in Weekday.values()) { - for (wday2 in Weekday.values()) { + for (wday1 in weekdays) { + for (wday2 in weekdays) { if (wday1 == wday2) { continue } - buildRRule(1, Frequency.WEEKLY, wday1, wday2) - val nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday1.javaDayNum) - val nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday2.javaDayNum) + buildRecur(1, Frequency.WEEKLY, wday1, wday2) + val nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, getCalendarDay(wday1)) + val nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, getCalendarDay(wday2)) computeNextDueDate(true) nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate) assertEquals(min(nextOne, nextTwo), nextDueDate) @@ -170,21 +171,21 @@ class AdvancedRepeatTest { @Test @Throws(Exception::class) fun testCompleteDateMultiWeek() { - for (wday in Weekday.values()) { - buildRRule(2, Frequency.WEEKLY, wday) + for (wday in weekdays) { + buildRecur(2, Frequency.WEEKLY, wday) computeNextDueDate(true) - val expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday.javaDayNum) + val expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, getCalendarDay(wday)) nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate) assertEquals(expected, nextDueDate) } - for (wday1 in Weekday.values()) { - for (wday2 in Weekday.values()) { + for (wday1 in weekdays) { + for (wday2 in weekdays) { if (wday1 == wday2) { continue } - buildRRule(2, Frequency.WEEKLY, wday1, wday2) - val nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday1.javaDayNum) - val nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday2.javaDayNum) + buildRecur(2, Frequency.WEEKLY, wday1, wday2) + val nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, getCalendarDay(wday1)) + val nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, getCalendarDay(wday2)) computeNextDueDate(true) nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate) assertEquals(min(nextOne, nextTwo), nextDueDate) @@ -194,13 +195,14 @@ class AdvancedRepeatTest { @Throws(ParseException::class) private fun computeNextDueDate(fromComplete: Boolean) { - nextDueDate = RepeatTaskHelper.computeNextDueDate(task!!, rrule!!.toIcal(), fromComplete) + nextDueDate = RepeatTaskHelper.computeNextDueDate(task!!, recur!!.toString(), fromComplete) } - private fun buildRRule(interval: Int, freq: Frequency, vararg weekdays: Weekday) { - rrule!!.interval = interval - rrule!!.freq = freq - setRRuleDays(rrule, *weekdays) + private fun buildRecur(interval: Int, freq: Frequency, vararg weekdays: WeekDay) { + recur!!.interval = interval + recur!!.setFrequency(freq.name) + recur!!.dayList.clear() + recur!!.dayList.addAll(weekdays) } private fun assertDueDate(actual: Long, expectedWhich: Int, expectedDayOfWeek: Int) { @@ -208,14 +210,6 @@ class AdvancedRepeatTest { assertEquals(expected, actual) } - private fun setRRuleDays(rrule: RRule?, vararg weekdays: Weekday) { - val days = ArrayList() - for (wd in weekdays) { - days.add(WeekdayNum(0, wd)) - } - rrule!!.byDay = days - } - private fun setTaskDueDate(which: Int, day: Int) { val time = getDate(DateUtilities.now(), which, day) task!!.dueDate = time @@ -238,6 +232,8 @@ class AdvancedRepeatTest { private const val THIS = 1 private const val NEXT = 2 + private val weekdays = listOf(SU, MO, TU, WE, TH, FR, SA) + fun assertDateTimeEquals(date: Long, other: Long) { assertEquals("Expected: ${printTimestamp(date)}, Actual: ${printTimestamp(other)}", date, other) } diff --git a/app/src/test/java/com/todoroo/astrid/repeats/NewRepeatTests.kt b/app/src/test/java/com/todoroo/astrid/repeats/NewRepeatTests.kt index 922e51149..16a5130b9 100644 --- a/app/src/test/java/com/todoroo/astrid/repeats/NewRepeatTests.kt +++ b/app/src/test/java/com/todoroo/astrid/repeats/NewRepeatTests.kt @@ -1,18 +1,17 @@ package com.todoroo.astrid.repeats -import com.google.ical.values.Frequency -import com.google.ical.values.RRule -import com.google.ical.values.Weekday -import com.google.ical.values.WeekdayNum import com.natpryce.makeiteasy.MakeItEasy.with import com.todoroo.astrid.data.Task +import net.fortuna.ical4j.model.Recur.Frequency +import net.fortuna.ical4j.model.WeekDay import org.junit.Assert.assertEquals import org.junit.Test import org.tasks.makers.TaskMaker.AFTER_COMPLETE import org.tasks.makers.TaskMaker.COMPLETION_TIME import org.tasks.makers.TaskMaker.DUE_TIME -import org.tasks.makers.TaskMaker.RRULE +import org.tasks.makers.TaskMaker.RECUR import org.tasks.makers.TaskMaker.newTask +import org.tasks.repeats.RecurrenceUtils.newRecur import org.tasks.time.DateTime import java.text.ParseException @@ -179,7 +178,7 @@ class NewRepeatTests { fun testAdvancedRepeatWeeklyFromDueDate() { val dueDateTime = newDayTime(2016, 8, 29, 0, 25) val task = newWeeklyFromDue( - 1, dueDateTime, WeekdayNum(0, Weekday.MO), WeekdayNum(0, Weekday.WE)) + 1, dueDateTime, WeekDay(WeekDay.MO, 0), WeekDay(WeekDay.WE, 0)) assertEquals(newDayTime(2016, 8, 31, 0, 25), calculateNextDueDate(task)) } @@ -192,8 +191,8 @@ class NewRepeatTests { 1, dueDateTime, completionDateTime, - WeekdayNum(0, Weekday.MO), - WeekdayNum(0, Weekday.WE)) + WeekDay(WeekDay.MO, 0), + WeekDay(WeekDay.WE, 0)) assertEquals(newDayTime(2016, 8, 29, 0, 25), calculateNextDueDate(task)) } @@ -206,8 +205,8 @@ class NewRepeatTests { 1, dueDateTime, completionDateTime, - WeekdayNum(0, Weekday.MO), - WeekdayNum(0, Weekday.WE)) + WeekDay(WeekDay.MO, 0), + WeekDay(WeekDay.WE, 0)) assertEquals(newDayTime(2016, 9, 5, 0, 25), calculateNextDueDate(task)) } @@ -221,19 +220,19 @@ class NewRepeatTests { @Throws(ParseException::class) private fun calculateNextDueDate(task: Task): DateTime { return DateTime( - RepeatTaskHelper.computeNextDueDate(task, task.sanitizedRecurrence(), task.repeatAfterCompletion())) + RepeatTaskHelper.computeNextDueDate(task, task.recurrence!!, task.repeatAfterCompletion())) } private fun newFromDue(frequency: Frequency, interval: Int, dueDateTime: DateTime): Task { return newTask( - with(RRULE, getRecurrenceRule(frequency, interval)), + with(RECUR, getRecurrenceRule(frequency, interval)), with(AFTER_COMPLETE, false), with(DUE_TIME, dueDateTime)) } - private fun newWeeklyFromDue(interval: Int, dueDateTime: DateTime, vararg weekdays: WeekdayNum): Task { + private fun newWeeklyFromDue(interval: Int, dueDateTime: DateTime, vararg weekdays: WeekDay): Task { return newTask( - with(RRULE, getRecurrenceRule(Frequency.WEEKLY, interval, *weekdays)), + with(RECUR, getRecurrenceRule(Frequency.WEEKLY, interval, *weekdays)), with(AFTER_COMPLETE, false), with(DUE_TIME, dueDateTime)) } @@ -241,29 +240,29 @@ class NewRepeatTests { private fun newFromCompleted( frequency: Frequency, interval: Int, dueDateTime: DateTime, completionDate: DateTime): Task { return newTask( - with(RRULE, getRecurrenceRule(frequency, interval)), + with(RECUR, getRecurrenceRule(frequency, interval)), with(AFTER_COMPLETE, true), with(DUE_TIME, dueDateTime), with(COMPLETION_TIME, completionDate)) } private fun newWeeklyFromCompleted( - interval: Int, dueDateTime: DateTime, completionDate: DateTime, vararg weekdays: WeekdayNum): Task { + interval: Int, dueDateTime: DateTime, completionDate: DateTime, vararg weekdays: WeekDay): Task { return newTask( - with(RRULE, getRecurrenceRule(Frequency.WEEKLY, interval, *weekdays)), + with(RECUR, getRecurrenceRule(Frequency.WEEKLY, interval, *weekdays)), with(AFTER_COMPLETE, true), with(DUE_TIME, dueDateTime), with(COMPLETION_TIME, completionDate)) } private fun getRecurrenceRule( - frequency: Frequency, interval: Int, vararg weekdays: WeekdayNum): RRule { - val rrule = RRule() - rrule.freq = frequency + frequency: Frequency, interval: Int, vararg weekdays: WeekDay): String { + val rrule = newRecur() + rrule.setFrequency(frequency.name) rrule.interval = interval if (weekdays.isNotEmpty()) { - rrule.byDay = listOf(*weekdays) + rrule.dayList.addAll(weekdays) } - return rrule + return rrule.toString() } } \ No newline at end of file diff --git a/app/src/test/java/com/todoroo/astrid/repeats/RepeatTaskHelperTest.kt b/app/src/test/java/com/todoroo/astrid/repeats/RepeatTaskHelperTest.kt index 9489d9c37..4c05622f9 100644 --- a/app/src/test/java/com/todoroo/astrid/repeats/RepeatTaskHelperTest.kt +++ b/app/src/test/java/com/todoroo/astrid/repeats/RepeatTaskHelperTest.kt @@ -1,7 +1,6 @@ package com.todoroo.astrid.repeats import android.annotation.SuppressLint -import com.google.ical.values.RRule import com.natpryce.makeiteasy.MakeItEasy.with import com.todoroo.astrid.alarms.AlarmService import com.todoroo.astrid.dao.TaskDao @@ -22,8 +21,9 @@ import org.tasks.makers.TaskMaker.AFTER_COMPLETE import org.tasks.makers.TaskMaker.COMPLETION_TIME import org.tasks.makers.TaskMaker.DUE_TIME import org.tasks.makers.TaskMaker.ID -import org.tasks.makers.TaskMaker.RRULE +import org.tasks.makers.TaskMaker.RECUR import org.tasks.makers.TaskMaker.newTask +import org.tasks.repeats.RecurrenceUtils.newRecur import org.tasks.time.DateTime import java.text.ParseException @@ -65,7 +65,7 @@ class RepeatTaskHelperTest { val task = newTask( with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), - with(RRULE, RRule("RRULE:FREQ=MINUTELY;INTERVAL=30"))) + with(RECUR, "RRULE:FREQ=MINUTELY;INTERVAL=30")) repeatAndVerify( task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 14, 0, 1)) } @@ -77,7 +77,7 @@ class RepeatTaskHelperTest { with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), with(COMPLETION_TIME, DateTime(2017, 10, 4, 13, 17, 45, 340)), - with(RRULE, RRule("RRULE:FREQ=MINUTELY;INTERVAL=30")), + with(RECUR, "RRULE:FREQ=MINUTELY;INTERVAL=30"), with(AFTER_COMPLETE, true)) repeatAndVerify( task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 13, 47, 1)) @@ -89,10 +89,10 @@ class RepeatTaskHelperTest { val task = newTask( with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), - with(RRULE, RRule("RRULE:FREQ=MINUTELY;COUNT=2;INTERVAL=30"))) + with(RECUR, "RRULE:FREQ=MINUTELY;COUNT=2;INTERVAL=30")) repeatAndVerify( task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 14, 0, 1)) - assertEquals(1, RRule(task.getRecurrenceWithoutFrom()).count) + assertEquals(1, newRecur(task.recurrence!!).count) } @Test @@ -101,7 +101,7 @@ class RepeatTaskHelperTest { val task = newTask( with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), - with(RRULE, RRule("RRULE:FREQ=MINUTELY;COUNT=1;INTERVAL=30"))) + with(RECUR, "RRULE:FREQ=MINUTELY;COUNT=1;INTERVAL=30")) helper.handleRepeat(task) } @@ -111,7 +111,7 @@ class RepeatTaskHelperTest { val task = newTask( with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), - with(RRULE, RRule("RRULE:FREQ=HOURLY;INTERVAL=6"))) + with(RECUR, "RRULE:FREQ=HOURLY;INTERVAL=6")) repeatAndVerify( task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 19, 30, 1)) } @@ -123,7 +123,7 @@ class RepeatTaskHelperTest { with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), with(COMPLETION_TIME, DateTime(2017, 10, 4, 13, 17, 45, 340)), - with(RRULE, RRule("RRULE:FREQ=HOURLY;INTERVAL=6")), + with(RECUR, "RRULE:FREQ=HOURLY;INTERVAL=6"), with(AFTER_COMPLETE, true)) repeatAndVerify( task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 4, 19, 17, 1)) @@ -135,7 +135,7 @@ class RepeatTaskHelperTest { val task = newTask( with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), - with(RRULE, RRule("RRULE:FREQ=DAILY;INTERVAL=6"))) + with(RECUR, "RRULE:FREQ=DAILY;INTERVAL=6")) repeatAndVerify( task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 10, 13, 30, 1)) } @@ -146,7 +146,7 @@ class RepeatTaskHelperTest { val task = newTask( with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), - with(RRULE, RRule("RRULE:FREQ=WEEKLY;INTERVAL=2"))) + with(RECUR, "RRULE:FREQ=WEEKLY;INTERVAL=2")) repeatAndVerify( task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2017, 10, 18, 13, 30, 1)) } @@ -157,7 +157,7 @@ class RepeatTaskHelperTest { val task = newTask( with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), - with(RRULE, RRule("RRULE:FREQ=YEARLY;INTERVAL=3"))) + with(RECUR, "RRULE:FREQ=YEARLY;INTERVAL=3")) repeatAndVerify( task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2020, 10, 4, 13, 30, 1)) } @@ -168,7 +168,7 @@ class RepeatTaskHelperTest { val task = newTask( with(ID, 1L), with(DUE_TIME, DateTime(2017, 10, 4, 13, 30)), - with(RRULE, RRule("RRULE:FREQ=MONTHLY;INTERVAL=3"))) + with(RECUR, "RRULE:FREQ=MONTHLY;INTERVAL=3")) repeatAndVerify( task, DateTime(2017, 10, 4, 13, 30, 1), DateTime(2018, 1, 4, 13, 30, 1)) } @@ -179,7 +179,7 @@ class RepeatTaskHelperTest { val task = newTask( with(ID, 1L), with(DUE_TIME, DateTime(2017, 1, 31, 13, 30)), - with(RRULE, RRule("RRULE:FREQ=MONTHLY;INTERVAL=1"))) + with(RECUR, "RRULE:FREQ=MONTHLY;INTERVAL=1")) repeatAndVerify( task, DateTime(2017, 1, 31, 13, 30, 1), DateTime(2017, 2, 28, 13, 30, 1)) } @@ -188,7 +188,7 @@ class RepeatTaskHelperTest { fun testAlarmShiftWithNoDueDate() { val task = newTask( with(ID, 1L), - with(RRULE, RRule("RRULE:FREQ=DAILY")) + with(RECUR, "RRULE:FREQ=DAILY") ) freezeClock { repeatAndVerify(