From 01349c51977ccd1987f753663997be91850c1777 Mon Sep 17 00:00:00 2001 From: Matt Vaughn Date: Thu, 15 Feb 2024 09:51:09 -0500 Subject: [PATCH] Allow Deletion of Preset Phrases --- .../7.json | 10 +++--- .../willowtree/vocable/PhrasesUseCaseTest.kt | 35 +++++++++++++++++++ .../RoomPresetPhrasesRepositoryTest.kt | 3 +- ...tubLegacyCategoriesAndPhrasesRepository.kt | 2 -- .../com/willowtree/vocable/PhrasesUseCase.kt | 9 +++-- .../ILegacyCategoriesAndPhrasesRepository.kt | 1 - .../LegacyCategoriesAndPhrasesRepository.kt | 8 ----- .../com/willowtree/vocable/presets/Phrase.kt | 6 ++-- .../vocable/room/PresetPhraseDto.kt | 2 +- .../vocable/room/PresetPhrasesDao.kt | 4 +-- .../vocable/room/PresetPhrasesRepository.kt | 5 ++- .../room/RoomPresetPhrasesRepository.kt | 16 ++++----- .../room/RoomStoredPhrasesRepository.kt | 4 +++ .../vocable/room/StoredPhrasesRepository.kt | 1 + ...akeLegacyCategoriesAndPhrasesRepository.kt | 4 --- 15 files changed, 67 insertions(+), 43 deletions(-) diff --git a/app/schemas/com.willowtree.vocable.room.VocableDatabase/7.json b/app/schemas/com.willowtree.vocable.room.VocableDatabase/7.json index 50945a1d..2448c3fd 100644 --- a/app/schemas/com.willowtree.vocable.room.VocableDatabase/7.json +++ b/app/schemas/com.willowtree.vocable.room.VocableDatabase/7.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 7, - "identityHash": "85eddb23319bc66076dc3049648b8948", + "identityHash": "594aeaa35a106dec45ceb3c0c04fb345", "entities": [ { "tableName": "Category", @@ -138,7 +138,7 @@ }, { "tableName": "PresetPhrase", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`phrase_id` TEXT NOT NULL, `parent_category_id` TEXT NOT NULL, `creation_date` INTEGER NOT NULL, `last_spoken_date` INTEGER, `sort_order` INTEGER NOT NULL, `hidden` INTEGER NOT NULL, PRIMARY KEY(`phrase_id`))", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`phrase_id` TEXT NOT NULL, `parent_category_id` TEXT NOT NULL, `creation_date` INTEGER NOT NULL, `last_spoken_date` INTEGER, `sort_order` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, PRIMARY KEY(`phrase_id`))", "fields": [ { "fieldPath": "phraseId", @@ -171,8 +171,8 @@ "notNull": true }, { - "fieldPath": "hidden", - "columnName": "hidden", + "fieldPath": "deleted", + "columnName": "deleted", "affinity": "INTEGER", "notNull": true } @@ -190,7 +190,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '85eddb23319bc66076dc3049648b8948')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '594aeaa35a106dec45ceb3c0c04fb345')" ] } } \ No newline at end of file diff --git a/app/src/androidTest/java/com/willowtree/vocable/PhrasesUseCaseTest.kt b/app/src/androidTest/java/com/willowtree/vocable/PhrasesUseCaseTest.kt index cabd592b..8a5e4623 100644 --- a/app/src/androidTest/java/com/willowtree/vocable/PhrasesUseCaseTest.kt +++ b/app/src/androidTest/java/com/willowtree/vocable/PhrasesUseCaseTest.kt @@ -202,4 +202,39 @@ class PhrasesUseCaseTest { .singleOrNull { it.phraseId == phraseId } as CustomPhrase assertEquals(localizedUtterance, newCustomPhrase.localizedUtterance) } + + @Test + fun deletePhrase_deletesFromStoredRepository() = runTest { + val useCase = createUseCase() + val customPhraseId = "1" + storedPhrasesRepository.addPhrase( + PhraseDto( + phraseId = customPhraseId, + localizedUtterance = testLocalesWithText, + parentCategoryId = PresetCategories.GENERAL.id, + creationDate = 0L, + lastSpokenDate = 100L, + sortOrder = 0 + ) + ) + + useCase.deletePhrase(customPhraseId) + + val storedPhrase = useCase.getPhrasesForCategory(PresetCategories.GENERAL.id) + .firstOrNull { it.phraseId == customPhraseId } + assertEquals(null, storedPhrase) + } + + @Test + fun deletePhrase_deletesFromPresetRepository() = runTest { + val useCase = createUseCase() + val presetPhraseId = "category_123_0" + presetPhrasesRepository.populateDatabase() + + useCase.deletePhrase(presetPhraseId) + + val presetPhrase = useCase.getPhrasesForCategory(PresetCategories.USER_KEYPAD.id) + .firstOrNull { it.phraseId == presetPhraseId } + assertEquals(null, presetPhrase) + } } \ No newline at end of file diff --git a/app/src/androidTest/java/com/willowtree/vocable/presets/RoomPresetPhrasesRepositoryTest.kt b/app/src/androidTest/java/com/willowtree/vocable/presets/RoomPresetPhrasesRepositoryTest.kt index 15c6a755..8789ea7e 100644 --- a/app/src/androidTest/java/com/willowtree/vocable/presets/RoomPresetPhrasesRepositoryTest.kt +++ b/app/src/androidTest/java/com/willowtree/vocable/presets/RoomPresetPhrasesRepositoryTest.kt @@ -67,7 +67,8 @@ class RoomPresetPhrasesRepositoryTest { phraseId = phraseEntryName, sortOrder = index, lastSpokenDate = null, - parentCategoryId = presetCategory.id + parentCategoryId = presetCategory.id, + deleted = false, ) ) } diff --git a/app/src/androidTest/java/com/willowtree/vocable/utility/StubLegacyCategoriesAndPhrasesRepository.kt b/app/src/androidTest/java/com/willowtree/vocable/utility/StubLegacyCategoriesAndPhrasesRepository.kt index 568c66e2..7e26d6e6 100644 --- a/app/src/androidTest/java/com/willowtree/vocable/utility/StubLegacyCategoriesAndPhrasesRepository.kt +++ b/app/src/androidTest/java/com/willowtree/vocable/utility/StubLegacyCategoriesAndPhrasesRepository.kt @@ -17,8 +17,6 @@ class StubLegacyCategoriesAndPhrasesRepository : ILegacyCategoriesAndPhrasesRepo override suspend fun getAllCategories() = error("Not implemented") - override suspend fun deletePhrase(phraseId: String) = error("Not implemented") - override suspend fun updateCategorySortOrders(categorySortOrders: List) = error("Not implemented") diff --git a/app/src/main/java/com/willowtree/vocable/PhrasesUseCase.kt b/app/src/main/java/com/willowtree/vocable/PhrasesUseCase.kt index 89ae00d6..83e856c1 100644 --- a/app/src/main/java/com/willowtree/vocable/PhrasesUseCase.kt +++ b/app/src/main/java/com/willowtree/vocable/PhrasesUseCase.kt @@ -35,12 +35,14 @@ class PhrasesUseCase( } override suspend fun deletePhrase(phraseId: String) { - legacyPhrasesRepository.deletePhrase(phraseId) + storedPhrasesRepository.deletePhrase(phraseId) + presetPhrasesRepository.deletePhrase(phraseId) } override suspend fun updatePhrase(phraseId: String, localizedUtterance: LocalesWithText) { val phrase = storedPhrasesRepository.getPhrase(phraseId) ?: presetPhrasesRepository.getPhrase(phraseId) + .takeIf { it != null && !it.deleted } when (phrase) { is CustomPhrase -> { storedPhrasesRepository.updatePhraseLocalizedUtterance( @@ -49,10 +51,7 @@ class PhrasesUseCase( ) } is PresetPhrase -> { - presetPhrasesRepository.updatePhraseHidden( - phraseId = phraseId, - hidden = true, - ) + presetPhrasesRepository.deletePhrase(phraseId = phraseId) // add a custom phrase to "shadow" over the preset storedPhrasesRepository.addPhrase( PhraseDto( diff --git a/app/src/main/java/com/willowtree/vocable/presets/ILegacyCategoriesAndPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/presets/ILegacyCategoriesAndPhrasesRepository.kt index ab7a512d..1540d4e0 100644 --- a/app/src/main/java/com/willowtree/vocable/presets/ILegacyCategoriesAndPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/presets/ILegacyCategoriesAndPhrasesRepository.kt @@ -20,7 +20,6 @@ interface ILegacyCategoriesAndPhrasesRepository { * Return all categories, sorted by [CategoryDto.sortOrder] */ suspend fun getAllCategories(): List - suspend fun deletePhrase(phraseId: String) suspend fun updateCategorySortOrders(categorySortOrders: List) suspend fun updateCategoryName(categoryId: String, localizedName: LocalesWithText) suspend fun updateCategoryHidden(categoryId: String, hidden: Boolean) diff --git a/app/src/main/java/com/willowtree/vocable/presets/LegacyCategoriesAndPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/presets/LegacyCategoriesAndPhrasesRepository.kt index a6d0bd0b..d31c26c3 100644 --- a/app/src/main/java/com/willowtree/vocable/presets/LegacyCategoriesAndPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/presets/LegacyCategoriesAndPhrasesRepository.kt @@ -30,14 +30,6 @@ class LegacyCategoriesAndPhrasesRepository( override suspend fun getRecentPhrases(): List = database.phraseDao().getRecentPhrases() - private suspend fun populatePhrases(phrases: List) { - database.phraseDao().insertPhrases(*phrases.toTypedArray()) - } - - override suspend fun deletePhrase(phraseId: String) { - database.phraseDao().deletePhrase(phraseId) - } - override suspend fun updateCategorySortOrders(categorySortOrders: List) { database.categoryDao().updateCategorySortOrders(categorySortOrders) } diff --git a/app/src/main/java/com/willowtree/vocable/presets/Phrase.kt b/app/src/main/java/com/willowtree/vocable/presets/Phrase.kt index 613be434..c3c9b054 100644 --- a/app/src/main/java/com/willowtree/vocable/presets/Phrase.kt +++ b/app/src/main/java/com/willowtree/vocable/presets/Phrase.kt @@ -34,6 +34,7 @@ data class PresetPhrase( override val phraseId: String, override val sortOrder: Int, override val lastSpokenDate: Long?, + val deleted: Boolean, val parentCategoryId: String?, ) : Phrase { @@ -49,7 +50,7 @@ data class PresetPhrase( fun PhraseDto.asPhrase(): Phrase = CustomPhrase( - phraseId = phraseId.toString(), + phraseId = phraseId, sortOrder = sortOrder, localizedUtterance = localizedUtterance, lastSpokenDate = lastSpokenDate, @@ -60,5 +61,6 @@ fun PresetPhraseDto.asPhrase(): PresetPhrase = phraseId = phraseId, sortOrder = sortOrder, lastSpokenDate = lastSpokenDate, - parentCategoryId = parentCategoryId + parentCategoryId = parentCategoryId, + deleted = deleted, ) diff --git a/app/src/main/java/com/willowtree/vocable/room/PresetPhraseDto.kt b/app/src/main/java/com/willowtree/vocable/room/PresetPhraseDto.kt index aa75a91d..81e0bf20 100644 --- a/app/src/main/java/com/willowtree/vocable/room/PresetPhraseDto.kt +++ b/app/src/main/java/com/willowtree/vocable/room/PresetPhraseDto.kt @@ -14,5 +14,5 @@ data class PresetPhraseDto( @ColumnInfo(name = "creation_date") val creationDate: Long, @ColumnInfo(name = "last_spoken_date") val lastSpokenDate: Long?, @ColumnInfo(name = "sort_order") val sortOrder: Int, - @ColumnInfo(name = "hidden") val hidden: Boolean = false + @ColumnInfo(name = "deleted") val deleted: Boolean = false, ) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesDao.kt b/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesDao.kt index c601fe5c..80e7fc7a 100644 --- a/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesDao.kt +++ b/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesDao.kt @@ -27,6 +27,6 @@ interface PresetPhrasesDao { @Query("SELECT * FROM PresetPhrase WHERE phrase_id = :phraseId") suspend fun getPhrase(phraseId: String): PresetPhraseDto? - @Query("UPDATE PresetPhrase SET hidden = :hidden WHERE phrase_id = :phraseId") - suspend fun updatePhraseHidden(phraseId: String, hidden: Boolean) + @Query("UPDATE PresetPhrase SET deleted = :deleted WHERE phrase_id = :phraseId") + suspend fun deletePhrase(phraseId: String, deleted: Boolean) } diff --git a/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesRepository.kt index b0b55e1d..d86937ae 100644 --- a/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesRepository.kt @@ -1,6 +1,5 @@ package com.willowtree.vocable.room -import com.willowtree.vocable.presets.Phrase import com.willowtree.vocable.presets.PresetPhrase interface PresetPhrasesRepository { @@ -9,6 +8,6 @@ interface PresetPhrasesRepository { suspend fun updatePhraseLastSpokenTime(phraseId: String) suspend fun getRecentPhrases() : List suspend fun getPhrasesForCategory(categoryId: String): List - suspend fun getPhrase(phraseId: String): Phrase? - suspend fun updatePhraseHidden(phraseId: String, hidden: Boolean) + suspend fun getPhrase(phraseId: String): PresetPhrase? + suspend fun deletePhrase(phraseId: String) } \ No newline at end of file diff --git a/app/src/main/java/com/willowtree/vocable/room/RoomPresetPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/room/RoomPresetPhrasesRepository.kt index aa594768..dc8e33d0 100644 --- a/app/src/main/java/com/willowtree/vocable/room/RoomPresetPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/room/RoomPresetPhrasesRepository.kt @@ -36,28 +36,26 @@ class RoomPresetPhrasesRepository( override suspend fun getRecentPhrases(): List { return presetPhrasesDao.getRecentPhrases() - .filterHiddenPresets() + .filterDeletedPresets() .map { it.asPhrase()} } override suspend fun getPhrasesForCategory(categoryId: String): List { return presetPhrasesDao.getPhrasesForCategory(categoryId) - .filterHiddenPresets() + .filterDeletedPresets() .map { it.asPhrase() } } override suspend fun getPhrase(phraseId: String): PresetPhrase? { - return presetPhrasesDao.getPhrase(phraseId) - .takeIf { it?.hidden != true } - ?.asPhrase() + return presetPhrasesDao.getPhrase(phraseId)?.asPhrase() } - override suspend fun updatePhraseHidden(phraseId: String, hidden: Boolean) { - presetPhrasesDao.updatePhraseHidden(phraseId, hidden) + override suspend fun deletePhrase(phraseId: String) { + presetPhrasesDao.deletePhrase(phraseId, deleted = true) } - private fun List.filterHiddenPresets() : List { - return filterNot { it.hidden } + private fun List.filterDeletedPresets() : List { + return filterNot { it.deleted } } private suspend fun ensurePopulated() { diff --git a/app/src/main/java/com/willowtree/vocable/room/RoomStoredPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/room/RoomStoredPhrasesRepository.kt index b2dc1ab2..1e326cce 100644 --- a/app/src/main/java/com/willowtree/vocable/room/RoomStoredPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/room/RoomStoredPhrasesRepository.kt @@ -49,4 +49,8 @@ class RoomStoredPhrasesRepository( ) ) } + + override suspend fun deletePhrase(phraseId: String) { + database.phraseDao().deletePhrase(phraseId) + } } \ No newline at end of file diff --git a/app/src/main/java/com/willowtree/vocable/room/StoredPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/room/StoredPhrasesRepository.kt index 969b7ee0..aaec6384 100644 --- a/app/src/main/java/com/willowtree/vocable/room/StoredPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/room/StoredPhrasesRepository.kt @@ -14,4 +14,5 @@ interface StoredPhrasesRepository { phraseId: String, localizedUtterance: LocalesWithText, ) + suspend fun deletePhrase(phraseId: String) } \ No newline at end of file diff --git a/app/src/test/java/com/willowtree/vocable/presets/FakeLegacyCategoriesAndPhrasesRepository.kt b/app/src/test/java/com/willowtree/vocable/presets/FakeLegacyCategoriesAndPhrasesRepository.kt index 65b446d3..63aa2f2a 100644 --- a/app/src/test/java/com/willowtree/vocable/presets/FakeLegacyCategoriesAndPhrasesRepository.kt +++ b/app/src/test/java/com/willowtree/vocable/presets/FakeLegacyCategoriesAndPhrasesRepository.kt @@ -59,10 +59,6 @@ class FakeLegacyCategoriesAndPhrasesRepository : ILegacyCategoriesAndPhrasesRepo return _allCategories.value.sortedBy { it.sortOrder } } - override suspend fun deletePhrase(phraseId: String) { - TODO("Not yet implemented") - } - override suspend fun updateCategorySortOrders(categorySortOrders: List) { _allCategories.update { allCategories -> allCategories.map { categoryDto ->