RoomDetailsEditEvents -> RoomDetailsEditEvent

This commit is contained in:
Benoit Marty 2025-12-03 17:31:07 +01:00 committed by Benoit Marty
parent a10e049a79
commit 4afeb6210c
7 changed files with 100 additions and 100 deletions

View file

@ -10,11 +10,11 @@ package io.element.android.features.roomdetailsedit.impl
import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.matrix.ui.media.AvatarAction
sealed interface RoomDetailsEditEvents { sealed interface RoomDetailsEditEvent {
data class HandleAvatarAction(val action: AvatarAction) : RoomDetailsEditEvents data class HandleAvatarAction(val action: AvatarAction) : RoomDetailsEditEvent
data class UpdateRoomName(val name: String) : RoomDetailsEditEvents data class UpdateRoomName(val name: String) : RoomDetailsEditEvent
data class UpdateRoomTopic(val topic: String) : RoomDetailsEditEvents data class UpdateRoomTopic(val topic: String) : RoomDetailsEditEvent
data object OnBackPress : RoomDetailsEditEvents data object OnBackPress : RoomDetailsEditEvent
data object Save : RoomDetailsEditEvents data object Save : RoomDetailsEditEvent
data object CloseDialog : RoomDetailsEditEvents data object CloseDialog : RoomDetailsEditEvent
} }

View file

@ -139,9 +139,9 @@ class RoomDetailsEditPresenter(
val saveAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) } val saveAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
val localCoroutineScope = rememberCoroutineScope() val localCoroutineScope = rememberCoroutineScope()
fun handleEvent(event: RoomDetailsEditEvents) { fun handleEvent(event: RoomDetailsEditEvent) {
when (event) { when (event) {
is RoomDetailsEditEvents.Save -> localCoroutineScope.saveChanges( is RoomDetailsEditEvent.Save -> localCoroutineScope.saveChanges(
currentNameTrimmed = roomRawNameTrimmed, currentNameTrimmed = roomRawNameTrimmed,
newNameTrimmed = roomRawNameEdited.trim(), newNameTrimmed = roomRawNameEdited.trim(),
currentTopicTrimmed = roomTopicTrimmed, currentTopicTrimmed = roomTopicTrimmed,
@ -150,7 +150,7 @@ class RoomDetailsEditPresenter(
newAvatarUri = roomAvatarUriEdited?.toUri(), newAvatarUri = roomAvatarUriEdited?.toUri(),
action = saveAction, action = saveAction,
) )
is RoomDetailsEditEvents.HandleAvatarAction -> { is RoomDetailsEditEvent.HandleAvatarAction -> {
when (event.action) { when (event.action) {
AvatarAction.ChoosePhoto -> galleryImagePicker.launch() AvatarAction.ChoosePhoto -> galleryImagePicker.launch()
AvatarAction.TakePhoto -> if (cameraPermissionState.permissionGranted) { AvatarAction.TakePhoto -> if (cameraPermissionState.permissionGranted) {
@ -166,10 +166,10 @@ class RoomDetailsEditPresenter(
} }
} }
is RoomDetailsEditEvents.UpdateRoomName -> roomRawNameEdited = event.name is RoomDetailsEditEvent.UpdateRoomName -> roomRawNameEdited = event.name
is RoomDetailsEditEvents.UpdateRoomTopic -> roomTopicEdited = event.topic is RoomDetailsEditEvent.UpdateRoomTopic -> roomTopicEdited = event.topic
RoomDetailsEditEvents.CloseDialog -> saveAction.value = AsyncAction.Uninitialized RoomDetailsEditEvent.CloseDialog -> saveAction.value = AsyncAction.Uninitialized
RoomDetailsEditEvents.OnBackPress -> if (saveButtonEnabled.not() || saveAction.value == AsyncAction.ConfirmingCancellation) { RoomDetailsEditEvent.OnBackPress -> if (saveButtonEnabled.not() || saveAction.value == AsyncAction.ConfirmingCancellation) {
// No changes to save or already confirming exit without saving // No changes to save or already confirming exit without saving
saveAction.value = AsyncAction.Success(Unit) saveAction.value = AsyncAction.Success(Unit)
} else { } else {

View file

@ -28,5 +28,5 @@ data class RoomDetailsEditState(
val saveAction: AsyncAction<Unit>, val saveAction: AsyncAction<Unit>,
val cameraPermissionState: PermissionsState, val cameraPermissionState: PermissionsState,
val isSpace: Boolean, val isSpace: Boolean,
val eventSink: (RoomDetailsEditEvents) -> Unit val eventSink: (RoomDetailsEditEvent) -> Unit
) )

View file

@ -45,7 +45,7 @@ fun aRoomDetailsEditState(
saveAction: AsyncAction<Unit> = AsyncAction.Uninitialized, saveAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
cameraPermissionState: PermissionsState = aPermissionsState(showDialog = false), cameraPermissionState: PermissionsState = aPermissionsState(showDialog = false),
isSpace: Boolean = false, isSpace: Boolean = false,
eventSink: (RoomDetailsEditEvents) -> Unit = {}, eventSink: (RoomDetailsEditEvent) -> Unit = {},
) = RoomDetailsEditState( ) = RoomDetailsEditState(
roomId = roomId, roomId = roomId,
roomRawName = roomRawName, roomRawName = roomRawName,

View file

@ -64,7 +64,7 @@ fun RoomDetailsEditView(
} }
BackHandler { BackHandler {
state.eventSink(RoomDetailsEditEvents.OnBackPress) state.eventSink(RoomDetailsEditEvent.OnBackPress)
} }
Scaffold( Scaffold(
modifier = modifier.clearFocusOnTap(focusManager), modifier = modifier.clearFocusOnTap(focusManager),
@ -74,7 +74,7 @@ fun RoomDetailsEditView(
navigationIcon = { navigationIcon = {
BackButton( BackButton(
onClick = { onClick = {
state.eventSink(RoomDetailsEditEvents.OnBackPress) state.eventSink(RoomDetailsEditEvent.OnBackPress)
} }
) )
}, },
@ -84,7 +84,7 @@ fun RoomDetailsEditView(
enabled = state.saveButtonEnabled, enabled = state.saveButtonEnabled,
onClick = { onClick = {
focusManager.clearFocus() focusManager.clearFocus()
state.eventSink(RoomDetailsEditEvents.Save) state.eventSink(RoomDetailsEditEvent.Save)
}, },
) )
} }
@ -121,7 +121,7 @@ fun RoomDetailsEditView(
placeholder = stringResource(CommonStrings.common_room_name_placeholder), placeholder = stringResource(CommonStrings.common_room_name_placeholder),
singleLine = true, singleLine = true,
readOnly = !state.canChangeName, readOnly = !state.canChangeName,
onValueChange = { state.eventSink(RoomDetailsEditEvents.UpdateRoomName(it)) }, onValueChange = { state.eventSink(RoomDetailsEditEvent.UpdateRoomName(it)) },
) )
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
@ -136,7 +136,7 @@ fun RoomDetailsEditView(
}, },
maxLines = 10, maxLines = 10,
readOnly = !state.canChangeTopic, readOnly = !state.canChangeTopic,
onValueChange = { state.eventSink(RoomDetailsEditEvents.UpdateRoomTopic(it)) }, onValueChange = { state.eventSink(RoomDetailsEditEvent.UpdateRoomTopic(it)) },
keyboardOptions = KeyboardOptions( keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Sentences, capitalization = KeyboardCapitalization.Sentences,
), ),
@ -147,7 +147,7 @@ fun RoomDetailsEditView(
actions = state.avatarActions, actions = state.avatarActions,
isVisible = isAvatarActionsSheetVisible.value, isVisible = isAvatarActionsSheetVisible.value,
onDismiss = { isAvatarActionsSheetVisible.value = false }, onDismiss = { isAvatarActionsSheetVisible.value = false },
onSelectAction = { state.eventSink(RoomDetailsEditEvents.HandleAvatarAction(it)) } onSelectAction = { state.eventSink(RoomDetailsEditEvent.HandleAvatarAction(it)) }
) )
AsyncActionView( AsyncActionView(
async = state.saveAction, async = state.saveAction,
@ -159,15 +159,15 @@ fun RoomDetailsEditView(
confirmationDialog = { confirmationDialog = {
if (state.saveAction == AsyncAction.ConfirmingCancellation) { if (state.saveAction == AsyncAction.ConfirmingCancellation) {
SaveChangesDialog( SaveChangesDialog(
onSaveClick = { state.eventSink(RoomDetailsEditEvents.Save) }, onSaveClick = { state.eventSink(RoomDetailsEditEvent.Save) },
onDiscardClick = { state.eventSink(RoomDetailsEditEvents.OnBackPress) }, onDiscardClick = { state.eventSink(RoomDetailsEditEvent.OnBackPress) },
onDismiss = { state.eventSink(RoomDetailsEditEvents.CloseDialog) } onDismiss = { state.eventSink(RoomDetailsEditEvent.CloseDialog) }
) )
} }
}, },
onSuccess = { onDone() }, onSuccess = { onDone() },
errorMessage = { stringResource(R.string.screen_room_details_edition_error) }, errorMessage = { stringResource(R.string.screen_room_details_edition_error) },
onErrorDismiss = { state.eventSink(RoomDetailsEditEvents.CloseDialog) } onErrorDismiss = { state.eventSink(RoomDetailsEditEvent.CloseDialog) }
) )
PermissionsView( PermissionsView(

View file

@ -241,25 +241,25 @@ class RoomDetailsEditPresenterTest {
assertThat(initialState.roomTopic).isEqualTo("My topic") assertThat(initialState.roomTopic).isEqualTo("My topic")
assertThat(initialState.roomRawName).isEqualTo("Name") assertThat(initialState.roomRawName).isEqualTo("Name")
assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name II")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name II"))
awaitItem().apply { awaitItem().apply {
assertThat(roomTopic).isEqualTo("My topic") assertThat(roomTopic).isEqualTo("My topic")
assertThat(roomRawName).isEqualTo("Name II") assertThat(roomRawName).isEqualTo("Name II")
assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
} }
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name III")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name III"))
awaitItem().apply { awaitItem().apply {
assertThat(roomTopic).isEqualTo("My topic") assertThat(roomTopic).isEqualTo("My topic")
assertThat(roomRawName).isEqualTo("Name III") assertThat(roomRawName).isEqualTo("Name III")
assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
} }
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("Another topic")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("Another topic"))
awaitItem().apply { awaitItem().apply {
assertThat(roomTopic).isEqualTo("Another topic") assertThat(roomTopic).isEqualTo("Another topic")
assertThat(roomRawName).isEqualTo("Name III") assertThat(roomRawName).isEqualTo("Name III")
assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
} }
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove))
awaitItem().apply { awaitItem().apply {
assertThat(roomTopic).isEqualTo("Another topic") assertThat(roomTopic).isEqualTo("Another topic")
assertThat(roomRawName).isEqualTo("Name III") assertThat(roomRawName).isEqualTo("Name III")
@ -285,7 +285,7 @@ class RoomDetailsEditPresenterTest {
presenter.test { presenter.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto))
awaitItem().apply { awaitItem().apply {
assertThat(roomAvatarUrl).isEqualTo(anotherAvatarUri.toString()) assertThat(roomAvatarUrl).isEqualTo(anotherAvatarUri.toString())
} }
@ -312,7 +312,7 @@ class RoomDetailsEditPresenterTest {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(initialState.roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
assertThat(initialState.cameraPermissionState.permissionGranted).isFalse() assertThat(initialState.cameraPermissionState.permissionGranted).isFalse()
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.TakePhoto))
val stateWithAskingPermission = awaitItem() val stateWithAskingPermission = awaitItem()
assertThat(stateWithAskingPermission.cameraPermissionState.showDialog).isTrue() assertThat(stateWithAskingPermission.cameraPermissionState.showDialog).isTrue()
fakePermissionsPresenter.setPermissionGranted() fakePermissionsPresenter.setPermissionGranted()
@ -322,7 +322,7 @@ class RoomDetailsEditPresenterTest {
assertThat(stateWithNewAvatar.roomAvatarUrl).isEqualTo(anotherAvatarUri.toString()) assertThat(stateWithNewAvatar.roomAvatarUrl).isEqualTo(anotherAvatarUri.toString())
// Do it again, no permission is requested // Do it again, no permission is requested
fakePickerProvider.givenResult(roomAvatarUri) fakePickerProvider.givenResult(roomAvatarUri)
stateWithNewAvatar.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto)) stateWithNewAvatar.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.TakePhoto))
val stateWithNewAvatar2 = awaitItem() val stateWithNewAvatar2 = awaitItem()
assertThat(stateWithNewAvatar2.roomAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(stateWithNewAvatar2.roomAvatarUrl).isEqualTo(AN_AVATAR_URL)
deleteCallback.assertions().isCalledExactly(3).withSequence( deleteCallback.assertions().isCalledExactly(3).withSequence(
@ -351,32 +351,32 @@ class RoomDetailsEditPresenterTest {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
assertThat(initialState.saveButtonEnabled).isFalse() assertThat(initialState.saveButtonEnabled).isFalse()
// Once a change is made, the save button is enabled // Once a change is made, the save button is enabled
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name II")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name II"))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isTrue() assertThat(saveButtonEnabled).isTrue()
} }
// If it's reverted then the save disables again // If it's reverted then the save disables again
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name"))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isFalse() assertThat(saveButtonEnabled).isFalse()
} }
// Make a change... // Make a change...
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("Another topic")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("Another topic"))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isTrue() assertThat(saveButtonEnabled).isTrue()
} }
// Revert it... // Revert it...
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("My topic")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("My topic"))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isFalse() assertThat(saveButtonEnabled).isFalse()
} }
// Make a change... // Make a change...
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isTrue() assertThat(saveButtonEnabled).isTrue()
} }
// Revert it... // Revert it...
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isFalse() assertThat(saveButtonEnabled).isFalse()
} }
@ -401,32 +401,32 @@ class RoomDetailsEditPresenterTest {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
assertThat(initialState.saveButtonEnabled).isFalse() assertThat(initialState.saveButtonEnabled).isFalse()
// Once a change is made, the save button is enabled // Once a change is made, the save button is enabled
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name II")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name II"))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isTrue() assertThat(saveButtonEnabled).isTrue()
} }
// If it's reverted then the save disables again // If it's reverted then the save disables again
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("fallback")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("fallback"))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isFalse() assertThat(saveButtonEnabled).isFalse()
} }
// Make a change... // Make a change...
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("Another topic")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("Another topic"))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isTrue() assertThat(saveButtonEnabled).isTrue()
} }
// Revert it... // Revert it...
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic(""))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isFalse() assertThat(saveButtonEnabled).isFalse()
} }
// Make a change... // Make a change...
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isTrue() assertThat(saveButtonEnabled).isTrue()
} }
// Revert it... // Revert it...
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isFalse() assertThat(saveButtonEnabled).isFalse()
} }
@ -454,10 +454,10 @@ class RoomDetailsEditPresenterTest {
) )
presenter.test { presenter.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("New name")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("New name"))
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("New topic")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("New topic"))
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove))
initialState.eventSink(RoomDetailsEditEvents.Save) initialState.eventSink(RoomDetailsEditEvent.Save)
skipItems(5) skipItems(5)
setNameResult.assertions().isCalledOnce().with(value("New name")) setNameResult.assertions().isCalledOnce().with(value("New name"))
setTopicResult.assertions().isCalledOnce().with(value("New topic")) setTopicResult.assertions().isCalledOnce().with(value("New topic"))
@ -480,9 +480,9 @@ class RoomDetailsEditPresenterTest {
) )
presenter.test { presenter.test {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName(" Name ")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName(" Name "))
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic(" My topic ")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic(" My topic "))
initialState.eventSink(RoomDetailsEditEvents.Save) initialState.eventSink(RoomDetailsEditEvent.Save)
cancelAndIgnoreRemainingEvents() cancelAndIgnoreRemainingEvents()
} }
} }
@ -502,8 +502,8 @@ class RoomDetailsEditPresenterTest {
) )
presenter.test { presenter.test {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic(""))
initialState.eventSink(RoomDetailsEditEvents.Save) initialState.eventSink(RoomDetailsEditEvent.Save)
cancelAndIgnoreRemainingEvents() cancelAndIgnoreRemainingEvents()
deleteCallback.assertions().isCalledOnce().with(value(null)) deleteCallback.assertions().isCalledOnce().with(value(null))
} }
@ -524,8 +524,8 @@ class RoomDetailsEditPresenterTest {
) )
presenter.test { presenter.test {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName(""))
initialState.eventSink(RoomDetailsEditEvents.Save) initialState.eventSink(RoomDetailsEditEvent.Save)
cancelAndIgnoreRemainingEvents() cancelAndIgnoreRemainingEvents()
deleteCallback.assertions().isCalledOnce().with(value(null)) deleteCallback.assertions().isCalledOnce().with(value(null))
} }
@ -549,8 +549,8 @@ class RoomDetailsEditPresenterTest {
) )
presenter.test { presenter.test {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto))
initialState.eventSink(RoomDetailsEditEvents.Save) initialState.eventSink(RoomDetailsEditEvent.Save)
skipItems(4) skipItems(4)
updateAvatarResult.assertions().isCalledOnce().with(value(MimeTypes.Jpeg), value(fakeFileContents)) updateAvatarResult.assertions().isCalledOnce().with(value(MimeTypes.Jpeg), value(fakeFileContents))
deleteCallback.assertions().isCalledExactly(2).withSequence( deleteCallback.assertions().isCalledExactly(2).withSequence(
@ -577,8 +577,8 @@ class RoomDetailsEditPresenterTest {
) )
presenter.test { presenter.test {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) initialState.eventSink(RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto))
initialState.eventSink(RoomDetailsEditEvents.Save) initialState.eventSink(RoomDetailsEditEvent.Save)
skipItems(3) skipItems(3)
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
} }
@ -593,7 +593,7 @@ class RoomDetailsEditPresenterTest {
setNameResult = { Result.failure(RuntimeException("!")) }, setNameResult = { Result.failure(RuntimeException("!")) },
canSendStateResult = { _, _ -> Result.success(true) } canSendStateResult = { _, _ -> Result.success(true) }
) )
saveAndAssertFailure(room, RoomDetailsEditEvents.UpdateRoomName("New name"), deleteCallbackNumberOfInvocation = 1) saveAndAssertFailure(room, RoomDetailsEditEvent.UpdateRoomName("New name"), deleteCallbackNumberOfInvocation = 1)
} }
@Test @Test
@ -605,7 +605,7 @@ class RoomDetailsEditPresenterTest {
setTopicResult = { Result.failure(RuntimeException("!")) }, setTopicResult = { Result.failure(RuntimeException("!")) },
canSendStateResult = { _, _ -> Result.success(true) } canSendStateResult = { _, _ -> Result.success(true) }
) )
saveAndAssertFailure(room, RoomDetailsEditEvents.UpdateRoomTopic("New topic"), deleteCallbackNumberOfInvocation = 1) saveAndAssertFailure(room, RoomDetailsEditEvent.UpdateRoomTopic("New topic"), deleteCallbackNumberOfInvocation = 1)
} }
@Test @Test
@ -617,7 +617,7 @@ class RoomDetailsEditPresenterTest {
removeAvatarResult = { Result.failure(RuntimeException("!")) }, removeAvatarResult = { Result.failure(RuntimeException("!")) },
canSendStateResult = { _, _ -> Result.success(true) } canSendStateResult = { _, _ -> Result.success(true) }
) )
saveAndAssertFailure(room, RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove), deleteCallbackNumberOfInvocation = 2) saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove), deleteCallbackNumberOfInvocation = 2)
} }
@Test @Test
@ -630,7 +630,7 @@ class RoomDetailsEditPresenterTest {
updateAvatarResult = { _, _ -> Result.failure(RuntimeException("!")) }, updateAvatarResult = { _, _ -> Result.failure(RuntimeException("!")) },
canSendStateResult = { _, _ -> Result.success(true) } canSendStateResult = { _, _ -> Result.success(true) }
) )
saveAndAssertFailure(room, RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto), deleteCallbackNumberOfInvocation = 2) saveAndAssertFailure(room, RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto), deleteCallbackNumberOfInvocation = 2)
} }
@Test @Test
@ -650,11 +650,11 @@ class RoomDetailsEditPresenterTest {
) )
presenter.test { presenter.test {
val initialState = awaitItem() val initialState = awaitItem()
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomTopic("foo")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomTopic("foo"))
initialState.eventSink(RoomDetailsEditEvents.Save) initialState.eventSink(RoomDetailsEditEvent.Save)
skipItems(3) skipItems(3)
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
initialState.eventSink(RoomDetailsEditEvents.CloseDialog) initialState.eventSink(RoomDetailsEditEvent.CloseDialog)
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
} }
} }
@ -674,14 +674,14 @@ class RoomDetailsEditPresenterTest {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
assertThat(initialState.saveButtonEnabled).isFalse() assertThat(initialState.saveButtonEnabled).isFalse()
// Once a change is made, the save button is enabled // Once a change is made, the save button is enabled
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name edited")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name edited"))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isTrue() assertThat(saveButtonEnabled).isTrue()
eventSink(RoomDetailsEditEvents.OnBackPress) eventSink(RoomDetailsEditEvent.OnBackPress)
} }
awaitItem().apply { awaitItem().apply {
assertThat(saveAction).isEqualTo(AsyncAction.ConfirmingCancellation) assertThat(saveAction).isEqualTo(AsyncAction.ConfirmingCancellation)
eventSink(RoomDetailsEditEvents.CloseDialog) eventSink(RoomDetailsEditEvent.CloseDialog)
} }
awaitItem().apply { awaitItem().apply {
assertThat(saveAction).isEqualTo(AsyncAction.Uninitialized) assertThat(saveAction).isEqualTo(AsyncAction.Uninitialized)
@ -702,7 +702,7 @@ class RoomDetailsEditPresenterTest {
presenter.test { presenter.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
assertThat(initialState.saveButtonEnabled).isFalse() assertThat(initialState.saveButtonEnabled).isFalse()
initialState.eventSink(RoomDetailsEditEvents.OnBackPress) initialState.eventSink(RoomDetailsEditEvent.OnBackPress)
assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.Success(Unit)) assertThat(awaitItem().saveAction).isEqualTo(AsyncAction.Success(Unit))
} }
} }
@ -721,14 +721,14 @@ class RoomDetailsEditPresenterTest {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
assertThat(initialState.saveButtonEnabled).isFalse() assertThat(initialState.saveButtonEnabled).isFalse()
// Once a change is made, the save button is enabled // Once a change is made, the save button is enabled
initialState.eventSink(RoomDetailsEditEvents.UpdateRoomName("Name edited")) initialState.eventSink(RoomDetailsEditEvent.UpdateRoomName("Name edited"))
awaitItem().apply { awaitItem().apply {
assertThat(saveButtonEnabled).isTrue() assertThat(saveButtonEnabled).isTrue()
eventSink(RoomDetailsEditEvents.OnBackPress) eventSink(RoomDetailsEditEvent.OnBackPress)
} }
awaitItem().apply { awaitItem().apply {
assertThat(saveAction).isEqualTo(AsyncAction.ConfirmingCancellation) assertThat(saveAction).isEqualTo(AsyncAction.ConfirmingCancellation)
eventSink(RoomDetailsEditEvents.OnBackPress) eventSink(RoomDetailsEditEvent.OnBackPress)
} }
awaitItem().apply { awaitItem().apply {
assertThat(saveAction).isEqualTo(AsyncAction.Success(Unit)) assertThat(saveAction).isEqualTo(AsyncAction.Success(Unit))
@ -738,7 +738,7 @@ class RoomDetailsEditPresenterTest {
private suspend fun saveAndAssertFailure( private suspend fun saveAndAssertFailure(
room: JoinedRoom, room: JoinedRoom,
event: RoomDetailsEditEvents, event: RoomDetailsEditEvent,
deleteCallbackNumberOfInvocation: Int = 2, deleteCallbackNumberOfInvocation: Int = 2,
) { ) {
val deleteCallback = lambdaRecorder<Uri?, Unit> {} val deleteCallback = lambdaRecorder<Uri?, Unit> {}
@ -749,7 +749,7 @@ class RoomDetailsEditPresenterTest {
presenter.test { presenter.test {
val initialState = awaitFirstItem() val initialState = awaitFirstItem()
initialState.eventSink(event) initialState.eventSink(event)
initialState.eventSink(RoomDetailsEditEvents.Save) initialState.eventSink(RoomDetailsEditEvent.Save)
skipItems(1) skipItems(1)
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Loading::class.java)
assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)

View file

@ -39,19 +39,19 @@ class RoomDetailsEditViewTest {
@Test @Test
fun `clicking on back emits the expected Event`() { fun `clicking on back emits the expected Event`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>() val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder eventSink = eventsRecorder
), ),
) )
rule.pressBack() rule.pressBack()
eventsRecorder.assertSingle(RoomDetailsEditEvents.OnBackPress) eventsRecorder.assertSingle(RoomDetailsEditEvent.OnBackPress)
} }
@Test @Test
fun `clicking on discard when confirming exit emits the expected Event`() { fun `clicking on discard when confirming exit emits the expected Event`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>() val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
saveAction = AsyncAction.ConfirmingCancellation, saveAction = AsyncAction.ConfirmingCancellation,
@ -59,12 +59,12 @@ class RoomDetailsEditViewTest {
), ),
) )
rule.clickOn(CommonStrings.action_discard) rule.clickOn(CommonStrings.action_discard)
eventsRecorder.assertSingle(RoomDetailsEditEvents.OnBackPress) eventsRecorder.assertSingle(RoomDetailsEditEvent.OnBackPress)
} }
@Test @Test
fun `clicking on save when confirming exit emits the expected Event`() { fun `clicking on save when confirming exit emits the expected Event`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>() val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
saveAction = AsyncAction.ConfirmingCancellation, saveAction = AsyncAction.ConfirmingCancellation,
@ -72,12 +72,12 @@ class RoomDetailsEditViewTest {
), ),
) )
rule.clickOn(CommonStrings.action_save, inDialog = true) rule.clickOn(CommonStrings.action_save, inDialog = true)
eventsRecorder.assertSingle(RoomDetailsEditEvents.Save) eventsRecorder.assertSingle(RoomDetailsEditEvent.Save)
} }
@Test @Test
fun `when edition is successful, the expected callback is invoked`() { fun `when edition is successful, the expected callback is invoked`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
ensureCalledOnce { callback -> ensureCalledOnce { callback ->
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
@ -91,7 +91,7 @@ class RoomDetailsEditViewTest {
@Test @Test
fun `when name is changed, the expected Event is emitted`() { fun `when name is changed, the expected Event is emitted`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>() val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -99,12 +99,12 @@ class RoomDetailsEditViewTest {
), ),
) )
rule.onNodeWithText("Marketing").performTextInput("A") rule.onNodeWithText("Marketing").performTextInput("A")
eventsRecorder.assertSingle(RoomDetailsEditEvents.UpdateRoomName("AMarketing")) eventsRecorder.assertSingle(RoomDetailsEditEvent.UpdateRoomName("AMarketing"))
} }
@Test @Test
fun `when user cannot change name, nothing happen`() { fun `when user cannot change name, nothing happen`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -117,7 +117,7 @@ class RoomDetailsEditViewTest {
@Test @Test
fun `when topic is changed, the expected Event is emitted`() { fun `when topic is changed, the expected Event is emitted`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>() val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -125,12 +125,12 @@ class RoomDetailsEditViewTest {
), ),
) )
rule.onNodeWithText("My Topic").performTextInput("A") rule.onNodeWithText("My Topic").performTextInput("A")
eventsRecorder.assertSingle(RoomDetailsEditEvents.UpdateRoomTopic("AMy Topic")) eventsRecorder.assertSingle(RoomDetailsEditEvent.UpdateRoomTopic("AMy Topic"))
} }
@Test @Test
fun `when user cannot change topic, nothing happen`() { fun `when user cannot change topic, nothing happen`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -146,7 +146,7 @@ class RoomDetailsEditViewTest {
fun `when avatar is changed with action to take photo, the expected Event is emitted`() { fun `when avatar is changed with action to take photo, the expected Event is emitted`() {
testAvatarChange( testAvatarChange(
stringActionRes = CommonStrings.action_take_photo, stringActionRes = CommonStrings.action_take_photo,
expectedEvent = RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.TakePhoto), expectedEvent = RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.TakePhoto),
) )
} }
@ -155,7 +155,7 @@ class RoomDetailsEditViewTest {
fun `when avatar is changed with action to choose photo, the expected Event is emitted`() { fun `when avatar is changed with action to choose photo, the expected Event is emitted`() {
testAvatarChange( testAvatarChange(
stringActionRes = CommonStrings.action_choose_photo, stringActionRes = CommonStrings.action_choose_photo,
expectedEvent = RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.ChoosePhoto), expectedEvent = RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.ChoosePhoto),
) )
} }
@ -164,15 +164,15 @@ class RoomDetailsEditViewTest {
fun `when avatar is changed with action to remove photo, the expected Event is emitted`() { fun `when avatar is changed with action to remove photo, the expected Event is emitted`() {
testAvatarChange( testAvatarChange(
stringActionRes = CommonStrings.action_remove, stringActionRes = CommonStrings.action_remove,
expectedEvent = RoomDetailsEditEvents.HandleAvatarAction(AvatarAction.Remove), expectedEvent = RoomDetailsEditEvent.HandleAvatarAction(AvatarAction.Remove),
) )
} }
private fun testAvatarChange( private fun testAvatarChange(
@StringRes stringActionRes: Int, @StringRes stringActionRes: Int,
expectedEvent: RoomDetailsEditEvents.HandleAvatarAction, expectedEvent: RoomDetailsEditEvent.HandleAvatarAction,
) { ) {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>() val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -187,7 +187,7 @@ class RoomDetailsEditViewTest {
@Test @Test
fun `when user cannot change avatar, nothing happen`() { fun `when user cannot change avatar, nothing happen`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -200,7 +200,7 @@ class RoomDetailsEditViewTest {
@Test @Test
fun `when save is clicked, the expected Event is emitted`() { fun `when save is clicked, the expected Event is emitted`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>() val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -208,12 +208,12 @@ class RoomDetailsEditViewTest {
), ),
) )
rule.clickOn(CommonStrings.action_save) rule.clickOn(CommonStrings.action_save)
eventsRecorder.assertSingle(RoomDetailsEditEvents.Save) eventsRecorder.assertSingle(RoomDetailsEditEvent.Save)
} }
@Test @Test
fun `when save is clicked, but nothing need to be saved, nothing happens`() { fun `when save is clicked, but nothing need to be saved, nothing happens`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>(expectEvents = false) val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>(expectEvents = false)
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -225,7 +225,7 @@ class RoomDetailsEditViewTest {
@Test @Test
fun `when error is shown, closing the dialog emit the expected Event`() { fun `when error is shown, closing the dialog emit the expected Event`() {
val eventsRecorder = EventsRecorder<RoomDetailsEditEvents>() val eventsRecorder = EventsRecorder<RoomDetailsEditEvent>()
rule.setRoomDetailsEditView( rule.setRoomDetailsEditView(
aRoomDetailsEditState( aRoomDetailsEditState(
eventSink = eventsRecorder, eventSink = eventsRecorder,
@ -233,7 +233,7 @@ class RoomDetailsEditViewTest {
), ),
) )
rule.clickOn(CommonStrings.action_ok) rule.clickOn(CommonStrings.action_ok)
eventsRecorder.assertSingle(RoomDetailsEditEvents.CloseDialog) eventsRecorder.assertSingle(RoomDetailsEditEvent.CloseDialog)
} }
} }