mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-22 09:25:49 +03:00
Add Init action + corresponding initialized event
This commit is contained in:
parent
e437c9e131
commit
fd85ad0f1b
5 changed files with 84 additions and 30 deletions
|
@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices.v2.rename
|
|||
import im.vector.app.core.platform.VectorViewModelAction
|
||||
|
||||
sealed class RenameSessionAction : VectorViewModelAction {
|
||||
object InitWithLastEditedName : RenameSessionAction()
|
||||
object SaveModifications : RenameSessionAction()
|
||||
data class EditLocally(val editedName: String) : RenameSessionAction()
|
||||
}
|
||||
|
|
|
@ -40,8 +40,6 @@ class RenameSessionFragment :
|
|||
|
||||
@Inject lateinit var viewNavigator: RenameSessionViewNavigator
|
||||
|
||||
private var renameEditTextInitialized = false
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSessionRenameBinding {
|
||||
return FragmentSessionRenameBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
@ -52,6 +50,7 @@ class RenameSessionFragment :
|
|||
initToolbar()
|
||||
initEditText()
|
||||
initSaveButton()
|
||||
initWithLastEditedName()
|
||||
}
|
||||
|
||||
private fun initToolbar() {
|
||||
|
@ -72,9 +71,17 @@ class RenameSessionFragment :
|
|||
}
|
||||
}
|
||||
|
||||
private fun initWithLastEditedName() {
|
||||
viewModel.handle(RenameSessionAction.InitWithLastEditedName)
|
||||
}
|
||||
|
||||
private fun observeViewEvents() {
|
||||
viewModel.observeViewEvents {
|
||||
when (it) {
|
||||
is RenameSessionViewEvent.Initialized -> {
|
||||
views.renameSessionEditText.setText(it.deviceName)
|
||||
views.renameSessionEditText.setSelection(views.renameSessionEditText.length())
|
||||
}
|
||||
is RenameSessionViewEvent.SessionRenamed -> {
|
||||
viewNavigator.goBack(requireActivity())
|
||||
}
|
||||
|
@ -86,11 +93,6 @@ class RenameSessionFragment :
|
|||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
if (renameEditTextInitialized.not()) {
|
||||
views.renameSessionEditText.setText(state.editedDeviceName)
|
||||
views.renameSessionEditText.setSelection(views.renameSessionEditText.length())
|
||||
renameEditTextInitialized = true
|
||||
}
|
||||
views.renameSessionSave.isEnabled = state.editedDeviceName.isNotEmpty()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.settings.devices.v2.rename
|
|||
import im.vector.app.core.platform.VectorViewEvents
|
||||
|
||||
sealed class RenameSessionViewEvent : VectorViewEvents {
|
||||
data class Initialized(val deviceName: String) : RenameSessionViewEvent()
|
||||
object SessionRenamed : RenameSessionViewEvent()
|
||||
data class Failure(val throwable: Throwable) : RenameSessionViewEvent()
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package im.vector.app.features.settings.devices.v2.rename
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
|
@ -24,8 +25,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory
|
|||
import im.vector.app.core.di.hiltMavericksViewModelFactory
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.features.settings.devices.v2.overview.GetDeviceFullInfoUseCase
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class RenameSessionViewModel @AssistedInject constructor(
|
||||
|
@ -41,23 +41,41 @@ class RenameSessionViewModel @AssistedInject constructor(
|
|||
override fun create(initialState: RenameSessionViewState): RenameSessionViewModel
|
||||
}
|
||||
|
||||
init {
|
||||
observeSessionInfo(initialState.deviceId)
|
||||
}
|
||||
|
||||
private fun observeSessionInfo(deviceId: String) {
|
||||
getDeviceFullInfoUseCase.execute(deviceId)
|
||||
.onEach { setState { copy(editedDeviceName = it.deviceInfo.displayName.orEmpty()) } }
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
@VisibleForTesting
|
||||
var hasRetrievedOriginalDeviceName = false
|
||||
|
||||
override fun handle(action: RenameSessionAction) {
|
||||
when (action) {
|
||||
is RenameSessionAction.InitWithLastEditedName -> handleInitWithLastEditedName()
|
||||
is RenameSessionAction.EditLocally -> handleEditLocally(action.editedName)
|
||||
is RenameSessionAction.SaveModifications -> handleSaveModifications()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleInitWithLastEditedName() = withState { state ->
|
||||
if (hasRetrievedOriginalDeviceName) {
|
||||
postInitEvent()
|
||||
} else {
|
||||
hasRetrievedOriginalDeviceName = true
|
||||
viewModelScope.launch {
|
||||
setStateWithOriginalDeviceName(state.deviceId)
|
||||
postInitEvent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setStateWithOriginalDeviceName(deviceId: String) {
|
||||
getDeviceFullInfoUseCase.execute(deviceId)
|
||||
.firstOrNull()
|
||||
?.let { deviceFullInfo ->
|
||||
setState { copy(editedDeviceName = deviceFullInfo.deviceInfo.displayName.orEmpty()) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun postInitEvent() = withState { state ->
|
||||
_viewEvents.post(RenameSessionViewEvent.Initialized(state.editedDeviceName))
|
||||
}
|
||||
|
||||
private fun handleEditLocally(editedName: String) {
|
||||
setState { copy(editedDeviceName = editedName) }
|
||||
}
|
||||
|
|
|
@ -51,38 +51,72 @@ class RenameSessionViewModelTest {
|
|||
)
|
||||
|
||||
@Test
|
||||
fun `given the viewModel has been initialized then viewState is updated with current session name`() {
|
||||
fun `given the original device name has not been retrieved when handling init with last edited name action then view state and view events are updated`() {
|
||||
// Given
|
||||
givenSessionWithName(A_SESSION_NAME)
|
||||
val action = RenameSessionAction.InitWithLastEditedName
|
||||
val expectedState = RenameSessionViewState(
|
||||
deviceId = A_SESSION_ID,
|
||||
editedDeviceName = A_SESSION_NAME,
|
||||
)
|
||||
val expectedEvent = RenameSessionViewEvent.Initialized(
|
||||
deviceName = A_SESSION_NAME,
|
||||
)
|
||||
val viewModel = createViewModel()
|
||||
viewModel.hasRetrievedOriginalDeviceName = false
|
||||
|
||||
// When
|
||||
val viewModel = createViewModel()
|
||||
val viewModelTest = viewModel.test()
|
||||
viewModel.handle(action)
|
||||
|
||||
// Then
|
||||
viewModel.test()
|
||||
.assertLatestState { state -> state == expectedState }
|
||||
viewModelTest.assertLatestState { state -> state == expectedState }
|
||||
.assertEvent { event -> event == expectedEvent }
|
||||
.finish()
|
||||
verify {
|
||||
getDeviceFullInfoUseCase.execute(A_SESSION_ID)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given the original device name has been retrieved when handling init with last edited name action then view state and view events are updated`() {
|
||||
// Given
|
||||
val action = RenameSessionAction.InitWithLastEditedName
|
||||
val expectedState = RenameSessionViewState(
|
||||
deviceId = A_SESSION_ID,
|
||||
editedDeviceName = AN_EDITED_SESSION_NAME,
|
||||
)
|
||||
val expectedEvent = RenameSessionViewEvent.Initialized(
|
||||
deviceName = AN_EDITED_SESSION_NAME,
|
||||
)
|
||||
val viewModel = createViewModel()
|
||||
viewModel.handle(RenameSessionAction.EditLocally(AN_EDITED_SESSION_NAME))
|
||||
viewModel.hasRetrievedOriginalDeviceName = true
|
||||
|
||||
// When
|
||||
val viewModelTest = viewModel.test()
|
||||
viewModel.handle(action)
|
||||
|
||||
// Then
|
||||
viewModelTest.assertLatestState { state -> state == expectedState }
|
||||
.assertEvent { event -> event == expectedEvent }
|
||||
.finish()
|
||||
verify(inverse = true) {
|
||||
getDeviceFullInfoUseCase.execute(A_SESSION_ID)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given a new edited name when handling edit name locally action then view state is updated accordingly`() {
|
||||
// Given
|
||||
givenSessionWithName(A_SESSION_NAME)
|
||||
val action = RenameSessionAction.EditLocally(AN_EDITED_SESSION_NAME)
|
||||
val expectedState = RenameSessionViewState(
|
||||
deviceId = A_SESSION_ID,
|
||||
editedDeviceName = AN_EDITED_SESSION_NAME,
|
||||
)
|
||||
val viewModel = createViewModel()
|
||||
|
||||
// When
|
||||
val viewModel = createViewModel()
|
||||
val viewModelTest = viewModel.test()
|
||||
viewModel.handle(action)
|
||||
|
||||
|
@ -95,12 +129,11 @@ class RenameSessionViewModelTest {
|
|||
@Test
|
||||
fun `given current edited name when handling save modifications action with success then correct view event is posted`() {
|
||||
// Given
|
||||
givenSessionWithName(A_SESSION_NAME)
|
||||
coEvery { renameSessionUseCase.execute(A_SESSION_ID, A_SESSION_NAME) } returns Result.success(Unit)
|
||||
coEvery { renameSessionUseCase.execute(A_SESSION_ID, any()) } returns Result.success(Unit)
|
||||
val action = RenameSessionAction.SaveModifications
|
||||
val viewModel = createViewModel()
|
||||
|
||||
// When
|
||||
val viewModel = createViewModel()
|
||||
val viewModelTest = viewModel.test()
|
||||
viewModel.handle(action)
|
||||
|
||||
|
@ -113,13 +146,12 @@ class RenameSessionViewModelTest {
|
|||
@Test
|
||||
fun `given current edited name when handling save modifications action with error then correct view event is posted`() {
|
||||
// Given
|
||||
givenSessionWithName(A_SESSION_NAME)
|
||||
val error = Exception()
|
||||
coEvery { renameSessionUseCase.execute(A_SESSION_ID, A_SESSION_NAME) } returns Result.failure(error)
|
||||
coEvery { renameSessionUseCase.execute(A_SESSION_ID, any()) } returns Result.failure(error)
|
||||
val action = RenameSessionAction.SaveModifications
|
||||
val viewModel = createViewModel()
|
||||
|
||||
// When
|
||||
val viewModel = createViewModel()
|
||||
val viewModelTest = viewModel.test()
|
||||
viewModel.handle(action)
|
||||
|
||||
|
|
Loading…
Reference in a new issue