Skip to content

Commit

Permalink
feat: update conversation guest link when opning the conversation (#2744
Browse files Browse the repository at this point in the history
)

Co-authored-by: Oussama Hassine <[email protected]>
  • Loading branch information
MohamadJaara and ohassine authored Mar 22, 2024
1 parent 50ccd98 commit bb3bc09
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import com.wire.kalium.logic.feature.conversation.RenameConversationUseCase
import com.wire.kalium.logic.feature.conversation.SendTypingEventUseCase
import com.wire.kalium.logic.feature.conversation.SetNotifiedAboutConversationUnderLegalHoldUseCase
import com.wire.kalium.logic.feature.conversation.SetUserInformedAboutVerificationUseCase
import com.wire.kalium.logic.feature.conversation.SyncConversationCodeUseCase
import com.wire.kalium.logic.feature.conversation.UpdateConversationAccessRoleUseCase
import com.wire.kalium.logic.feature.conversation.UpdateConversationArchivedStatusUseCase
import com.wire.kalium.logic.feature.conversation.UpdateConversationMemberRoleUseCase
Expand Down Expand Up @@ -288,4 +289,9 @@ class ConversationModule {
fun provideObserveLegalHoldWithChangeNotifiedForConversationUseCase(
conversationScope: ConversationScope,
): ObserveConversationUnderLegalHoldNotifiedUseCase = conversationScope.observeConversationUnderLegalHoldNotified

@ViewModelScoped
@Provides
fun provideSyncConversationCodeUseCase(conversationScope: ConversationScope): SyncConversationCodeUseCase =
conversationScope.syncConversationCode
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.wire.android.util.dispatchers.DispatcherProvider
import com.wire.kalium.logic.data.conversation.Conversation
import com.wire.kalium.logic.data.id.QualifiedID
import com.wire.kalium.logic.feature.conversation.ObserveConversationDetailsUseCase
import com.wire.kalium.logic.feature.conversation.SyncConversationCodeUseCase
import com.wire.kalium.logic.feature.conversation.UpdateConversationAccessRoleUseCase
import com.wire.kalium.logic.feature.conversation.guestroomlink.CanCreatePasswordProtectedLinksUseCase
import com.wire.kalium.logic.feature.conversation.guestroomlink.GenerateGuestRoomLinkResult
Expand All @@ -49,6 +50,8 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import javax.inject.Inject

Expand All @@ -64,6 +67,7 @@ class EditGuestAccessViewModel @Inject constructor(
private val observeGuestRoomLink: ObserveGuestRoomLinkUseCase,
private val observeGuestRoomLinkFeatureFlag: ObserveGuestRoomLinkFeatureFlagUseCase,
private val canCreatePasswordProtectedLinks: CanCreatePasswordProtectedLinksUseCase,
private val syncConversationCode: SyncConversationCodeUseCase,
savedStateHandle: SavedStateHandle
) : ViewModel() {

Expand All @@ -86,6 +90,20 @@ class EditGuestAccessViewModel @Inject constructor(
checkIfUserCanCreatePasswordProtectedLinks()
}

private val syncCodeMutex = Mutex()

private var isGuestCodeUpdated = false
private fun updateConversationCodeOnce() {
viewModelScope.launch {
syncCodeMutex.withLock {
if (!isGuestCodeUpdated) {
syncConversationCode(conversationId)
isGuestCodeUpdated = true
}
}
}
}

private fun checkIfUserCanCreatePasswordProtectedLinks() {
viewModelScope.launch {
val canCreatePasswordProtectedLinks = when {
Expand Down Expand Up @@ -123,6 +141,8 @@ class EditGuestAccessViewModel @Inject constructor(
conversationDetailsFlow,
isSelfAdminFlow
) { conversationDetails, isSelfAnAdmin ->
isSelfAnAdmin to conversationDetails
}.collect { (isSelfAnAdmin, conversationDetails) ->

val isGuestAllowed =
conversationDetails.conversation.isGuestAllowed() || conversationDetails.conversation.isNonTeamMemberAllowed()
Expand All @@ -132,6 +152,8 @@ class EditGuestAccessViewModel @Inject constructor(
isServicesAccessAllowed = conversationDetails.conversation.isServicesAllowed(),
isUpdatingGuestAccessAllowed = isSelfAnAdmin
)

if (isGuestAllowed) updateConversationCodeOnce()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ import androidx.lifecycle.SavedStateHandle
import com.wire.android.config.CoroutineTestExtension
import com.wire.android.config.NavigationTestExtension
import com.wire.android.config.TestDispatcherProvider
import com.wire.android.ui.home.conversations.details.participants.model.ConversationParticipantsData
import com.wire.android.ui.home.conversations.details.participants.usecase.ObserveParticipantsForConversationUseCase
import com.wire.android.ui.navArgs
import com.wire.android.ui.userprofile.other.OtherUserProfileScreenViewModelTest
import com.wire.kalium.logic.CoreFailure
import com.wire.kalium.logic.NetworkFailure
import com.wire.kalium.logic.feature.conversation.ObserveConversationDetailsUseCase
import com.wire.kalium.logic.feature.conversation.SyncConversationCodeUseCase
import com.wire.kalium.logic.feature.conversation.UpdateConversationAccessRoleUseCase
import com.wire.kalium.logic.feature.conversation.guestroomlink.CanCreatePasswordProtectedLinksUseCase
import com.wire.kalium.logic.feature.conversation.guestroomlink.GenerateGuestRoomLinkResult
Expand All @@ -44,7 +46,9 @@ import io.mockk.coVerify
import io.mockk.every
import io.mockk.impl.annotations.MockK
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.internal.assertEquals
import org.junit.jupiter.api.Test
Expand All @@ -62,6 +66,7 @@ class EditGuestAccessViewModelTest {
val (arrangement, editGuestAccessViewModel) = Arrangement()
.withUpdateConversationAccessRoleResult(UpdateConversationAccessRoleUseCase.Result.Success)
.arrange()
advanceUntilIdle()

// when
editGuestAccessViewModel.updateGuestAccess(true)
Expand All @@ -72,41 +77,47 @@ class EditGuestAccessViewModelTest {
}

@Test
fun `given a failure when running updateConversationAccessRole, when trying to enable guest access, then do not enable guest access`() {
// given
val (arrangement, editGuestAccessViewModel) = Arrangement()
.withUpdateConversationAccessRoleResult(
UpdateConversationAccessRoleUseCase.Result.Failure(CoreFailure.MissingClientRegistration)
).arrange()
fun `given a failure when running updateConversationAccessRole, when trying to enable guest access, then do not enable guest access`() =
runTest {
// given
val (arrangement, editGuestAccessViewModel) = Arrangement()
.withUpdateConversationAccessRoleResult(
UpdateConversationAccessRoleUseCase.Result.Failure(CoreFailure.MissingClientRegistration)
).arrange()
advanceUntilIdle()

// when
editGuestAccessViewModel.updateGuestAccess(true)
// when
editGuestAccessViewModel.updateGuestAccess(true)

// then
coVerify(exactly = 1) { arrangement.updateConversationAccessRole(any(), any(), any()) }
assertEquals(false, editGuestAccessViewModel.editGuestAccessState.isGuestAccessAllowed)
}
// then
coVerify(exactly = 1) { arrangement.updateConversationAccessRole(any(), any(), any()) }
assertEquals(false, editGuestAccessViewModel.editGuestAccessState.isGuestAccessAllowed)
}

@Test
fun `given guest access is activated, when trying to disable guest access, then display dialog before disabling guest access`() {
// given
val (arrangement, editGuestAccessViewModel) = Arrangement()
.withUpdateConversationAccessRoleResult(UpdateConversationAccessRoleUseCase.Result.Success).arrange()
fun `given guest access is activated, when trying to disable guest access, then display dialog before disabling guest access`() =
runTest {
// given
val (arrangement, editGuestAccessViewModel) = Arrangement()
.withUpdateConversationAccessRoleResult(UpdateConversationAccessRoleUseCase.Result.Success)
.arrange()
advanceUntilIdle()

// when
editGuestAccessViewModel.updateGuestAccess(false)
// when
editGuestAccessViewModel.updateGuestAccess(false)

// then
coVerify(inverse = true) { arrangement.updateConversationAccessRoleUseCase(any(), any(), any()) }
assertEquals(true, editGuestAccessViewModel.editGuestAccessState.shouldShowGuestAccessChangeConfirmationDialog)
}
// then
coVerify(inverse = true) { arrangement.updateConversationAccessRoleUseCase(any(), any(), any()) }
assertEquals(true, editGuestAccessViewModel.editGuestAccessState.shouldShowGuestAccessChangeConfirmationDialog)
}

@Test
fun `given useCase runs with success, when_generating guest link, then invoke it once`() = runTest {
// given
val (arrangement, editGuestAccessViewModel) = Arrangement()
.withGenerateGuestRoomResult(GenerateGuestRoomLinkResult.Success)
.arrange()
advanceUntilIdle()

// when
editGuestAccessViewModel.onRequestGuestRoomLink()
Expand All @@ -123,6 +134,7 @@ class EditGuestAccessViewModelTest {
.withGenerateGuestRoomResult(
GenerateGuestRoomLinkResult.Failure(NetworkFailure.NoNetworkConnection(RuntimeException("no network")))
).arrange()
advanceUntilIdle()

// when
editGuestAccessViewModel.onRequestGuestRoomLink()
Expand All @@ -138,6 +150,7 @@ class EditGuestAccessViewModelTest {
val (arrangement, editGuestAccessViewModel) = Arrangement()
.withRevokeGuestRoomLinkResult(RevokeGuestRoomLinkResult.Success)
.arrange()
advanceUntilIdle()

// when
editGuestAccessViewModel.removeGuestLink()
Expand All @@ -153,6 +166,7 @@ class EditGuestAccessViewModelTest {
val (arrangement, editGuestAccessViewModel) = Arrangement()
.withRevokeGuestRoomLinkResult(RevokeGuestRoomLinkResult.Failure(CoreFailure.MissingClientRegistration))
.arrange()
advanceUntilIdle()

// when
editGuestAccessViewModel.removeGuestLink()
Expand All @@ -170,6 +184,7 @@ class EditGuestAccessViewModelTest {
val (arrangement, editGuestAccessViewModel) = Arrangement()
.withUpdateConversationAccessRoleResult(UpdateConversationAccessRoleUseCase.Result.Success)
.arrange()
advanceUntilIdle()

// when
editGuestAccessViewModel.onGuestDialogConfirm()
Expand All @@ -188,6 +203,7 @@ class EditGuestAccessViewModelTest {
UpdateConversationAccessRoleUseCase.Result.Failure(CoreFailure.MissingClientRegistration)
)
.arrange()
advanceUntilIdle()

// when
editGuestAccessViewModel.onGuestDialogConfirm()
Expand Down Expand Up @@ -228,6 +244,9 @@ class EditGuestAccessViewModelTest {
@MockK
lateinit var canCreatePasswordProtectedLinks: CanCreatePasswordProtectedLinksUseCase

@MockK
lateinit var syncConversationCodeUseCase: SyncConversationCodeUseCase

val editGuestAccessViewModel: EditGuestAccessViewModel by lazy {
EditGuestAccessViewModel(
savedStateHandle = savedStateHandle,
Expand All @@ -239,7 +258,8 @@ class EditGuestAccessViewModelTest {
revokeGuestRoomLink = revokeGuestRoomLink,
observeGuestRoomLinkFeatureFlag = observeGuestRoomLinkFeatureFlag,
canCreatePasswordProtectedLinks = canCreatePasswordProtectedLinks,
dispatcher = TestDispatcherProvider()
dispatcher = TestDispatcherProvider(),
syncConversationCode = syncConversationCodeUseCase
)
}

Expand All @@ -260,6 +280,18 @@ class EditGuestAccessViewModelTest {
coEvery { canCreatePasswordProtectedLinks() } returns true
}

fun withSyncConversationCodeSuccess() = apply {
coEvery { syncConversationCodeUseCase.invoke(any()) }
}

fun withConversationMembers(result: Flow<ConversationParticipantsData>) = apply {
coEvery { observeConversationMembers(any()) } returns result
}

fun withConversationDetails(result: Flow<ObserveConversationDetailsUseCase.Result>) = apply {
coEvery { observeConversationDetails(any()) } returns result
}

fun withRevokeGuestRoomLinkResult(result: RevokeGuestRoomLinkResult) = apply {
coEvery { revokeGuestRoomLink(any()) } returns result
}
Expand Down
2 changes: 1 addition & 1 deletion kalium
Submodule kalium updated 27 files
+27 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/draft/MessageDraft.kt
+36 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/draft/MessageDraftMapper.kt
+50 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/draft/MessageDraftRepository.kt
+1 βˆ’1 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/mention/MessageMentionMapper.kt
+6 βˆ’7 logic/src/commonMain/kotlin/com/wire/kalium/logic/data/user/UserRepository.kt
+8 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt
+2 βˆ’3 ...Main/kotlin/com/wire/kalium/logic/feature/conversation/ObserveConversationInteractionAvailabilityUseCase.kt
+17 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageScope.kt
+44 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/draft/GetMessageDraftUseCase.kt
+41 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/draft/RemoveMessageDraftUseCase.kt
+44 βˆ’0 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/draft/SaveMessageDraftUseCase.kt
+147 βˆ’0 logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/draft/MessageDraftRepositoryTest.kt
+1 βˆ’1 logic/src/commonTest/kotlin/com/wire/kalium/logic/data/user/UserRepositoryTest.kt
+2 βˆ’2 .../kotlin/com/wire/kalium/logic/feature/conversation/ObserveConversationInteractionAvailabilityUseCaseTest.kt
+119 βˆ’0 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/draft/GetMessageDraftUseCaseTest.kt
+72 βˆ’0 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/draft/RemoveMessageDraftUseCaseTest.kt
+85 βˆ’0 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/message/draft/SaveMessageDraftUseCaseTest.kt
+31 βˆ’0 persistence/src/commonMain/db_user/com/wire/kalium/persistence/MessageDrafts.sq
+16 βˆ’0 persistence/src/commonMain/db_user/migrations/79.sqm
+36 βˆ’0 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/adapter/MentionListAdapter.kt
+1 βˆ’1 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/MessageDAOImpl.kt
+27 βˆ’0 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/draft/MessageDraftDAO.kt
+56 βˆ’0 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/draft/MessageDraftDAOImpl.kt
+27 βˆ’0 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/message/draft/MessageDraftEntity.kt
+7 βˆ’0 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/db/TableMapper.kt
+8 βˆ’1 persistence/src/commonMain/kotlin/com/wire/kalium/persistence/db/UserDatabaseBuilder.kt
+150 βˆ’0 persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/message/draft/MessageDraftDAOTest.kt

0 comments on commit bb3bc09

Please sign in to comment.