Skip to content

Commit

Permalink
Merge pull request #569 from willowtreeapps/bugfix/557-cannot-edit-us…
Browse files Browse the repository at this point in the history
…er-added-phrase

Push updating phrase logic down into the use case
  • Loading branch information
PaulKlauser authored Jun 12, 2024
2 parents 1c8fee5 + ae185f3 commit cc52fc1
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ class CategoriesUseCaseTest {
storedPhrasesRepository,
presetPhrasesRepository,
FakeDateProvider(),
FakeUUIDProvider()
FakeUUIDProvider(),
FakeLocaleProvider()
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.willowtree.vocable.basetest.utils.FakeLocaleProvider
import com.willowtree.vocable.presets.CustomPhrase
import com.willowtree.vocable.presets.PresetCategories
import com.willowtree.vocable.room.PhraseDto
import com.willowtree.vocable.room.RoomPresetPhrasesRepository
import com.willowtree.vocable.room.RoomStoredPhrasesRepository
import com.willowtree.vocable.room.VocableDatabase
import com.willowtree.vocable.utility.FakeDateProvider
import com.willowtree.vocable.utility.VocableKoinTestRule
import com.willowtree.vocable.utility.StubLegacyCategoriesAndPhrasesRepository
import com.willowtree.vocable.utility.VocableKoinTestRule
import com.willowtree.vocable.utils.UUIDProvider
import com.willowtree.vocable.utils.locale.LocalesWithText
import junit.framework.Assert.assertEquals
Expand Down Expand Up @@ -43,6 +44,7 @@ class PhrasesUseCaseTest {
private val testLocalesWithText = LocalesWithText(
mapOf("en" to "text")
)
private val localeProvider = FakeLocaleProvider()

private fun createUseCase(): PhrasesUseCase {
return PhrasesUseCase(
Expand All @@ -52,7 +54,8 @@ class PhrasesUseCaseTest {
dateProvider = dateProvider,
uuidProvider = object : UUIDProvider {
override fun randomUUIDString(): String = "random"
}
},
localeProvider = localeProvider
)
}

Expand Down Expand Up @@ -172,24 +175,54 @@ class PhrasesUseCaseTest {
fun updatePhrase_updatesCustomPhrase() = runTest {
val useCase = createUseCase()
val phraseId = "1"
val localizedUtterance = LocalesWithText(mapOf("en" to "updated text"))
storedPhrasesRepository.addPhrase(
PhraseDto(
phraseId = phraseId,
parentCategoryId = "category",
creationDate = 0L,
lastSpokenDate = null,
localizedUtterance = testLocalesWithText,
localizedUtterance = LocalesWithText(localeProvider.getDefaultLocaleString() to "text"),
sortOrder = 0
)
)

useCase.updatePhrase(phraseId, "updated text")

val updatedPhrases = useCase.getPhrasesForCategory("category")
assertEquals(updatedPhrases.size, 1)
assertEquals(
LocalesWithText(localeProvider.getDefaultLocaleString() to "updated text"),
(updatedPhrases[0] as CustomPhrase).localizedUtterance
)
}

@Test
fun updatePhrase_updatesCustomPhrase_leaving_other_locale() = runTest {
val useCase = createUseCase()
val phraseId = "1"
storedPhrasesRepository.addPhrase(
PhraseDto(
phraseId = phraseId,
parentCategoryId = "category",
creationDate = 0L,
lastSpokenDate = null,
localizedUtterance = LocalesWithText(
localeProvider.getDefaultLocaleString() to "text",
"other_locale" to "other text"
),
sortOrder = 0
)
)

useCase.updatePhrase(phraseId, localizedUtterance)
useCase.updatePhrase(phraseId, "updated text")

val updatedPhrases = useCase.getPhrasesForCategory("category")
assertEquals(updatedPhrases.size, 1)
assertEquals(
localizedUtterance,
LocalesWithText(
localeProvider.getDefaultLocaleString() to "updated text",
"other_locale" to "other text"
),
(updatedPhrases[0] as CustomPhrase).localizedUtterance
)
}
Expand All @@ -199,9 +232,10 @@ class PhrasesUseCaseTest {
val useCase = createUseCase()
presetPhrasesRepository.populateDatabase()
val phraseId = "category_123_0"
val localizedUtterance = LocalesWithText(mapOf("en" to "updated text"))
val localizedUtterance =
LocalesWithText(localeProvider.getDefaultLocaleString() to "updated text")

useCase.updatePhrase(phraseId, localizedUtterance)
useCase.updatePhrase(phraseId, "updated text")

val newCustomPhrase = useCase.getPhrasesForCategory(PresetCategories.USER_KEYPAD.id)
.singleOrNull { it.phraseId == phraseId } as CustomPhrase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class AddUpdateCategoryViewModelTest {
storedPhrasesRepository,
presetPhrasesRepository,
FakeDateProvider(),
FakeUUIDProvider()
FakeUUIDProvider(),
FakeLocaleProvider()
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ class EditCategoriesViewModelTest {
storedPhrasesRepository,
presetPhrasesRepository,
FakeDateProvider(),
FakeUUIDProvider()
FakeUUIDProvider(),
FakeLocaleProvider()
)
)

Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/willowtree/vocable/AppKoinModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import com.willowtree.vocable.utils.FaceTrackingPermissions
import com.willowtree.vocable.utils.IFaceTrackingPermissions
import com.willowtree.vocable.utils.ILocalizedResourceUtility
import com.willowtree.vocable.utils.IVocableSharedPreferences
import com.willowtree.vocable.utils.JavaDateProvider
import com.willowtree.vocable.utils.IdlingResourceContainer
import com.willowtree.vocable.utils.IdlingResourceContainerImpl
import com.willowtree.vocable.utils.JavaDateProvider
import com.willowtree.vocable.utils.RandomUUIDProvider
import com.willowtree.vocable.utils.UUIDProvider
import com.willowtree.vocable.utils.VocableEnvironment
Expand Down Expand Up @@ -90,7 +90,7 @@ val vocableKoinModule = module {
single { Moshi.Builder().add(KotlinJsonAdapterFactory()).build() }
single { LocalizedResourceUtility(androidContext()) } bind ILocalizedResourceUtility::class
single { CategoriesUseCase(get(), get(), get(), get(), get()) } bind ICategoriesUseCase::class
single { PhrasesUseCase(get(), get(), get(), get(), get()) } bind IPhrasesUseCase::class
single { PhrasesUseCase(get(), get(), get(), get(), get(), get()) } bind IPhrasesUseCase::class
single { RandomUUIDProvider() } bind UUIDProvider::class
single { JavaDateProvider() } bind DateProvider::class
single { JavaLocaleProvider() } bind LocaleProvider::class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface IPhrasesUseCase {

suspend fun deletePhrase(phraseId: String)

suspend fun updatePhrase(phraseId: String, localizedUtterance: LocalesWithText)
suspend fun updatePhrase(phraseId: String, updatedPhrase: String)

suspend fun addPhrase(localizedUtterance: LocalesWithText, parentCategoryId: String)
}
10 changes: 7 additions & 3 deletions app/src/main/java/com/willowtree/vocable/PhrasesUseCase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.willowtree.vocable.room.PresetPhrasesRepository
import com.willowtree.vocable.room.StoredPhrasesRepository
import com.willowtree.vocable.utils.DateProvider
import com.willowtree.vocable.utils.UUIDProvider
import com.willowtree.vocable.utils.locale.LocaleProvider
import com.willowtree.vocable.utils.locale.LocalesWithText

class PhrasesUseCase(
Expand All @@ -18,6 +19,7 @@ class PhrasesUseCase(
private val presetPhrasesRepository: PresetPhrasesRepository,
private val dateProvider: DateProvider,
private val uuidProvider: UUIDProvider,
private val localeProvider: LocaleProvider
) : IPhrasesUseCase {
override suspend fun getPhrasesForCategory(categoryId: String): List<Phrase> {
if (categoryId == PresetCategories.RECENTS.id) {
Expand All @@ -39,12 +41,14 @@ class PhrasesUseCase(
presetPhrasesRepository.deletePhrase(phraseId)
}

override suspend fun updatePhrase(phraseId: String, localizedUtterance: LocalesWithText) {
override suspend fun updatePhrase(phraseId: String, updatedPhrase: String) {
val phrase = storedPhrasesRepository.getPhrase(phraseId)
?: presetPhrasesRepository.getPhrase(phraseId)
.takeIf { it != null && !it.deleted }
.takeIf { it != null && !it.deleted }!!
when (phrase) {
is CustomPhrase -> {
val localizedUtterance = (phrase.localizedUtterance ?: LocalesWithText(emptyMap()))
.with(localeProvider.getDefaultLocaleString(), updatedPhrase)
storedPhrasesRepository.updatePhraseLocalizedUtterance(
phraseId = phraseId,
localizedUtterance = localizedUtterance,
Expand All @@ -59,7 +63,7 @@ class PhrasesUseCase(
parentCategoryId = phrase.parentCategoryId,
creationDate = dateProvider.currentTimeMillis(),
lastSpokenDate = phrase.lastSpokenDate,
localizedUtterance = localizedUtterance,
localizedUtterance = LocalesWithText(mapOf(localeProvider.getDefaultLocaleString() to updatedPhrase)),
sortOrder = phrase.sortOrder
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class AddUpdateCategoryViewModel(
is Category.Recents -> throw IllegalArgumentException("Cannot update Recents category name!")
}

val updatedLocalizedNames: LocalesWithText = localesWithText.set(localeProvider.getDefaultLocaleString(), updatedName)
val updatedLocalizedNames: LocalesWithText = localesWithText.with(localeProvider.getDefaultLocaleString(), updatedName)

categoriesUseCase.updateCategoryName(toUpdate.categoryId, updatedLocalizedNames)
liveShowCategoryUpdateMessage.postValue(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import com.willowtree.vocable.R
import com.willowtree.vocable.presets.CustomPhrase
import com.willowtree.vocable.presets.Phrase
import com.willowtree.vocable.presets.PresetPhrase
import com.willowtree.vocable.utils.locale.LocalesWithText

class EditPhrasesKeyboardFragment : EditKeyboardFragment() {

Expand Down Expand Up @@ -50,13 +47,7 @@ class EditPhrasesKeyboardFragment : EditKeyboardFragment() {
if (!isDefaultTextVisible()) {
binding.keyboardInput.text.let { text ->
if (text.isNotBlank()) {
val localesWithText = when (val savingPhrase = phrase) {
is CustomPhrase -> {
savingPhrase.localizedUtterance ?: LocalesWithText(emptyMap())
}
is PresetPhrase -> LocalesWithText(mapOf("en" to text.toString()))
}
viewModel.updatePhrase(phrase.phraseId, localesWithText)
viewModel.updatePhrase(phrase.phraseId, text.toString())
addNewPhrase = false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.willowtree.vocable.PhrasesUseCase
import com.willowtree.vocable.utils.locale.LocalesWithText
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
Expand All @@ -17,9 +16,9 @@ class EditPhrasesViewModel : ViewModel(), KoinComponent {
private val liveShowPhraseAdded = MutableLiveData<Boolean>()
val showPhraseAdded: LiveData<Boolean> = liveShowPhraseAdded

fun updatePhrase(phraseId: String, localizedUtterance: LocalesWithText) {
fun updatePhrase(phraseId: String, newText: String) {
viewModelScope.launch {
phrasesUseCase.updatePhrase(phraseId, localizedUtterance)
phrasesUseCase.updatePhrase(phraseId, newText)
liveShowPhraseAdded.postValue(true)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ data class LocalesWithText(
val localesTextMap: Map<LocaleString, String>
) : Parcelable {

constructor(vararg pairs: Pair<LocaleString, String>) : this(mapOf(*pairs))

/**
* Gets the string corresponding to the given localeString.
* @param localeString The localeString to match against
Expand All @@ -46,7 +48,7 @@ data class LocalesWithText(
* @param text for the localeString
* @return A new LocalesWithText with the given localeString and text added to the map
*/
operator fun set(localeString: LocaleString, text: String): LocalesWithText {
fun with(localeString: LocaleString, text: String): LocalesWithText {
return LocalesWithText(localesTextMap.toMutableMap().apply {
this[localeString] = text
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class FakePhrasesUseCase : IPhrasesUseCase {

override suspend fun deletePhrase(phraseId: String) = error("Not implemented")

override suspend fun updatePhrase(phraseId: String, localizedUtterance: LocalesWithText) {
override suspend fun updatePhrase(phraseId: String, updatedPhrase: String) {
error("Not implemented")
}

Expand Down

0 comments on commit cc52fc1

Please sign in to comment.