Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,13 @@ internal class DeleteMessageListenerState(
logic.channelFromMessage(message)?.upsertMessage(message)
logic.getActiveQueryThreadsLogic().forEach { it.upsertMessage(message) }
logic.threadFromMessage(message)?.upsertMessage(message)
logic.getActiveQueryChannelsLogic().forEach { it.refreshChannelState(message.cid) }
}

private fun deleteMessage(message: Message) {
logic.channelFromMessage(message)?.deleteMessage(message)
logic.getActiveQueryThreadsLogic().forEach { it.deleteMessage(message) }
logic.threadFromMessage(message)?.deleteMessage(message)
logic.getActiveQueryChannelsLogic().forEach { it.refreshChannelState(message.cid) }
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ internal class ChannelMutableState(
val messageIds = messages.map { it.id }.toSet()
logger.v { "[deleteMessages] messages.ids: $messageIds" }
_messages?.apply { value = value - messageIds }
cachedLatestMessages.value = cachedLatestMessages.value - messageIds
deletePinnedMessages(messages)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import io.getstream.chat.android.randomUser
import io.getstream.chat.android.state.plugin.logic.channel.internal.ChannelLogic
import io.getstream.chat.android.state.plugin.logic.channel.internal.ChannelStateLogic
import io.getstream.chat.android.state.plugin.logic.internal.LogicRegistry
import io.getstream.chat.android.state.plugin.logic.querychannels.internal.QueryChannelsLogic
import io.getstream.chat.android.state.plugin.logic.querythreads.internal.QueryThreadsLogic
import io.getstream.chat.android.state.plugin.state.global.GlobalState
import io.getstream.result.Error
Expand All @@ -39,6 +40,7 @@ import org.mockito.kotlin.any
import org.mockito.kotlin.argThat
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

Expand All @@ -50,6 +52,7 @@ internal class DeleteMessageListenerStateTest {
}
private val threadsLogic: QueryThreadsLogic = mock()
private val activeThreadsLogic = listOf(threadsLogic)
private val queryChannelsLogic: QueryChannelsLogic = mock()

private val clientState: ClientState = mock {
on(it.user) doReturn MutableStateFlow(randomUser())
Expand All @@ -60,6 +63,7 @@ internal class DeleteMessageListenerStateTest {
on(it.channelFromMessageId(any())) doReturn channelLogic
on(it.channelFromMessage(any())) doReturn channelLogic
on(it.getActiveQueryThreadsLogic()) doReturn activeThreadsLogic
on(it.getActiveQueryChannelsLogic()) doReturn listOf(queryChannelsLogic)
}

private val deleteMessageListenerState: DeleteMessageListenerState =
Expand Down Expand Up @@ -307,4 +311,59 @@ internal class DeleteMessageListenerStateTest {

assertTrue(result is Result.Success)
}

@Test
fun `when a message is deleted only locally, the channel lists should be refreshed`() = runTest {
val testMessage = randomMessage(cid = randomCID(), type = MessageType.ERROR)
whenever(channelLogic.getMessage(any())) doReturn testMessage

deleteMessageListenerState.onMessageDeletePrecondition(testMessage.id)

verify(queryChannelsLogic).refreshChannelState(testMessage.cid)
}

@Test
fun `when a message is deleted remotely, the channel lists should not be refreshed before the request`() =
runTest {
val testMessage = randomMessage(
cid = randomCID(),
type = MessageType.REGULAR,
syncStatus = SyncStatus.COMPLETED,
)
whenever(channelLogic.getMessage(any())) doReturn testMessage

deleteMessageListenerState.onMessageDeletePrecondition(testMessage.id)

verify(queryChannelsLogic, never()).refreshChannelState(any())
}

@Test
fun `when the delete request starts, the channel lists should be refreshed`() = runTest {
val testMessage = randomMessage(cid = randomCID())
whenever(clientState.isNetworkAvailable) doReturn true
whenever(channelLogic.getMessage(any())) doReturn testMessage

deleteMessageListenerState.onMessageDeleteRequest(testMessage.id)

verify(queryChannelsLogic).refreshChannelState(testMessage.cid)
}

@Test
fun `when the delete request succeeds, the channel lists should be refreshed`() = runTest {
val testMessage = randomMessage(cid = randomCID())

deleteMessageListenerState.onMessageDeleteResult(testMessage.id, Result.Success(testMessage))

verify(queryChannelsLogic).refreshChannelState(testMessage.cid)
}

@Test
fun `when the delete request fails, the channel lists should be refreshed`() = runTest {
val testMessage = randomMessage(cid = randomCID())
whenever(channelLogic.getMessage(any())) doReturn testMessage

deleteMessageListenerState.onMessageDeleteResult(testMessage.id, Result.Failure(Error.GenericError("")))

verify(queryChannelsLogic).refreshChannelState(testMessage.cid)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,24 @@ internal class ChannelMutableStateTests {
}
}

@Test
fun `deleteMessages should remove messages from the cached latest messages`() = runTest {
// given
val messages = createMessages(5)
channelState.updateCachedLatestMessages(messages.associateBy { it.id })
val messagesToDelete = messages.take(2)

// when
channelState.deleteMessages(messagesToDelete)

// then
assertEquals(messages.drop(2).map { it.id }.toSet(), channelState.cachedLatestMessages.value.keys)
assertEquals(
messages.drop(2).map { it.id }.toSet(),
channelState.toChannel().cachedLatestMessages.map { it.id }.toSet(),
)
}

@Test
fun `deleteMessages with empty list should not affect channel state`() = runTest {
// given
Expand Down
Loading