Add caldav manual sort task adapter tests

pull/996/head
Alex Baker 4 years ago
parent e6beaddbd6
commit f4d1410e3e

@ -0,0 +1,189 @@
package com.todoroo.astrid.adapter
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.natpryce.makeiteasy.MakeItEasy.with
import com.natpryce.makeiteasy.PropertyValue
import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.tasks.R
import org.tasks.data.CaldavCalendar
import org.tasks.data.CaldavDao
import org.tasks.data.TaskContainer
import org.tasks.data.TaskListQuery.getQuery
import org.tasks.injection.InjectingTestCase
import org.tasks.injection.TestComponent
import org.tasks.makers.CaldavTaskMaker.CALENDAR
import org.tasks.makers.CaldavTaskMaker.REMOTE_PARENT
import org.tasks.makers.CaldavTaskMaker.TASK
import org.tasks.makers.CaldavTaskMaker.newCaldavTask
import org.tasks.makers.TaskMaker.CREATION_TIME
import org.tasks.makers.TaskMaker.newTask
import org.tasks.preferences.Preferences
import org.tasks.time.DateTime
import javax.inject.Inject
@RunWith(AndroidJUnit4::class)
class CaldavManualSortTaskAdapterTest : InjectingTestCase() {
@Inject lateinit var taskDao: TaskDao
@Inject lateinit var caldavDao: CaldavDao
@Inject lateinit var preferences: Preferences
private lateinit var adapter: CaldavManualSortTaskAdapter
private val tasks = ArrayList<TaskContainer>()
private val filter = CaldavFilter(CaldavCalendar("calendar", "1234"))
private val dataSource = object : TaskAdapterDataSource {
override fun getItem(position: Int) = tasks[position]
override val itemCount get() = tasks.size
}
@Before
override fun setUp() {
super.setUp()
preferences.clear()
preferences.setBoolean(R.string.p_manual_sort, true)
tasks.clear()
adapter = CaldavManualSortTaskAdapter(taskDao, caldavDao)
adapter.setDataSource(dataSource)
}
@Test
fun moveToSamePositionIsNoop() {
val created = DateTime(2020, 5, 17, 9, 53, 17)
addTask(with(CREATION_TIME, created))
addTask(with(CREATION_TIME, created.plusSeconds(1)))
move(0, 0)
checkOrder(null, 0)
checkOrder(null, 1)
}
@Test
fun moveTaskToTopOfList() {
val created = DateTime(2020, 5, 17, 9, 53, 17)
addTask(with(CREATION_TIME, created))
addTask(with(CREATION_TIME, created.plusSeconds(1)))
move(1, 0)
checkOrder(1, 1)
checkOrder(null, 0)
}
@Test
fun moveTaskToBottomOfList() {
val created = DateTime(2020, 5, 17, 9, 53, 17)
addTask(with(CREATION_TIME, created))
addTask(with(CREATION_TIME, created.plusSeconds(1)))
move(0, 1)
checkOrder(null, 1)
checkOrder(created.plusSeconds(2), 0)
}
@Test
fun moveDownToMiddleOfList() {
val created = DateTime(2020, 5, 17, 9, 53, 17)
addTask(with(CREATION_TIME, created))
addTask(with(CREATION_TIME, created.plusSeconds(1)))
addTask(with(CREATION_TIME, created.plusSeconds(2)))
addTask(with(CREATION_TIME, created.plusSeconds(3)))
addTask(with(CREATION_TIME, created.plusSeconds(4)))
move(0, 2)
checkOrder(null, 1)
checkOrder(null, 2)
checkOrder(created.plusSeconds(3), 0)
checkOrder(created.plusSeconds(4), 3)
checkOrder(created.plusSeconds(5), 4)
}
@Test
fun moveUpToMiddleOfList() {
val created = DateTime(2020, 5, 17, 9, 53, 17)
addTask(with(CREATION_TIME, created))
addTask(with(CREATION_TIME, created.plusSeconds(1)))
addTask(with(CREATION_TIME, created.plusSeconds(2)))
addTask(with(CREATION_TIME, created.plusSeconds(3)))
addTask(with(CREATION_TIME, created.plusSeconds(4)))
move(3, 1)
checkOrder(null, 0)
checkOrder(created.plusSeconds(1), 3)
checkOrder(created.plusSeconds(2), 1)
checkOrder(created.plusSeconds(3), 2)
checkOrder(null, 4)
}
@Test
fun moveDownNoShiftRequired() {
val created = DateTime(2020, 5, 17, 9, 53, 17)
addTask(with(CREATION_TIME, created))
addTask(with(CREATION_TIME, created.plusSeconds(1)))
addTask(with(CREATION_TIME, created.plusSeconds(3)))
addTask(with(CREATION_TIME, created.plusSeconds(4)))
move(0, 1)
checkOrder(null, 1)
checkOrder(created.plusSeconds(2), 0)
checkOrder(null, 2)
checkOrder(null, 3)
}
@Test
fun moveUpNoShiftRequired() {
val created = DateTime(2020, 5, 17, 9, 53, 17)
addTask(with(CREATION_TIME, created))
addTask(with(CREATION_TIME, created.plusSeconds(2)))
addTask(with(CREATION_TIME, created.plusSeconds(3)))
addTask(with(CREATION_TIME, created.plusSeconds(4)))
move(2, 1)
checkOrder(null, 0)
checkOrder(created.plusSeconds(1), 2)
checkOrder(null, 1)
checkOrder(null, 3)
}
private fun move(from: Int, to: Int, indent: Int = 0) {
tasks.addAll(taskDao.fetchTasks { getQuery(preferences, filter, it) })
val adjustedTo = if (from < to) to + 1 else to // match DragAndDropRecyclerAdapter behavior
adapter.moved(from, adjustedTo, indent)
}
private fun checkOrder(dateTime: DateTime, index: Int) = checkOrder(dateTime.toAppleEpoch(), index)
private fun checkOrder(order: Long?, index: Int) {
val sortOrder = caldavDao.getTask(adapter.getTask(index).id)!!.order
if (order == null) {
assertNull(sortOrder)
} else {
assertEquals(order, sortOrder)
}
}
private fun addTask(vararg properties: PropertyValue<in Task?, *>) {
val task = newTask(*properties)
taskDao.createNew(task)
val remoteParent = if (task.parent > 0) caldavDao.getRemoteIdForTask(task.parent) else null
caldavDao.insert(
newCaldavTask(
with(TASK, task.id),
with(CALENDAR, "1234"),
with(REMOTE_PARENT, remoteParent)))
}
override fun inject(component: TestComponent) = component.inject(this)
}

@ -1,5 +1,6 @@
package org.tasks.injection
import com.todoroo.astrid.adapter.CaldavManualSortTaskAdapterTest
import com.todoroo.astrid.adapter.CaldavTaskAdapterTest
import com.todoroo.astrid.alarms.AlarmJobServiceTest
import com.todoroo.astrid.dao.TaskDaoTests
@ -44,4 +45,5 @@ interface TestComponent : ApplicationComponent {
fun inject(tests: CaldavTaskAdapterTest)
fun inject(tests: ManualGoogleTaskQueryTest)
fun inject(tests: CaldavDaoShiftTests)
fun inject(tests: CaldavManualSortTaskAdapterTest)
}

@ -2,38 +2,19 @@ package com.todoroo.astrid.adapter
import com.todoroo.astrid.dao.TaskDao
import org.tasks.data.CaldavDao
import org.tasks.data.TaskContainer
open class CaldavManualSortTaskAdapter internal constructor(private val taskDao: TaskDao, private val caldavDao: CaldavDao) : TaskAdapter() {
override fun canMove(source: TaskContainer, from: Int, target: TaskContainer, to: Int) = !taskIsChild(source, to)
override fun maxIndent(previousPosition: Int, task: TaskContainer) = getTask(previousPosition).getIndent() + 1
override fun minIndent(nextPosition: Int, task: TaskContainer): Int {
(nextPosition until count).forEach {
if (!taskIsChild(task, it)) {
return getTask(it).indent
}
}
return 0
}
override fun supportsParentingOrManualSort() = true
class CaldavManualSortTaskAdapter internal constructor(private val taskDao: TaskDao, private val caldavDao: CaldavDao) : CaldavTaskAdapter(taskDao, caldavDao) {
override fun supportsManualSorting() = true
override fun moved(from: Int, to: Int, indent: Int) {
val task = getTask(from)
val previous = if (to > 0) getTask(to - 1) else null
val newParent = findNewParent(indent, to)
val newParent = findNewParent(task, indent, to)
if (newParent == task.parent && from == to) {
if (from == to) {
return
}
if (newParent != task.parent) {
changeParent(task, newParent)
}
if (from != to) {
val newPosition = when {
previous == null -> 1
@ -46,50 +27,4 @@ open class CaldavManualSortTaskAdapter internal constructor(private val taskDao:
taskDao.touch(task.id)
}
internal fun findNewParent(indent: Int, to: Int): Long {
val previous = if (to > 0) getTask(to - 1) else null
return when {
indent == 0 || previous == null -> 0
indent == previous.getIndent() -> previous.parent
indent > previous.getIndent() -> previous.id
else -> {
var newParent = previous.parent
var currentIndex = to
for (i in 0 until previous.getIndent() - indent) {
var thisParent = newParent
while (newParent == thisParent) {
thisParent = getTask(--currentIndex).parent
}
newParent = thisParent
}
newParent
}
}
}
internal fun changeParent(task: TaskContainer, newParent: Long) {
val caldavTask = task.getCaldavTask()
if (newParent == 0L) {
caldavTask.cd_remote_parent = ""
task.parent = 0
} else {
val parentTask = caldavDao.getTask(newParent) ?: return
caldavTask.cd_remote_parent = parentTask.remoteId
task.parent = newParent
}
caldavDao.updateParent(caldavTask)
taskDao.save(task.getTask(), null)
}
private fun taskIsChild(source: TaskContainer, destinationIndex: Int): Boolean {
(destinationIndex downTo 0).forEach {
when (getTask(it).parent) {
0L -> return false
source.parent -> return false
source.id -> return true
}
}
return false
}
}

@ -2,15 +2,75 @@ package com.todoroo.astrid.adapter
import com.todoroo.astrid.dao.TaskDao
import org.tasks.data.CaldavDao
import org.tasks.data.TaskContainer
class CaldavTaskAdapter internal constructor(taskDao: TaskDao, caldavDao: CaldavDao) : CaldavManualSortTaskAdapter(taskDao, caldavDao) {
override fun supportsManualSorting() = false
open class CaldavTaskAdapter internal constructor(private val taskDao: TaskDao, private val caldavDao: CaldavDao) : TaskAdapter() {
override fun canMove(source: TaskContainer, from: Int, target: TaskContainer, to: Int) = !taskIsChild(source, to)
override fun maxIndent(previousPosition: Int, task: TaskContainer) = getTask(previousPosition).getIndent() + 1
override fun minIndent(nextPosition: Int, task: TaskContainer): Int {
(nextPosition until count).forEach {
if (!taskIsChild(task, it)) {
return getTask(it).indent
}
}
return 0
}
override fun supportsParentingOrManualSort() = true
override fun moved(from: Int, to: Int, indent: Int) {
val task = getTask(from)
val newParent = findNewParent(indent, to)
findNewParent(getTask(from), indent, to)
}
internal fun findNewParent(task: TaskContainer, indent: Int, to: Int): Long {
val previous = if (to > 0) getTask(to - 1) else null
val newParent = when {
indent == 0 || previous == null -> 0
indent == previous.getIndent() -> previous.parent
indent > previous.getIndent() -> previous.id
else -> {
var newParent = previous.parent
var currentIndex = to
for (i in 0 until previous.getIndent() - indent) {
var thisParent = newParent
while (newParent == thisParent) {
thisParent = getTask(--currentIndex).parent
}
newParent = thisParent
}
newParent
}
}
if (newParent != task.parent) {
changeParent(task, newParent)
}
return newParent
}
private fun changeParent(task: TaskContainer, newParent: Long) {
val caldavTask = task.getCaldavTask()
if (newParent == 0L) {
caldavTask.cd_remote_parent = ""
task.parent = 0
} else {
val parentTask = caldavDao.getTask(newParent) ?: return
caldavTask.cd_remote_parent = parentTask.remoteId
task.parent = newParent
}
caldavDao.updateParent(caldavTask)
taskDao.save(task.getTask(), null)
}
private fun taskIsChild(source: TaskContainer, destinationIndex: Int): Boolean {
(destinationIndex downTo 0).forEach {
when (getTask(it).parent) {
0L -> return false
source.parent -> return false
source.id -> return true
}
}
return false
}
}
Loading…
Cancel
Save