From d0fd159efe9ceafba25322aa65e6de1d1dcf5ae2 Mon Sep 17 00:00:00 2001 From: Marten Gajda Date: Sat, 14 Sep 2019 06:12:24 +0200 Subject: [PATCH] Ignore recurrence if start and due are absent, fixes #841 (#844) Apparently there are tasks which have a recurrence rule but neither a dtstart nor a due date. This caused an NPE. By treating such tasks as non-recurring this should be fixed. --- .../dmfs/provider/tasks/TaskProviderTest.java | 38 +++++++++++++++++++ .../tasks/model/AbstractTaskAdapter.java | 3 +- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/opentasks-provider/src/androidTest/java/org/dmfs/provider/tasks/TaskProviderTest.java b/opentasks-provider/src/androidTest/java/org/dmfs/provider/tasks/TaskProviderTest.java index 911f43d53..47a8d9d3e 100644 --- a/opentasks-provider/src/androidTest/java/org/dmfs/provider/tasks/TaskProviderTest.java +++ b/opentasks-provider/src/androidTest/java/org/dmfs/provider/tasks/TaskProviderTest.java @@ -53,6 +53,7 @@ import org.dmfs.opentaskspal.tasklists.NameData; import org.dmfs.opentaskspal.tasks.OriginalInstanceData; import org.dmfs.opentaskspal.tasks.OriginalInstanceSyncIdData; +import org.dmfs.opentaskspal.tasks.RRuleTaskData; import org.dmfs.opentaskspal.tasks.StatusData; import org.dmfs.opentaskspal.tasks.SyncIdData; import org.dmfs.opentaskspal.tasks.TimeData; @@ -61,6 +62,8 @@ import org.dmfs.opentaskstestpal.InstanceTestData; import org.dmfs.rfc5545.DateTime; import org.dmfs.rfc5545.Duration; +import org.dmfs.rfc5545.recur.InvalidRecurrenceRuleException; +import org.dmfs.rfc5545.recur.RecurrenceRule; import org.dmfs.tasks.contract.TaskContract.Instances; import org.dmfs.tasks.contract.TaskContract.TaskLists; import org.dmfs.tasks.contract.TaskContract.Tasks; @@ -904,4 +907,39 @@ public void testMoveTaskInstanceAsSyncAdapter() throws Exception )); } + + /** + * Create task with start and due, check datetime values including generated duration. + */ + @Test + public void testInsertTaskWithoutStartAndDueButRRULE() throws InvalidRecurrenceRuleException + { + RowSnapshot taskList = new VirtualRowSnapshot<>(new LocalTaskListsTable(mAuthority)); + RowSnapshot task = new VirtualRowSnapshot<>(new TaskListScoped(taskList, new TasksTable(mAuthority))); + + DateTime start = DateTime.now(); + DateTime due = start.addDuration(new Duration(1, 1, 0)); + + assertThat(new Seq<>( + new Put<>(taskList, new EmptyRowData<>()), + new Put<>(task, new Composite<>( + new TitleData("test"), + new RRuleTaskData(new RecurrenceRule("FREQ=DAILY;COUNT=5", RecurrenceRule.RfcMode.RFC2445_LAX))))), + resultsIn(mClient, + new Assert<>(task, new Composite<>( + new TitleData("test"), + new VersionData(0))), + new AssertRelated<>( + new InstanceTable(mAuthority), Instances.TASK_ID, task, + new Composite<>( + new CharSequenceRowData<>(Tasks.TITLE, "test"), + new InstanceTestData( + absent(), + absent(), + absent(), + 0), + new CharSequenceRowData<>(Tasks.TZ, null)) + ))); + } + } diff --git a/opentasks-provider/src/main/java/org/dmfs/provider/tasks/model/AbstractTaskAdapter.java b/opentasks-provider/src/main/java/org/dmfs/provider/tasks/model/AbstractTaskAdapter.java index 5ca586e56..1f23f7735 100644 --- a/opentasks-provider/src/main/java/org/dmfs/provider/tasks/model/AbstractTaskAdapter.java +++ b/opentasks-provider/src/main/java/org/dmfs/provider/tasks/model/AbstractTaskAdapter.java @@ -44,7 +44,8 @@ public Uri uri(String authority) @Override public boolean isRecurring() { - return valueOf(RRULE) != null || valueOf(RDATE).iterator().hasNext(); + // recurring tasks must have an RRULE or RDATEs and at least one of DTSTART and DUE date + return (valueOf(RRULE) != null || valueOf(RDATE).iterator().hasNext()) && (valueOf(DTSTART) != null || valueOf(DUE) != null); }