diff --git a/CHANGELOG.md b/CHANGELOG.md index ef882b502..301c6e24d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ Change Log --- ======= +### 9.7.3 (2020-07-07) + +* Fix Google Task bugs + ### 9.7.2 (2020-06-22) * Downgrade Mapbox SDK to remove non-free library (F-Droid only) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 079c9af54..3ae91825a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -43,8 +43,8 @@ android { defaultConfig { testApplicationId = "org.tasks.test" applicationId = "org.tasks" - versionCode = 90703 - versionName = "9.7.2" + versionCode = 90704 + versionName = "9.7.3" targetSdkVersion(Versions.targetSdk) minSdkVersion(Versions.minSdk) testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/androidTest/java/org/tasks/data/GoogleTaskDaoTests.kt b/app/src/androidTest/java/org/tasks/data/GoogleTaskDaoTests.kt index 5a6bdac85..46feeff52 100644 --- a/app/src/androidTest/java/org/tasks/data/GoogleTaskDaoTests.kt +++ b/app/src/androidTest/java/org/tasks/data/GoogleTaskDaoTests.kt @@ -13,6 +13,7 @@ import org.tasks.injection.TestComponent import org.tasks.makers.GoogleTaskMaker.LIST import org.tasks.makers.GoogleTaskMaker.PARENT import org.tasks.makers.GoogleTaskMaker.REMOTE_ID +import org.tasks.makers.GoogleTaskMaker.REMOTE_PARENT import org.tasks.makers.GoogleTaskMaker.TASK import org.tasks.makers.GoogleTaskMaker.newGoogleTask import org.tasks.makers.GtaskListMaker.newGtaskList @@ -153,6 +154,84 @@ class GoogleTaskDaoTests : InjectingTestCase() { assertEquals(listOf(2L), googleTaskDao.getChildren(listOf(1L, 2L))) } + @Test + fun dontAllowEmptyParent() { + googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1"), with(REMOTE_ID, "1234"))) + + googleTaskDao.updatePosition("1234", "", "0") + + assertNull(googleTaskDao.getByTaskId(1)!!.remoteParent) + } + + @Test + fun updatePosition() { + googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1"), with(REMOTE_ID, "1234"))) + + googleTaskDao.updatePosition("1234", "abcd", "0") + + assertEquals("abcd", googleTaskDao.getByTaskId(1)!!.remoteParent) + } + + @Test + fun updateParents() { + googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1"), with(REMOTE_ID, "123"))) + googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(REMOTE_PARENT, "123"))) + + googleTaskDao.updateParents() + + assertEquals(1, googleTaskDao.getByTaskId(2)!!.parent) + } + + @Test + fun updateParentsByList() { + googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1"), with(REMOTE_ID, "123"))) + googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(REMOTE_PARENT, "123"))) + + googleTaskDao.updateParents("1") + + assertEquals(1, googleTaskDao.getByTaskId(2)!!.parent) + } + + @Test + fun updateParentsMustMatchList() { + googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1"), with(REMOTE_ID, "123"))) + googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "2"), with(REMOTE_PARENT, "123"))) + + googleTaskDao.updateParents() + + assertEquals(0, googleTaskDao.getByTaskId(2)!!.parent) + } + + @Test + fun updateParentsByListMustMatchList() { + googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1"), with(REMOTE_ID, "123"))) + googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "2"), with(REMOTE_PARENT, "123"))) + + googleTaskDao.updateParents("2") + + assertEquals(0, googleTaskDao.getByTaskId(2)!!.parent) + } + + @Test + fun ignoreEmptyStringWhenUpdatingParents() { + googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1"), with(REMOTE_ID, ""))) + googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(REMOTE_ID, ""), with(REMOTE_PARENT, ""))) + + googleTaskDao.updateParents() + + assertEquals(0, googleTaskDao.getByTaskId(2)!!.parent) + } + + @Test + fun ignoreEmptyStringWhenUpdatingParentsForList() { + googleTaskDao.insert(newGoogleTask(with(TASK, 1), with(LIST, "1"), with(REMOTE_ID, ""))) + googleTaskDao.insert(newGoogleTask(with(TASK, 2), with(LIST, "1"), with(REMOTE_ID, ""), with(REMOTE_PARENT, ""))) + + googleTaskDao.updateParents("1") + + assertEquals(0, googleTaskDao.getByTaskId(2)!!.parent) + } + private fun insertTop(googleTask: GoogleTask) { insert(googleTask, true) } diff --git a/app/src/commonTest/java/org/tasks/makers/GoogleTaskMaker.kt b/app/src/commonTest/java/org/tasks/makers/GoogleTaskMaker.kt index 5123c4300..d29a02ff7 100644 --- a/app/src/commonTest/java/org/tasks/makers/GoogleTaskMaker.kt +++ b/app/src/commonTest/java/org/tasks/makers/GoogleTaskMaker.kt @@ -14,6 +14,7 @@ object GoogleTaskMaker { val REMOTE_ID: Property = newProperty() val TASK: Property = newProperty() val PARENT: Property = newProperty() + val REMOTE_PARENT: Property = newProperty() private val instantiator = Instantiator { val task = GoogleTask() @@ -22,6 +23,7 @@ object GoogleTaskMaker { task.remoteId = it.valueOf(REMOTE_ID, UUIDHelper.newUUID()) task.task = it.valueOf(TASK, 1) task.parent = it.valueOf(PARENT, 0L) + task.remoteParent = it.valueOf(REMOTE_PARENT, null as String?) task } diff --git a/app/src/main/java/com/todoroo/astrid/service/Upgrader.kt b/app/src/main/java/com/todoroo/astrid/service/Upgrader.kt index c34f4ee47..65b1081b1 100644 --- a/app/src/main/java/com/todoroo/astrid/service/Upgrader.kt +++ b/app/src/main/java/com/todoroo/astrid/service/Upgrader.kt @@ -31,6 +31,7 @@ class Upgrader @Inject constructor( private val filterDao: FilterDao, private val defaultFilterProvider: DefaultFilterProvider, private val googleTaskListDao: GoogleTaskListDao, + private val googleTaskDao: GoogleTaskDao, private val userActivityDao: UserActivityDao, private val taskAttachmentDao: TaskAttachmentDao, private val caldavDao: CaldavDao, @@ -66,6 +67,7 @@ class Upgrader @Inject constructor( taskMover.migrateLocalTasks() } run(from, V9_7) { googleTaskListDao.resetOrders() } + run(from, V9_7_3) { googleTaskDao.updateParents() } preferences.setBoolean(R.string.p_just_updated, true) } preferences.setCurrentVersion(to) @@ -309,6 +311,7 @@ class Upgrader @Inject constructor( private const val V9_3 = 90300 const val V9_6 = 90600 const val V9_7 = 90700 + const val V9_7_3 = 90704 @JvmStatic fun getAndroidColor(context: Context, index: Int): Int { diff --git a/app/src/main/java/org/tasks/data/GoogleTask.kt b/app/src/main/java/org/tasks/data/GoogleTask.kt index d1fb1f69e..caab7a7d4 100644 --- a/app/src/main/java/org/tasks/data/GoogleTask.kt +++ b/app/src/main/java/org/tasks/data/GoogleTask.kt @@ -1,8 +1,6 @@ package org.tasks.data import androidx.room.* -import com.todoroo.andlib.data.Property -import com.todoroo.andlib.data.Property.* import com.todoroo.andlib.data.Table @Entity(tableName = "google_tasks", @@ -31,6 +29,9 @@ class GoogleTask { @ColumnInfo(name = "gt_remote_parent") var remoteParent: String? = null + set(value) { + field = if (value?.isNotBlank() == true) value else null + } @ColumnInfo(name = "gt_moved") @Transient diff --git a/app/src/main/java/org/tasks/data/GoogleTaskDao.kt b/app/src/main/java/org/tasks/data/GoogleTaskDao.kt index 0f1a69da6..fdb972730 100644 --- a/app/src/main/java/org/tasks/data/GoogleTaskDao.kt +++ b/app/src/main/java/org/tasks/data/GoogleTaskDao.kt @@ -117,20 +117,39 @@ abstract class GoogleTaskDao { @Query("SELECT google_tasks.*, gt_remote_order AS primary_sort, NULL AS secondary_sort FROM google_tasks JOIN tasks ON tasks._id = gt_task WHERE gt_parent = 0 AND gt_list_id = :listId AND tasks.deleted = 0 UNION SELECT c.*, p.gt_remote_order AS primary_sort, c.gt_remote_order AS secondary_sort FROM google_tasks AS c LEFT JOIN google_tasks AS p ON c.gt_parent = p.gt_task JOIN tasks ON tasks._id = c.gt_task WHERE c.gt_parent > 0 AND c.gt_list_id = :listId AND tasks.deleted = 0 ORDER BY primary_sort ASC, secondary_sort ASC") abstract fun getByRemoteOrder(listId: String): List - @Query("UPDATE google_tasks" - + " SET gt_parent = IFNULL((" - + " SELECT gt_task FROM google_tasks AS p" - + " WHERE p.gt_remote_id = google_tasks.gt_remote_parent" - + " AND p.gt_list_id = google_tasks.gt_list_id " - + " AND p.gt_deleted = 0)," - + " 0)" - + " WHERE gt_moved = 0") + @Query(""" +UPDATE google_tasks +SET gt_parent = IFNULL((SELECT gt_task + FROM google_tasks AS p + WHERE google_tasks.gt_remote_parent IS NOT NULL + AND google_tasks.gt_remote_parent != '' + AND p.gt_remote_id = google_tasks.gt_remote_parent + AND p.gt_list_id = google_tasks.gt_list_id + AND p.gt_deleted = 0), 0) +WHERE gt_moved = 0 + """) abstract fun updateParents() - @Query("UPDATE google_tasks SET gt_parent = IFNULL((SELECT gt_task FROM google_tasks AS p WHERE p.gt_remote_id = google_tasks.gt_remote_parent), 0) WHERE gt_list_id = :listId AND gt_moved = 0") + @Query(""" +UPDATE google_tasks +SET gt_parent = IFNULL((SELECT gt_task + FROM google_tasks AS p + WHERE google_tasks.gt_remote_parent IS NOT NULL + AND google_tasks.gt_remote_parent != '' + AND p.gt_remote_id = google_tasks.gt_remote_parent + AND p.gt_list_id = google_tasks.gt_list_id + AND p.gt_deleted = 0), 0) +WHERE gt_list_id = :listId + AND gt_moved = 0 + """) abstract fun updateParents(listId: String) - @Query("UPDATE google_tasks SET gt_remote_parent = :parent, gt_remote_order = :position WHERE gt_remote_id = :id") + @Query(""" +UPDATE google_tasks +SET gt_remote_parent = CASE WHEN :parent == '' THEN NULL ELSE :parent END, + gt_remote_order = :position +WHERE gt_remote_id = :id + """) abstract fun updatePosition(id: String, parent: String, position: String) @Transaction diff --git a/app/src/main/res/values/changelog.xml b/app/src/main/res/values/changelog.xml index a7982bc3f..413b0a1af 100644 --- a/app/src/main/res/values/changelog.xml +++ b/app/src/main/res/values/changelog.xml @@ -1,6 +1,7 @@ - Downgrade Mapbox SDK to remove non-free library (F-Droid only) + Fix Google Task bugs + Join Tasks on Reddit: https://reddit.com/r/tasks diff --git a/fastlane/metadata/android/en-US/changelogs/90704.txt b/fastlane/metadata/android/en-US/changelogs/90704.txt new file mode 100644 index 000000000..56d0bfdb4 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/90704.txt @@ -0,0 +1 @@ +* Fix Google Task bugs