Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: archive only locally
Browse files Browse the repository at this point in the history
Garzas committed Oct 23, 2023
1 parent c82d8aa commit 7d39930
Showing 2 changed files with 112 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -21,9 +21,11 @@ package com.wire.kalium.logic.feature.conversation
import com.wire.kalium.logic.data.conversation.ConversationRepository
import com.wire.kalium.logic.data.conversation.MutedConversationStatus
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.functional.Either
import com.wire.kalium.logic.functional.flatMap
import com.wire.kalium.logic.functional.fold
import com.wire.kalium.logic.functional.onFailure
import com.wire.kalium.logic.functional.onSuccess
import com.wire.kalium.logic.kaliumLogger
import com.wire.kalium.util.DateTimeUtil

@@ -33,12 +35,14 @@ interface UpdateConversationArchivedStatusUseCase {
*
* @param conversationId the id of the conversation where status wants to be changed
* @param shouldArchiveConversation new archived status to be updated on the given conversation
* @param onlyLocally controls if archived status should only be updated locally
* @param archivedStatusTimestamp the timestamp when the archiving event occurred
* @return an [ConversationUpdateStatusResult] containing Success or Failure cases
*/
suspend operator fun invoke(
conversationId: ConversationId,
shouldArchiveConversation: Boolean,
onlyLocally: Boolean,
archivedStatusTimestamp: Long = DateTimeUtil.currentInstant().toEpochMilliseconds()
): ArchiveStatusUpdateResult
}
@@ -50,43 +54,80 @@ internal class UpdateConversationArchivedStatusUseCaseImpl(
override suspend operator fun invoke(
conversationId: ConversationId,
shouldArchiveConversation: Boolean,
onlyLocally: Boolean,
archivedStatusTimestamp: Long
): ArchiveStatusUpdateResult =
conversationRepository.updateArchivedStatusRemotely(conversationId, shouldArchiveConversation, archivedStatusTimestamp).onFailure {
kaliumLogger.e("Something went wrong when updating remotely convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)")
}.flatMap {
conversationRepository.updateArchivedStatusLocally(conversationId, shouldArchiveConversation, archivedStatusTimestamp)
}.fold({
kaliumLogger.e("Something went wrong when updating locally convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)")
ArchiveStatusUpdateResult.Failure
}, {
kaliumLogger.d("Successfully updated remotely and locally convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)")

// Now we should make sure the conversation gets muted if it's archived or un-muted if it's unarchived
val updatedMutedStatus = if (shouldArchiveConversation) {
MutedConversationStatus.AllMuted
} else {
MutedConversationStatus.AllAllowed
}
conversationRepository.updateMutedStatusRemotely(conversationId, updatedMutedStatus, archivedStatusTimestamp)
.flatMap {
conversationRepository.updateMutedStatusLocally(conversationId, updatedMutedStatus, archivedStatusTimestamp)
}.fold({
if (!onlyLocally) {
conversationRepository.updateArchivedStatusRemotely(conversationId, shouldArchiveConversation, archivedStatusTimestamp)
.onFailure {
kaliumLogger.e(
"Something went wrong when updating the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
"Something went wrong when updating remotely convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)"
)
}, {
}
.onSuccess {
kaliumLogger.d(
"Successfully updated remotely and locally the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}")
})
// Even if the muting status update fails, we should still return success as the archived status update was successful
ArchiveStatusUpdateResult.Success
})
"Successfully updated remotely convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)"
)
}
} else {
Either.Right(Unit)
}
.flatMap {
conversationRepository.updateArchivedStatusLocally(conversationId, shouldArchiveConversation, archivedStatusTimestamp)
}.fold({
kaliumLogger.e(
"Something went wrong when updating locally convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)"
)
ArchiveStatusUpdateResult.Failure
}, {
kaliumLogger.d(
"Successfully updated locally convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)"
)

// Now we should make sure the conversation gets muted if it's archived or un-muted if it's unarchived
val updatedMutedStatus = if (shouldArchiveConversation) {
MutedConversationStatus.AllMuted
} else {
MutedConversationStatus.AllAllowed
}

if (!onlyLocally) {
conversationRepository.updateMutedStatusRemotely(conversationId, updatedMutedStatus, archivedStatusTimestamp)
.onFailure {
kaliumLogger.e(
"Something went wrong when updating remotely the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
)
}
.onSuccess {
kaliumLogger.d(
"Successfully updated remotely the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
)
}
} else {
Either.Right(Unit)
}
.flatMap {
conversationRepository.updateMutedStatusLocally(conversationId, updatedMutedStatus, archivedStatusTimestamp)
}.fold({
kaliumLogger.e(
"Something went wrong when updating locally the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
)
}, {
kaliumLogger.d(
"Successfully updated locally the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
)
})
// Even if the muting status update fails, we should still return success as the archived status update was successful
ArchiveStatusUpdateResult.Success
})
}

sealed class ArchiveStatusUpdateResult {
Original file line number Diff line number Diff line change
@@ -42,13 +42,14 @@ class UpdateConversationArchivedStatusUseCaseTest {
val conversationId = TestConversation.ID
val isConversationArchived = true
val archivedStatusTimestamp = 123456789L
val onlyLocally = false

val (arrangement, updateConversationArchivedStatus) = Arrangement()
.withSuccessfulMutingUpdates()
.withUpdateArchivedStatusFullSuccess()
.arrange()

val result = updateConversationArchivedStatus(conversationId, isConversationArchived, archivedStatusTimestamp)
val result = updateConversationArchivedStatus(conversationId, isConversationArchived, onlyLocally, archivedStatusTimestamp)
assertEquals(ArchiveStatusUpdateResult.Success::class, result::class)

with(arrangement) {
@@ -64,18 +65,48 @@ class UpdateConversationArchivedStatusUseCaseTest {
}
}

@Test
fun givenAConversationId_whenInvokingAnArchivedStatusChangeAndUserIsNotMember_thenShouldArchiveOnlyLocally() =
runTest {
val conversationId = TestConversation.ID
val isConversationArchived = true
val archivedStatusTimestamp = 123456789L
val onlyLocally = true

val (arrangement, updateConversationArchivedStatus) = Arrangement()
.withSuccessfulMutingUpdates()
.withUpdateArchivedStatusFullSuccess()
.arrange()

val result = updateConversationArchivedStatus(conversationId, isConversationArchived, onlyLocally, archivedStatusTimestamp)
assertEquals(ArchiveStatusUpdateResult.Success::class, result::class)

with(arrangement) {
verify(conversationRepository)
.suspendFunction(conversationRepository::updateArchivedStatusRemotely)
.with(any(), any())
.wasNotInvoked()

verify(conversationRepository)
.suspendFunction(conversationRepository::updateArchivedStatusLocally)
.with(any(), eq(isConversationArchived), matching { it == archivedStatusTimestamp })
.wasInvoked(exactly = once)
}
}

@Test
fun givenAConversationId_whenInvokingAnArchivedStatusChangeAndFails_thenShouldDelegateTheCallAndReturnAFailureResult() = runTest {
val conversationId = TestConversation.ID
val isConversationArchived = true
val archivedStatusTimestamp = 123456789L
val onlyLocally = false

val (arrangement, updateConversationArchivedStatus) = Arrangement()
.withSuccessfulMutingUpdates()
.withRemoteUpdateArchivedStatusFailure()
.arrange()

val result = updateConversationArchivedStatus(conversationId, isConversationArchived, archivedStatusTimestamp)
val result = updateConversationArchivedStatus(conversationId, isConversationArchived, onlyLocally, archivedStatusTimestamp)
assertEquals(ArchiveStatusUpdateResult.Failure::class, result::class)

with(arrangement) {
@@ -96,13 +127,14 @@ class UpdateConversationArchivedStatusUseCaseTest {
val conversationId = TestConversation.ID
val isConversationArchived = true
val archivedStatusTimestamp = 123456789L
val onlyLocally = false

val (arrangement, updateConversationArchivedStatus) = Arrangement()
.withLocalUpdateArchivedStatusFailure()
.withSuccessfulMutingUpdates()
.arrange()

val result = updateConversationArchivedStatus(conversationId, isConversationArchived, archivedStatusTimestamp)
val result = updateConversationArchivedStatus(conversationId, isConversationArchived, onlyLocally, archivedStatusTimestamp)
assertEquals(ArchiveStatusUpdateResult.Failure::class, result::class)

with(arrangement) {
@@ -124,13 +156,14 @@ class UpdateConversationArchivedStatusUseCaseTest {
val conversationId = TestConversation.ID
val isConversationArchived = true
val archivedStatusTimestamp = 123456789L
val onlyLocally = false

val (arrangement, updateConversationArchivedStatus) = Arrangement()
.withUpdateArchivedStatusFullSuccess()
.withRemoteErrorMutingUpdates()
.arrange()

val result = updateConversationArchivedStatus(conversationId, isConversationArchived, archivedStatusTimestamp)
val result = updateConversationArchivedStatus(conversationId, isConversationArchived, onlyLocally, archivedStatusTimestamp)
assertTrue(result is ArchiveStatusUpdateResult.Success)

with(arrangement) {
@@ -152,13 +185,14 @@ class UpdateConversationArchivedStatusUseCaseTest {
val conversationId = TestConversation.ID
val isConversationArchived = true
val archivedStatusTimestamp = 123456789L
val onlyLocally = false

val (arrangement, updateConversationArchivedStatus) = Arrangement()
.withUpdateArchivedStatusFullSuccess()
.withLocalErrorMutingUpdates()
.arrange()

val result = updateConversationArchivedStatus(conversationId, isConversationArchived, archivedStatusTimestamp)
val result = updateConversationArchivedStatus(conversationId, isConversationArchived, onlyLocally, archivedStatusTimestamp)
assertTrue(result is ArchiveStatusUpdateResult.Success)

with(arrangement) {

0 comments on commit 7d39930

Please sign in to comment.