Fix CalDAV findChildrenInList

gtask_related_email
Alex Baker 5 years ago
parent 9f6a6b4b04
commit 2339884fec

@ -1,9 +1,14 @@
package org.tasks.data;
import static com.natpryce.makeiteasy.MakeItEasy.with;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.tasks.makers.CaldavTaskMaker.CALENDAR;
import static org.tasks.makers.CaldavTaskMaker.REMOTE_ID;
import static org.tasks.makers.CaldavTaskMaker.REMOTE_PARENT;
import static org.tasks.makers.CaldavTaskMaker.newCaldavTask;
import static org.tasks.makers.TagDataMaker.newTagData;
import static org.tasks.makers.TagMaker.TAGDATA;
import static org.tasks.makers.TagMaker.TASK;
@ -12,6 +17,8 @@ import static org.tasks.makers.TaskMaker.ID;
import static org.tasks.makers.TaskMaker.newTask;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SdkSuppress;
import com.google.common.primitives.Longs;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task;
import javax.inject.Inject;
@ -19,6 +26,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.tasks.injection.InjectingTestCase;
import org.tasks.injection.TestComponent;
import org.tasks.makers.CaldavTaskMaker;
@RunWith(AndroidJUnit4.class)
public class CaldavDaoTests extends InjectingTestCase {
@ -63,6 +71,74 @@ public class CaldavDaoTests extends InjectingTestCase {
assertTrue(caldavDao.getTasksWithTags().isEmpty());
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void findChildrenInList() {
taskDao.createNew(newTask(with(ID, 1L)));
taskDao.createNew(newTask(with(ID, 2L)));
caldavDao.insert(
asList(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(CaldavTaskMaker.PARENT, 1L),
with(REMOTE_PARENT, "a"))));
assertEquals(singletonList(2L), caldavDao.findChildrenInList(Longs.asList(1, 2)));
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void findRecursiveChildrenInList() {
taskDao.createNew(newTask(with(ID, 1L)));
taskDao.createNew(newTask(with(ID, 2L)));
taskDao.createNew(newTask(with(ID, 3L)));
caldavDao.insert(
asList(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(CaldavTaskMaker.PARENT, 1L),
with(REMOTE_ID, "b"),
with(REMOTE_PARENT, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 3L),
with(CALENDAR, "1"),
with(CaldavTaskMaker.PARENT, 2L),
with(REMOTE_PARENT, "b"))));
assertEquals(asList(2L, 3L), caldavDao.findChildrenInList(Longs.asList(1, 2, 3)));
}
@Test
@SdkSuppress(minSdkVersion = 21)
public void findRecursiveChildrenInListAfterSkippingParent() {
taskDao.createNew(newTask(with(ID, 1L)));
taskDao.createNew(newTask(with(ID, 2L)));
taskDao.createNew(newTask(with(ID, 3L)));
caldavDao.insert(
asList(
newCaldavTask(
with(CaldavTaskMaker.TASK, 1L), with(CALENDAR, "1"), with(REMOTE_ID, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 2L),
with(CALENDAR, "1"),
with(CaldavTaskMaker.PARENT, 1L),
with(REMOTE_ID, "b"),
with(REMOTE_PARENT, "a")),
newCaldavTask(
with(CaldavTaskMaker.TASK, 3L),
with(CALENDAR, "1"),
with(CaldavTaskMaker.PARENT, 2L),
with(REMOTE_PARENT, "b"))));
assertEquals(singletonList(3L), caldavDao.findChildrenInList(Longs.asList(1, 3)));
}
@Override
protected void inject(TestComponent component) {
component.inject(this);

@ -0,0 +1,34 @@
package org.tasks.makers;
import static com.natpryce.makeiteasy.Property.newProperty;
import static org.tasks.makers.Maker.make;
import com.google.common.base.Strings;
import com.natpryce.makeiteasy.Instantiator;
import com.natpryce.makeiteasy.Property;
import com.natpryce.makeiteasy.PropertyValue;
import org.tasks.data.CaldavTask;
public class CaldavTaskMaker {
public static final Property<CaldavTask, String> CALENDAR = newProperty();
public static final Property<CaldavTask, Long> TASK = newProperty();
public static final Property<CaldavTask, Long> PARENT = newProperty();
public static final Property<CaldavTask, String> REMOTE_ID = newProperty();
public static final Property<CaldavTask, String> REMOTE_PARENT = newProperty();
private static final Instantiator<CaldavTask> instantiator =
lookup -> {
CaldavTask task =
new CaldavTask(lookup.valueOf(TASK, 1L), lookup.valueOf(CALENDAR, "calendar"));
task.setParent(lookup.valueOf(PARENT, 0L));
task.setRemoteId(lookup.valueOf(REMOTE_ID, task.getRemoteId()));
task.setRemoteParent(lookup.valueOf(REMOTE_PARENT, (String) null));
return task;
};
@SafeVarargs
public static CaldavTask newCaldavTask(PropertyValue<? super CaldavTask, ?>... properties) {
return make(instantiator, properties);
}
}

@ -1,5 +1,6 @@
package org.tasks.data;
import static com.google.common.collect.Lists.newArrayList;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
import static org.tasks.db.DbUtils.collect;
@ -194,28 +195,8 @@ public abstract class CaldavDao {
abstract List<Long> getChildrenRecursive(List<Long> ids);
public List<Long> findChildrenInList(List<Long> ids) {
return atLeastLollipop()
? findChildrenInListRecursive(ids)
: Collections.emptyList();
List<Long> result = newArrayList(ids);
result.retainAll(getChildren(ids));
return result;
}
@Query("WITH RECURSIVE "
+ " recursive_caldav (cd_task) AS ( "
+ " SELECT cd_task "
+ " FROM tasks "
+ " INNER JOIN caldav_tasks "
+ " ON _id = cd_task "
+ " WHERE cd_parent IN (:ids) AND cd_task IN (:ids)"
+ " AND tasks.deleted = 0 AND caldav_tasks.cd_deleted = 0 "
+ "UNION ALL "
+ " SELECT caldav_tasks.cd_task "
+ " FROM tasks "
+ " INNER JOIN caldav_tasks "
+ " ON _id = caldav_tasks.cd_task "
+ " INNER JOIN recursive_caldav "
+ " ON recursive_caldav.cd_task = caldav_tasks.cd_parent "
+ " WHERE tasks.deleted = 0 AND caldav_tasks.cd_deleted = 0 "
+ " ) "
+ "SELECT cd_task FROM recursive_caldav")
abstract List<Long> findChildrenInListRecursive(List<Long> ids);
}

Loading…
Cancel
Save