Update "Learn more" link (#4686)
* Update target link for "Learn more". * Rename VerifySelfSession* to OutgoingVerification* * Optimize import * Refactor to avoid long line * Update screenshots --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
@@ -9,6 +9,7 @@ package io.element.android.appconfig
|
||||
|
||||
object LearnMoreConfig {
|
||||
const val ENCRYPTION_URL: String = "https://element.io/help#encryption"
|
||||
const val DEVICE_VERIFICATION_URL: String = "https://element.io/help#encryption-device-verification"
|
||||
const val SECURE_BACKUP_URL: String = "https://element.io/help#encryption5"
|
||||
const val IDENTITY_CHANGE_URL: String = "https://element.io/help#encryption18"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import extension.setupAnvil
|
||||
import org.gradle.kotlin.dsl.test
|
||||
|
||||
/*
|
||||
* Copyright 2023, 2024 New Vector Ltd.
|
||||
|
||||
@@ -26,7 +26,7 @@ import io.element.android.anvilannotations.ContributesNode
|
||||
import io.element.android.appconfig.LearnMoreConfig
|
||||
import io.element.android.features.ftue.impl.sessionverification.choosemode.ChooseSelfVerificationModeNode
|
||||
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
|
||||
import io.element.android.features.verifysession.api.VerifySessionEntryPoint
|
||||
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
import io.element.android.libraries.architecture.BaseFlowNode
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
@@ -40,7 +40,7 @@ import kotlinx.parcelize.Parcelize
|
||||
class FtueSessionVerificationFlowNode @AssistedInject constructor(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
private val verifySessionEntryPoint: VerifySessionEntryPoint,
|
||||
private val outgoingVerificationEntryPoint: OutgoingVerificationEntryPoint,
|
||||
private val secureBackupEntryPoint: SecureBackupEntryPoint,
|
||||
) : BaseFlowNode<FtueSessionVerificationFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
@@ -94,19 +94,19 @@ class FtueSessionVerificationFlowNode @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override fun onLearnMoreAboutEncryption() {
|
||||
learnMoreUrl.value = LearnMoreConfig.ENCRYPTION_URL
|
||||
learnMoreUrl.value = LearnMoreConfig.DEVICE_VERIFICATION_URL
|
||||
}
|
||||
}
|
||||
|
||||
createNode<ChooseSelfVerificationModeNode>(buildContext, plugins = listOf(callback))
|
||||
}
|
||||
is NavTarget.UseAnotherDevice -> {
|
||||
verifySessionEntryPoint.nodeBuilder(this, buildContext)
|
||||
.params(VerifySessionEntryPoint.Params(
|
||||
outgoingVerificationEntryPoint.nodeBuilder(this, buildContext)
|
||||
.params(OutgoingVerificationEntryPoint.Params(
|
||||
showDeviceVerifiedScreen = true,
|
||||
verificationRequest = VerificationRequest.Outgoing.CurrentSession,
|
||||
))
|
||||
.callback(object : VerifySessionEntryPoint.Callback {
|
||||
.callback(object : OutgoingVerificationEntryPoint.Callback {
|
||||
override fun onDone() {
|
||||
plugins<Callback>().forEach { it.onDone() }
|
||||
}
|
||||
@@ -116,7 +116,8 @@ class FtueSessionVerificationFlowNode @AssistedInject constructor(
|
||||
}
|
||||
|
||||
override fun onLearnMoreAboutEncryption() {
|
||||
learnMoreUrl.value = LearnMoreConfig.ENCRYPTION_URL
|
||||
// Note that this callback is never called. The "Learn more" link is not displayed
|
||||
// for the self session interactive verification.
|
||||
}
|
||||
})
|
||||
.build()
|
||||
|
||||
@@ -25,7 +25,6 @@ import io.element.android.libraries.preferences.test.InMemoryAppPreferencesStore
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.test
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
@@ -38,7 +38,7 @@ import io.element.android.features.roomdetails.impl.notificationsettings.RoomNot
|
||||
import io.element.android.features.roomdetails.impl.rolesandpermissions.RolesAndPermissionsFlowNode
|
||||
import io.element.android.features.roomdetails.impl.securityandprivacy.SecurityAndPrivacyFlowNode
|
||||
import io.element.android.features.userprofile.shared.UserProfileNodeHelper
|
||||
import io.element.android.features.verifysession.api.VerifySessionEntryPoint
|
||||
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||
import io.element.android.libraries.architecture.BackstackWithOverlayBox
|
||||
import io.element.android.libraries.architecture.BaseFlowNode
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
@@ -71,7 +71,7 @@ class RoomDetailsFlowNode @AssistedInject constructor(
|
||||
private val knockRequestsListEntryPoint: KnockRequestsListEntryPoint,
|
||||
private val mediaViewerEntryPoint: MediaViewerEntryPoint,
|
||||
private val mediaGalleryEntryPoint: MediaGalleryEntryPoint,
|
||||
private val verifySessionEntryPoint: VerifySessionEntryPoint,
|
||||
private val outgoingVerificationEntryPoint: OutgoingVerificationEntryPoint,
|
||||
private val reportRoomEntryPoint: ReportRoomEntryPoint,
|
||||
) : BaseFlowNode<RoomDetailsFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
@@ -328,13 +328,13 @@ class RoomDetailsFlowNode @AssistedInject constructor(
|
||||
createNode<SecurityAndPrivacyFlowNode>(buildContext)
|
||||
}
|
||||
is NavTarget.VerifyUser -> {
|
||||
val params = VerifySessionEntryPoint.Params(
|
||||
val params = OutgoingVerificationEntryPoint.Params(
|
||||
showDeviceVerifiedScreen = true,
|
||||
verificationRequest = VerificationRequest.Outgoing.User(userId = navTarget.userId,)
|
||||
)
|
||||
verifySessionEntryPoint.nodeBuilder(this, buildContext)
|
||||
outgoingVerificationEntryPoint.nodeBuilder(this, buildContext)
|
||||
.params(params)
|
||||
.callback(object : VerifySessionEntryPoint.Callback {
|
||||
.callback(object : OutgoingVerificationEntryPoint.Callback {
|
||||
override fun onDone() {
|
||||
backstack.pop()
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import io.element.android.features.call.api.ElementCallEntryPoint
|
||||
import io.element.android.features.userprofile.api.UserProfileEntryPoint
|
||||
import io.element.android.features.userprofile.impl.root.UserProfileNode
|
||||
import io.element.android.features.userprofile.shared.UserProfileNodeHelper
|
||||
import io.element.android.features.verifysession.api.VerifySessionEntryPoint
|
||||
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||
import io.element.android.libraries.architecture.BackstackView
|
||||
import io.element.android.libraries.architecture.BaseFlowNode
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
@@ -46,7 +46,7 @@ class UserProfileFlowNode @AssistedInject constructor(
|
||||
private val elementCallEntryPoint: ElementCallEntryPoint,
|
||||
private val sessionIdHolder: CurrentSessionIdHolder,
|
||||
private val mediaViewerEntryPoint: MediaViewerEntryPoint,
|
||||
private val verifySessionEntryPoint: VerifySessionEntryPoint,
|
||||
private val outgoingVerificationEntryPoint: OutgoingVerificationEntryPoint,
|
||||
) : BaseFlowNode<UserProfileFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
initialElement = NavTarget.Root,
|
||||
@@ -110,11 +110,11 @@ class UserProfileFlowNode @AssistedInject constructor(
|
||||
.build()
|
||||
}
|
||||
is NavTarget.VerifyUser -> {
|
||||
val params = VerifySessionEntryPoint.Params(
|
||||
val params = OutgoingVerificationEntryPoint.Params(
|
||||
showDeviceVerifiedScreen = false,
|
||||
verificationRequest = VerificationRequest.Outgoing.User(userId = navTarget.userId)
|
||||
)
|
||||
verifySessionEntryPoint.nodeBuilder(this, buildContext)
|
||||
outgoingVerificationEntryPoint.nodeBuilder(this, buildContext)
|
||||
.params(params)
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import io.element.android.libraries.architecture.FeatureEntryPoint
|
||||
import io.element.android.libraries.architecture.NodeInputs
|
||||
import io.element.android.libraries.matrix.api.verification.VerificationRequest
|
||||
|
||||
interface VerifySessionEntryPoint : FeatureEntryPoint {
|
||||
interface OutgoingVerificationEntryPoint : FeatureEntryPoint {
|
||||
data class Params(
|
||||
val showDeviceVerifiedScreen: Boolean,
|
||||
val verificationRequest: VerificationRequest.Outgoing,
|
||||
@@ -11,29 +11,29 @@ import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.bumble.appyx.core.node.Node
|
||||
import com.bumble.appyx.core.plugin.Plugin
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.features.verifysession.api.VerifySessionEntryPoint
|
||||
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||
import io.element.android.libraries.architecture.createNode
|
||||
import io.element.android.libraries.di.AppScope
|
||||
import javax.inject.Inject
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultVerifySessionEntryPoint @Inject constructor() : VerifySessionEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): VerifySessionEntryPoint.NodeBuilder {
|
||||
class DefaultOutgoingVerificationEntryPoint @Inject constructor() : OutgoingVerificationEntryPoint {
|
||||
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): OutgoingVerificationEntryPoint.NodeBuilder {
|
||||
val plugins = ArrayList<Plugin>()
|
||||
|
||||
return object : VerifySessionEntryPoint.NodeBuilder {
|
||||
override fun callback(callback: VerifySessionEntryPoint.Callback): VerifySessionEntryPoint.NodeBuilder {
|
||||
return object : OutgoingVerificationEntryPoint.NodeBuilder {
|
||||
override fun callback(callback: OutgoingVerificationEntryPoint.Callback): OutgoingVerificationEntryPoint.NodeBuilder {
|
||||
plugins += callback
|
||||
return this
|
||||
}
|
||||
|
||||
override fun params(params: VerifySessionEntryPoint.Params): VerifySessionEntryPoint.NodeBuilder {
|
||||
override fun params(params: OutgoingVerificationEntryPoint.Params): OutgoingVerificationEntryPoint.NodeBuilder {
|
||||
plugins += params
|
||||
return this
|
||||
}
|
||||
|
||||
override fun build(): Node {
|
||||
return parentNode.createNode<VerifySelfSessionNode>(buildContext, plugins)
|
||||
return parentNode.createNode<OutgoingVerificationNode>(buildContext, plugins)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,19 @@ import com.bumble.appyx.core.plugin.plugins
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import io.element.android.anvilannotations.ContributesNode
|
||||
import io.element.android.features.verifysession.api.VerifySessionEntryPoint
|
||||
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
|
||||
import io.element.android.libraries.architecture.inputs
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
|
||||
@ContributesNode(SessionScope::class)
|
||||
class VerifySelfSessionNode @AssistedInject constructor(
|
||||
class OutgoingVerificationNode @AssistedInject constructor(
|
||||
@Assisted buildContext: BuildContext,
|
||||
@Assisted plugins: List<Plugin>,
|
||||
presenterFactory: VerifySelfSessionPresenter.Factory,
|
||||
presenterFactory: OutgoingVerificationPresenter.Factory,
|
||||
) : Node(buildContext, plugins = plugins) {
|
||||
private val callback = plugins<VerifySessionEntryPoint.Callback>().first()
|
||||
private val callback = plugins<OutgoingVerificationEntryPoint.Callback>().first()
|
||||
|
||||
private val inputs = inputs<VerifySessionEntryPoint.Params>()
|
||||
private val inputs = inputs<OutgoingVerificationEntryPoint.Params>()
|
||||
|
||||
private val presenter = presenterFactory.create(
|
||||
showDeviceVerifiedScreen = inputs.showDeviceVerifiedScreen,
|
||||
@@ -38,7 +38,7 @@ class VerifySelfSessionNode @AssistedInject constructor(
|
||||
@Composable
|
||||
override fun View(modifier: Modifier) {
|
||||
val state = presenter.present()
|
||||
VerifySelfSessionView(
|
||||
OutgoingVerificationView(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
onLearnMoreClick = callback::onLearnMoreAboutEncryption,
|
||||
@@ -31,30 +31,30 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import io.element.android.features.verifysession.impl.outgoing.VerifySelfSessionStateMachine.Event as StateMachineEvent
|
||||
import io.element.android.features.verifysession.impl.outgoing.VerifySelfSessionStateMachine.State as StateMachineState
|
||||
import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationStateMachine.Event as StateMachineEvent
|
||||
import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationStateMachine.State as StateMachineState
|
||||
|
||||
class VerifySelfSessionPresenter @AssistedInject constructor(
|
||||
class OutgoingVerificationPresenter @AssistedInject constructor(
|
||||
@Assisted private val showDeviceVerifiedScreen: Boolean,
|
||||
@Assisted private val verificationRequest: VerificationRequest.Outgoing,
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
private val encryptionService: EncryptionService,
|
||||
) : Presenter<VerifySelfSessionState> {
|
||||
) : Presenter<OutgoingVerificationState> {
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(
|
||||
verificationRequest: VerificationRequest.Outgoing,
|
||||
showDeviceVerifiedScreen: Boolean,
|
||||
): VerifySelfSessionPresenter
|
||||
): OutgoingVerificationPresenter
|
||||
}
|
||||
|
||||
private val stateMachine = VerifySelfSessionStateMachine(
|
||||
private val stateMachine = OutgoingVerificationStateMachine(
|
||||
sessionVerificationService = sessionVerificationService,
|
||||
encryptionService = encryptionService,
|
||||
)
|
||||
|
||||
@Composable
|
||||
override fun present(): VerifySelfSessionState {
|
||||
override fun present(): OutgoingVerificationState {
|
||||
val stateAndDispatch = stateMachine.rememberStateAndDispatch()
|
||||
|
||||
val sessionVerifiedStatus by sessionVerificationService.sessionVerifiedStatus.collectAsState()
|
||||
@@ -63,17 +63,17 @@ class VerifySelfSessionPresenter @AssistedInject constructor(
|
||||
when (verificationRequest) {
|
||||
is VerificationRequest.Outgoing.CurrentSession -> {
|
||||
when (sessionVerifiedStatus) {
|
||||
SessionVerifiedStatus.Unknown -> VerifySelfSessionState.Step.Loading
|
||||
SessionVerifiedStatus.Unknown -> OutgoingVerificationState.Step.Loading
|
||||
SessionVerifiedStatus.NotVerified -> {
|
||||
stateAndDispatch.state.value.toVerificationStep()
|
||||
}
|
||||
SessionVerifiedStatus.Verified -> {
|
||||
if (stateAndDispatch.state.value != StateMachineState.Initial || showDeviceVerifiedScreen) {
|
||||
// The user has verified the session, we need to show the success screen
|
||||
VerifySelfSessionState.Step.Completed
|
||||
OutgoingVerificationState.Step.Completed
|
||||
} else {
|
||||
// Automatic verification, which can happen on freshly created account, in this case, skip the screen
|
||||
VerifySelfSessionState.Step.Exit
|
||||
OutgoingVerificationState.Step.Exit
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,42 +91,44 @@ class VerifySelfSessionPresenter @AssistedInject constructor(
|
||||
observeVerificationService()
|
||||
}
|
||||
|
||||
fun handleEvents(event: VerifySelfSessionViewEvents) {
|
||||
fun handleEvents(event: OutgoingVerificationViewEvents) {
|
||||
Timber.d("Verification user action: ${event::class.simpleName}")
|
||||
when (event) {
|
||||
// Just relay the event to the state machine
|
||||
VerifySelfSessionViewEvents.RequestVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.RequestVerification(verificationRequest))
|
||||
VerifySelfSessionViewEvents.StartSasVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.StartSasVerification)
|
||||
VerifySelfSessionViewEvents.ConfirmVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.AcceptChallenge)
|
||||
VerifySelfSessionViewEvents.DeclineVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.DeclineChallenge)
|
||||
VerifySelfSessionViewEvents.Cancel -> stateAndDispatch.dispatchAction(StateMachineEvent.Cancel)
|
||||
VerifySelfSessionViewEvents.Reset -> stateAndDispatch.dispatchAction(StateMachineEvent.Reset)
|
||||
OutgoingVerificationViewEvents.RequestVerification -> StateMachineEvent.RequestVerification(verificationRequest)
|
||||
OutgoingVerificationViewEvents.StartSasVerification -> StateMachineEvent.StartSasVerification
|
||||
OutgoingVerificationViewEvents.ConfirmVerification -> StateMachineEvent.AcceptChallenge
|
||||
OutgoingVerificationViewEvents.DeclineVerification -> StateMachineEvent.DeclineChallenge
|
||||
OutgoingVerificationViewEvents.Cancel -> StateMachineEvent.Cancel
|
||||
OutgoingVerificationViewEvents.Reset -> StateMachineEvent.Reset
|
||||
}.let { stateMachineEvent ->
|
||||
stateAndDispatch.dispatchAction(stateMachineEvent)
|
||||
}
|
||||
}
|
||||
return VerifySelfSessionState(
|
||||
return OutgoingVerificationState(
|
||||
step = step,
|
||||
request = verificationRequest,
|
||||
eventSink = ::handleEvents,
|
||||
)
|
||||
}
|
||||
|
||||
private fun StateMachineState?.toVerificationStep(): VerifySelfSessionState.Step =
|
||||
private fun StateMachineState?.toVerificationStep(): OutgoingVerificationState.Step =
|
||||
when (val machineState = this) {
|
||||
StateMachineState.Initial, null -> {
|
||||
VerifySelfSessionState.Step.Initial
|
||||
OutgoingVerificationState.Step.Initial
|
||||
}
|
||||
is StateMachineState.RequestingVerification,
|
||||
is StateMachineState.StartingSasVerification,
|
||||
StateMachineState.SasVerificationStarted -> {
|
||||
VerifySelfSessionState.Step.AwaitingOtherDeviceResponse
|
||||
OutgoingVerificationState.Step.AwaitingOtherDeviceResponse
|
||||
}
|
||||
|
||||
StateMachineState.VerificationRequestAccepted -> {
|
||||
VerifySelfSessionState.Step.Ready
|
||||
OutgoingVerificationState.Step.Ready
|
||||
}
|
||||
|
||||
is StateMachineState.Canceled -> {
|
||||
VerifySelfSessionState.Step.Canceled
|
||||
OutgoingVerificationState.Step.Canceled
|
||||
}
|
||||
|
||||
is StateMachineState.Verifying -> {
|
||||
@@ -134,15 +136,15 @@ class VerifySelfSessionPresenter @AssistedInject constructor(
|
||||
is StateMachineState.Verifying.Replying -> AsyncData.Loading()
|
||||
else -> AsyncData.Uninitialized
|
||||
}
|
||||
VerifySelfSessionState.Step.Verifying(machineState.data, async)
|
||||
OutgoingVerificationState.Step.Verifying(machineState.data, async)
|
||||
}
|
||||
|
||||
StateMachineState.Completed -> {
|
||||
VerifySelfSessionState.Step.Completed
|
||||
OutgoingVerificationState.Step.Completed
|
||||
}
|
||||
|
||||
StateMachineState.Exit -> {
|
||||
VerifySelfSessionState.Step.Exit
|
||||
OutgoingVerificationState.Step.Exit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,10 @@ import io.element.android.libraries.matrix.api.verification.SessionVerificationD
|
||||
import io.element.android.libraries.matrix.api.verification.VerificationRequest
|
||||
|
||||
@Immutable
|
||||
data class VerifySelfSessionState(
|
||||
data class OutgoingVerificationState(
|
||||
val step: Step,
|
||||
val request: VerificationRequest.Outgoing,
|
||||
val eventSink: (VerifySelfSessionViewEvents) -> Unit,
|
||||
val eventSink: (OutgoingVerificationViewEvents) -> Unit,
|
||||
) {
|
||||
@Stable
|
||||
sealed interface Step {
|
||||
@@ -29,10 +29,10 @@ import kotlin.time.Duration.Companion.seconds
|
||||
import com.freeletics.flowredux.dsl.State as MachineState
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
class VerifySelfSessionStateMachine(
|
||||
class OutgoingVerificationStateMachine(
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
private val encryptionService: EncryptionService,
|
||||
) : FlowReduxStateMachine<VerifySelfSessionStateMachine.State, VerifySelfSessionStateMachine.Event>(
|
||||
) : FlowReduxStateMachine<OutgoingVerificationStateMachine.State, OutgoingVerificationStateMachine.Event>(
|
||||
initialState = State.Initial,
|
||||
) {
|
||||
init {
|
||||
@@ -8,64 +8,64 @@
|
||||
package io.element.android.features.verifysession.impl.outgoing
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.features.verifysession.impl.outgoing.VerifySelfSessionState.Step
|
||||
import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationState.Step
|
||||
import io.element.android.features.verifysession.impl.ui.aDecimalsSessionVerificationData
|
||||
import io.element.android.features.verifysession.impl.ui.aEmojisSessionVerificationData
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.verification.VerificationRequest
|
||||
|
||||
open class VerifySelfSessionStateProvider : PreviewParameterProvider<VerifySelfSessionState> {
|
||||
override val values: Sequence<VerifySelfSessionState>
|
||||
open class OutgoingVerificationStateProvider : PreviewParameterProvider<OutgoingVerificationState> {
|
||||
override val values: Sequence<OutgoingVerificationState>
|
||||
get() = sequenceOf(
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Initial,
|
||||
request = anOutgoingSessionVerificationRequest(),
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Initial,
|
||||
request = anOutgoingUserVerificationRequest(),
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.AwaitingOtherDeviceResponse,
|
||||
request = anOutgoingSessionVerificationRequest(),
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.AwaitingOtherDeviceResponse,
|
||||
request = anOutgoingUserVerificationRequest(),
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Verifying(aEmojisSessionVerificationData(), AsyncData.Uninitialized),
|
||||
request = anOutgoingSessionVerificationRequest(),
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Verifying(aEmojisSessionVerificationData(), AsyncData.Uninitialized),
|
||||
request = anOutgoingUserVerificationRequest(),
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Verifying(aEmojisSessionVerificationData(), AsyncData.Loading())
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Canceled
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Ready
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Verifying(aDecimalsSessionVerificationData(), AsyncData.Uninitialized)
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Completed,
|
||||
request = anOutgoingSessionVerificationRequest(),
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Completed,
|
||||
request = anOutgoingUserVerificationRequest(),
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Loading
|
||||
),
|
||||
aVerifySelfSessionState(
|
||||
anOutgoingVerificationState(
|
||||
step = Step.Exit
|
||||
),
|
||||
// Add other state here
|
||||
@@ -75,11 +75,11 @@ open class VerifySelfSessionStateProvider : PreviewParameterProvider<VerifySelfS
|
||||
internal fun anOutgoingUserVerificationRequest() = VerificationRequest.Outgoing.User(userId = UserId("@alice:example.com"))
|
||||
internal fun anOutgoingSessionVerificationRequest() = VerificationRequest.Outgoing.CurrentSession
|
||||
|
||||
internal fun aVerifySelfSessionState(
|
||||
internal fun anOutgoingVerificationState(
|
||||
step: Step = Step.Initial,
|
||||
request: VerificationRequest.Outgoing = anOutgoingSessionVerificationRequest(),
|
||||
eventSink: (VerifySelfSessionViewEvents) -> Unit = {},
|
||||
) = VerifySelfSessionState(
|
||||
eventSink: (OutgoingVerificationViewEvents) -> Unit = {},
|
||||
) = OutgoingVerificationState(
|
||||
step = step,
|
||||
request = request,
|
||||
eventSink = eventSink,
|
||||
@@ -27,7 +27,7 @@ import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.compound.tokens.generated.CompoundIcons
|
||||
import io.element.android.features.verifysession.impl.R
|
||||
import io.element.android.features.verifysession.impl.outgoing.VerifySelfSessionState.Step
|
||||
import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationState.Step
|
||||
import io.element.android.features.verifysession.impl.ui.VerificationBottomMenu
|
||||
import io.element.android.features.verifysession.impl.ui.VerificationContentVerifying
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
@@ -49,8 +49,8 @@ import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun VerifySelfSessionView(
|
||||
state: VerifySelfSessionState,
|
||||
fun OutgoingVerificationView(
|
||||
state: OutgoingVerificationState,
|
||||
onLearnMoreClick: () -> Unit,
|
||||
onFinish: () -> Unit,
|
||||
onBack: () -> Unit,
|
||||
@@ -59,12 +59,12 @@ fun VerifySelfSessionView(
|
||||
val step = state.step
|
||||
fun cancelOrResetFlow() {
|
||||
when (step) {
|
||||
is Step.Canceled -> state.eventSink(VerifySelfSessionViewEvents.Reset)
|
||||
is Step.Canceled -> state.eventSink(OutgoingVerificationViewEvents.Reset)
|
||||
Step.Initial, Step.Completed -> onBack()
|
||||
Step.Ready, is Step.AwaitingOtherDeviceResponse -> state.eventSink(VerifySelfSessionViewEvents.Cancel)
|
||||
Step.Ready, is Step.AwaitingOtherDeviceResponse -> state.eventSink(OutgoingVerificationViewEvents.Cancel)
|
||||
is Step.Verifying -> {
|
||||
if (!step.state.isLoading()) {
|
||||
state.eventSink(VerifySelfSessionViewEvents.DeclineVerification)
|
||||
state.eventSink(OutgoingVerificationViewEvents.DeclineVerification)
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
@@ -98,10 +98,10 @@ fun VerifySelfSessionView(
|
||||
)
|
||||
},
|
||||
header = {
|
||||
VerifySelfSessionHeader(step = step, request = state.request)
|
||||
OutgoingVerificationHeader(step = step, request = state.request)
|
||||
},
|
||||
footer = {
|
||||
VerifySelfSessionBottomMenu(
|
||||
OutgoingVerificationViewBottomMenu(
|
||||
screenState = state,
|
||||
onCancelClick = ::cancelOrResetFlow,
|
||||
onContinueClick = onFinish,
|
||||
@@ -109,7 +109,7 @@ fun VerifySelfSessionView(
|
||||
},
|
||||
isScrollable = true,
|
||||
) {
|
||||
VerifySelfSessionContent(
|
||||
OutgoingVerificationContent(
|
||||
flowState = step,
|
||||
request = state.request,
|
||||
onLearnMoreClick = onLearnMoreClick,
|
||||
@@ -119,7 +119,7 @@ fun VerifySelfSessionView(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun VerifySelfSessionHeader(step: Step, request: VerificationRequest.Outgoing) {
|
||||
private fun OutgoingVerificationHeader(step: Step, request: VerificationRequest.Outgoing) {
|
||||
val iconStyle = when (step) {
|
||||
Step.Loading -> error("Should not happen")
|
||||
Step.Initial -> when (request) {
|
||||
@@ -189,7 +189,7 @@ private fun VerifySelfSessionHeader(step: Step, request: VerificationRequest.Out
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun VerifySelfSessionContent(
|
||||
private fun OutgoingVerificationContent(
|
||||
flowState: Step,
|
||||
request: VerificationRequest.Outgoing,
|
||||
onLearnMoreClick: () -> Unit,
|
||||
@@ -227,8 +227,8 @@ private fun ContentInitial(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun VerifySelfSessionBottomMenu(
|
||||
screenState: VerifySelfSessionState,
|
||||
private fun OutgoingVerificationViewBottomMenu(
|
||||
screenState: OutgoingVerificationState,
|
||||
onCancelClick: () -> Unit,
|
||||
onContinueClick: () -> Unit,
|
||||
) {
|
||||
@@ -244,7 +244,7 @@ private fun VerifySelfSessionBottomMenu(
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(CommonStrings.action_start_verification),
|
||||
onClick = { eventSink(VerifySelfSessionViewEvents.RequestVerification) },
|
||||
onClick = { eventSink(OutgoingVerificationViewEvents.RequestVerification) },
|
||||
)
|
||||
InvisibleButton()
|
||||
}
|
||||
@@ -264,7 +264,7 @@ private fun VerifySelfSessionBottomMenu(
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(CommonStrings.action_start),
|
||||
onClick = { eventSink(VerifySelfSessionViewEvents.StartSasVerification) },
|
||||
onClick = { eventSink(OutgoingVerificationViewEvents.StartSasVerification) },
|
||||
)
|
||||
TextButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@@ -287,14 +287,14 @@ private fun VerifySelfSessionBottomMenu(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(R.string.screen_session_verification_they_match),
|
||||
onClick = {
|
||||
eventSink(VerifySelfSessionViewEvents.ConfirmVerification)
|
||||
eventSink(OutgoingVerificationViewEvents.ConfirmVerification)
|
||||
},
|
||||
)
|
||||
|
||||
TextButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(R.string.screen_session_verification_they_dont_match),
|
||||
onClick = { eventSink(VerifySelfSessionViewEvents.DeclineVerification) },
|
||||
onClick = { eventSink(OutgoingVerificationViewEvents.DeclineVerification) },
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -315,8 +315,8 @@ private fun VerifySelfSessionBottomMenu(
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun VerifySelfSessionViewPreview(@PreviewParameter(VerifySelfSessionStateProvider::class) state: VerifySelfSessionState) = ElementPreview {
|
||||
VerifySelfSessionView(
|
||||
internal fun OutgoingVerificationViewPreview(@PreviewParameter(OutgoingVerificationStateProvider::class) state: OutgoingVerificationState) = ElementPreview {
|
||||
OutgoingVerificationView(
|
||||
state = state,
|
||||
onLearnMoreClick = {},
|
||||
onFinish = {},
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2023, 2024 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.verifysession.impl.outgoing
|
||||
|
||||
sealed interface OutgoingVerificationViewEvents {
|
||||
data object RequestVerification : OutgoingVerificationViewEvents
|
||||
data object StartSasVerification : OutgoingVerificationViewEvents
|
||||
data object ConfirmVerification : OutgoingVerificationViewEvents
|
||||
data object DeclineVerification : OutgoingVerificationViewEvents
|
||||
data object Cancel : OutgoingVerificationViewEvents
|
||||
data object Reset : OutgoingVerificationViewEvents
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023, 2024 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.verifysession.impl.outgoing
|
||||
|
||||
sealed interface VerifySelfSessionViewEvents {
|
||||
data object RequestVerification : VerifySelfSessionViewEvents
|
||||
data object StartSasVerification : VerifySelfSessionViewEvents
|
||||
data object ConfirmVerification : VerifySelfSessionViewEvents
|
||||
data object DeclineVerification : VerifySelfSessionViewEvents
|
||||
data object Cancel : VerifySelfSessionViewEvents
|
||||
data object Reset : VerifySelfSessionViewEvents
|
||||
}
|
||||
@@ -9,7 +9,7 @@ package io.element.android.features.verifysession.impl.outgoing
|
||||
|
||||
import app.cash.turbine.ReceiveTurbine
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.verifysession.impl.outgoing.VerifySelfSessionState.Step
|
||||
import io.element.android.features.verifysession.impl.outgoing.OutgoingVerificationState.Step
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.encryption.EncryptionService
|
||||
@@ -31,13 +31,13 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
class VerifySelfSessionPresenterTest {
|
||||
class OutgoingVerificationPresenterTest {
|
||||
@get:Rule
|
||||
val warmUpRule = WarmUpRule()
|
||||
|
||||
@Test
|
||||
fun `present - Initial state is received`() = runTest {
|
||||
val presenter = createVerifySelfSessionPresenter(
|
||||
val presenter = createOutgoingVerificationPresenter(
|
||||
service = unverifiedSessionService(),
|
||||
)
|
||||
presenter.test {
|
||||
@@ -55,7 +55,7 @@ class VerifySelfSessionPresenterTest {
|
||||
requestSessionVerificationLambda = requestSessionVerificationRecorder,
|
||||
startVerificationLambda = startVerificationRecorder,
|
||||
)
|
||||
val presenter = createVerifySelfSessionPresenter(
|
||||
val presenter = createOutgoingVerificationPresenter(
|
||||
service = service,
|
||||
verificationRequest = anOutgoingSessionVerificationRequest(),
|
||||
)
|
||||
@@ -75,7 +75,7 @@ class VerifySelfSessionPresenterTest {
|
||||
requestUserVerificationLambda = requestUserVerificationRecorder,
|
||||
startVerificationLambda = startVerificationRecorder,
|
||||
)
|
||||
val presenter = createVerifySelfSessionPresenter(
|
||||
val presenter = createOutgoingVerificationPresenter(
|
||||
service = service,
|
||||
verificationRequest = anOutgoingUserVerificationRequest(),
|
||||
)
|
||||
@@ -89,14 +89,14 @@ class VerifySelfSessionPresenterTest {
|
||||
|
||||
@Test
|
||||
fun `present - Cancellation on initial state moves to Exit state`() = runTest {
|
||||
val presenter = createVerifySelfSessionPresenter(
|
||||
val presenter = createOutgoingVerificationPresenter(
|
||||
service = unverifiedSessionService(),
|
||||
)
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.step).isEqualTo(Step.Initial)
|
||||
val eventSink = initialState.eventSink
|
||||
eventSink(VerifySelfSessionViewEvents.Cancel)
|
||||
eventSink(OutgoingVerificationViewEvents.Cancel)
|
||||
|
||||
assertThat(awaitItem().step).isEqualTo(Step.Exit)
|
||||
}
|
||||
@@ -109,10 +109,10 @@ class VerifySelfSessionPresenterTest {
|
||||
startVerificationLambda = { },
|
||||
approveVerificationLambda = { },
|
||||
)
|
||||
val presenter = createVerifySelfSessionPresenter(service)
|
||||
val presenter = createOutgoingVerificationPresenter(service)
|
||||
presenter.test {
|
||||
val state = requestVerificationAndAwaitVerifyingState(service)
|
||||
state.eventSink(VerifySelfSessionViewEvents.ConfirmVerification)
|
||||
state.eventSink(OutgoingVerificationViewEvents.ConfirmVerification)
|
||||
// Cancelling
|
||||
assertThat(awaitItem().step).isInstanceOf(Step.Verifying::class.java)
|
||||
service.emitVerificationFlowState(VerificationFlowState.DidFail)
|
||||
@@ -126,9 +126,9 @@ class VerifySelfSessionPresenterTest {
|
||||
val service = unverifiedSessionService(
|
||||
requestSessionVerificationLambda = { },
|
||||
)
|
||||
val presenter = createVerifySelfSessionPresenter(service)
|
||||
val presenter = createOutgoingVerificationPresenter(service)
|
||||
presenter.test {
|
||||
awaitItem().eventSink(VerifySelfSessionViewEvents.RequestVerification)
|
||||
awaitItem().eventSink(OutgoingVerificationViewEvents.RequestVerification)
|
||||
service.emitVerificationFlowState(VerificationFlowState.DidFail)
|
||||
assertThat(awaitItem().step).isInstanceOf(Step.AwaitingOtherDeviceResponse::class.java)
|
||||
assertThat(awaitItem().step).isEqualTo(Step.Canceled)
|
||||
@@ -142,10 +142,10 @@ class VerifySelfSessionPresenterTest {
|
||||
startVerificationLambda = { },
|
||||
cancelVerificationLambda = { },
|
||||
)
|
||||
val presenter = createVerifySelfSessionPresenter(service)
|
||||
val presenter = createOutgoingVerificationPresenter(service)
|
||||
presenter.test {
|
||||
val state = requestVerificationAndAwaitVerifyingState(service)
|
||||
state.eventSink(VerifySelfSessionViewEvents.Cancel)
|
||||
state.eventSink(OutgoingVerificationViewEvents.Cancel)
|
||||
assertThat(awaitItem().step).isEqualTo(Step.Canceled)
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,7 @@ class VerifySelfSessionPresenterTest {
|
||||
requestSessionVerificationLambda = { },
|
||||
startVerificationLambda = { },
|
||||
)
|
||||
val presenter = createVerifySelfSessionPresenter(service)
|
||||
val presenter = createOutgoingVerificationPresenter(service)
|
||||
presenter.test {
|
||||
requestVerificationAndAwaitVerifyingState(service)
|
||||
service.emitVerificationFlowState(VerificationFlowState.DidReceiveVerificationData(SessionVerificationData.Emojis(emptyList())))
|
||||
@@ -170,12 +170,12 @@ class VerifySelfSessionPresenterTest {
|
||||
requestSessionVerificationLambda = { },
|
||||
startVerificationLambda = { },
|
||||
)
|
||||
val presenter = createVerifySelfSessionPresenter(service)
|
||||
val presenter = createOutgoingVerificationPresenter(service)
|
||||
presenter.test {
|
||||
val state = requestVerificationAndAwaitVerifyingState(service)
|
||||
service.emitVerificationFlowState(VerificationFlowState.DidCancel)
|
||||
assertThat(awaitItem().step).isEqualTo(Step.Canceled)
|
||||
state.eventSink(VerifySelfSessionViewEvents.Reset)
|
||||
state.eventSink(OutgoingVerificationViewEvents.Reset)
|
||||
// Went back to initial state
|
||||
assertThat(awaitItem().step).isEqualTo(Step.Initial)
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
@@ -192,13 +192,13 @@ class VerifySelfSessionPresenterTest {
|
||||
startVerificationLambda = { },
|
||||
approveVerificationLambda = { },
|
||||
)
|
||||
val presenter = createVerifySelfSessionPresenter(service)
|
||||
val presenter = createOutgoingVerificationPresenter(service)
|
||||
presenter.test {
|
||||
val state = requestVerificationAndAwaitVerifyingState(
|
||||
service,
|
||||
SessionVerificationData.Emojis(emojis)
|
||||
)
|
||||
state.eventSink(VerifySelfSessionViewEvents.ConfirmVerification)
|
||||
state.eventSink(OutgoingVerificationViewEvents.ConfirmVerification)
|
||||
assertThat(awaitItem().step).isEqualTo(
|
||||
Step.Verifying(
|
||||
SessionVerificationData.Emojis(emojis),
|
||||
@@ -217,10 +217,10 @@ class VerifySelfSessionPresenterTest {
|
||||
startVerificationLambda = { },
|
||||
declineVerificationLambda = { },
|
||||
)
|
||||
val presenter = createVerifySelfSessionPresenter(service)
|
||||
val presenter = createOutgoingVerificationPresenter(service)
|
||||
presenter.test {
|
||||
val state = requestVerificationAndAwaitVerifyingState(service)
|
||||
state.eventSink(VerifySelfSessionViewEvents.DeclineVerification)
|
||||
state.eventSink(OutgoingVerificationViewEvents.DeclineVerification)
|
||||
assertThat(awaitItem().step).isEqualTo(
|
||||
Step.Verifying(
|
||||
SessionVerificationData.Emojis(emptyList()),
|
||||
@@ -241,7 +241,7 @@ class VerifySelfSessionPresenterTest {
|
||||
emitVerifiedStatus(SessionVerifiedStatus.Verified)
|
||||
emitVerificationFlowState(VerificationFlowState.DidFinish)
|
||||
}
|
||||
val presenter = createVerifySelfSessionPresenter(
|
||||
val presenter = createOutgoingVerificationPresenter(
|
||||
service = service,
|
||||
showDeviceVerifiedScreen = true,
|
||||
)
|
||||
@@ -259,7 +259,7 @@ class VerifySelfSessionPresenterTest {
|
||||
emitVerifiedStatus(SessionVerifiedStatus.Verified)
|
||||
emitVerificationFlowState(VerificationFlowState.DidFinish)
|
||||
}
|
||||
val presenter = createVerifySelfSessionPresenter(
|
||||
val presenter = createOutgoingVerificationPresenter(
|
||||
service = service,
|
||||
showDeviceVerifiedScreen = false,
|
||||
)
|
||||
@@ -269,13 +269,13 @@ class VerifySelfSessionPresenterTest {
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun ReceiveTurbine<VerifySelfSessionState>.requestVerificationAndAwaitVerifyingState(
|
||||
private suspend fun ReceiveTurbine<OutgoingVerificationState>.requestVerificationAndAwaitVerifyingState(
|
||||
fakeService: FakeSessionVerificationService,
|
||||
sessionVerificationData: SessionVerificationData = SessionVerificationData.Emojis(emptyList()),
|
||||
): VerifySelfSessionState {
|
||||
): OutgoingVerificationState {
|
||||
var state = awaitItem()
|
||||
assertThat(state.step).isEqualTo(Step.Initial)
|
||||
state.eventSink(VerifySelfSessionViewEvents.RequestVerification)
|
||||
state.eventSink(OutgoingVerificationViewEvents.RequestVerification)
|
||||
// Await for other device response:
|
||||
fakeService.emitVerificationFlowState(VerificationFlowState.DidAcceptVerificationRequest)
|
||||
state = awaitItem()
|
||||
@@ -283,7 +283,7 @@ class VerifySelfSessionPresenterTest {
|
||||
// Await for the state to be Ready
|
||||
state = awaitItem()
|
||||
assertThat(state.step).isEqualTo(Step.Ready)
|
||||
state.eventSink(VerifySelfSessionViewEvents.StartSasVerification)
|
||||
state.eventSink(OutgoingVerificationViewEvents.StartSasVerification)
|
||||
// Await for other device response (again):
|
||||
fakeService.emitVerificationFlowState(VerificationFlowState.DidStartSasVerification)
|
||||
state = awaitItem()
|
||||
@@ -321,13 +321,13 @@ class VerifySelfSessionPresenterTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createVerifySelfSessionPresenter(
|
||||
private fun createOutgoingVerificationPresenter(
|
||||
service: SessionVerificationService,
|
||||
verificationRequest: VerificationRequest.Outgoing = anOutgoingSessionVerificationRequest(),
|
||||
encryptionService: EncryptionService = FakeEncryptionService(),
|
||||
showDeviceVerifiedScreen: Boolean = false,
|
||||
): VerifySelfSessionPresenter {
|
||||
return VerifySelfSessionPresenter(
|
||||
): OutgoingVerificationPresenter {
|
||||
return OutgoingVerificationPresenter(
|
||||
showDeviceVerifiedScreen = showDeviceVerifiedScreen,
|
||||
verificationRequest = verificationRequest,
|
||||
sessionVerificationService = service,
|
||||
@@ -26,54 +26,54 @@ import org.junit.rules.TestRule
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class VerifySelfSessionViewTest {
|
||||
class OutgoingVerificationViewTest {
|
||||
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when canceled resets the flow`() {
|
||||
val eventsRecorder = EventsRecorder<VerifySelfSessionViewEvents>()
|
||||
rule.setVerifySelfSessionView(
|
||||
aVerifySelfSessionState(
|
||||
step = VerifySelfSessionState.Step.Canceled,
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Canceled,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
eventsRecorder.assertSingle(VerifySelfSessionViewEvents.Reset)
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.Reset)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when awaiting response cancels the verification`() {
|
||||
val eventsRecorder = EventsRecorder<VerifySelfSessionViewEvents>()
|
||||
rule.setVerifySelfSessionView(
|
||||
aVerifySelfSessionState(
|
||||
step = VerifySelfSessionState.Step.AwaitingOtherDeviceResponse,
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.AwaitingOtherDeviceResponse,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
eventsRecorder.assertSingle(VerifySelfSessionViewEvents.Cancel)
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.Cancel)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when ready to verify cancels the verification`() {
|
||||
val eventsRecorder = EventsRecorder<VerifySelfSessionViewEvents>()
|
||||
rule.setVerifySelfSessionView(
|
||||
aVerifySelfSessionState(
|
||||
step = VerifySelfSessionState.Step.Ready,
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Ready,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
eventsRecorder.assertSingle(VerifySelfSessionViewEvents.Cancel)
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.Cancel)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when verifying and not loading declines the verification`() {
|
||||
val eventsRecorder = EventsRecorder<VerifySelfSessionViewEvents>()
|
||||
rule.setVerifySelfSessionView(
|
||||
aVerifySelfSessionState(
|
||||
step = VerifySelfSessionState.Step.Verifying(
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
state = AsyncData.Uninitialized,
|
||||
),
|
||||
@@ -81,15 +81,15 @@ class VerifySelfSessionViewTest {
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
eventsRecorder.assertSingle(VerifySelfSessionViewEvents.DeclineVerification)
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.DeclineVerification)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `back key pressed - when verifying and loading does nothing`() {
|
||||
val eventsRecorder = EventsRecorder<VerifySelfSessionViewEvents>()
|
||||
rule.setVerifySelfSessionView(
|
||||
aVerifySelfSessionState(
|
||||
step = VerifySelfSessionState.Step.Verifying(
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
state = AsyncData.Loading(),
|
||||
),
|
||||
@@ -103,10 +103,10 @@ class VerifySelfSessionViewTest {
|
||||
@Test
|
||||
fun `back key pressed - on Completed exits the flow`() {
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setVerifySelfSessionView(
|
||||
rule.setOutgoingVerificationView(
|
||||
onBack = callback,
|
||||
state = aVerifySelfSessionState(
|
||||
step = VerifySelfSessionState.Step.Completed,
|
||||
state = anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Completed,
|
||||
),
|
||||
)
|
||||
rule.pressBackKey()
|
||||
@@ -115,11 +115,11 @@ class VerifySelfSessionViewTest {
|
||||
|
||||
@Test
|
||||
fun `when flow is completed and the user clicks on the continue button, the expected callback is invoked`() {
|
||||
val eventsRecorder = EventsRecorder<VerifySelfSessionViewEvents>(expectEvents = false)
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>(expectEvents = false)
|
||||
ensureCalledOnce { callback ->
|
||||
rule.setVerifySelfSessionView(
|
||||
aVerifySelfSessionState(
|
||||
step = VerifySelfSessionState.Step.Completed,
|
||||
rule.setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Completed,
|
||||
eventSink = eventsRecorder
|
||||
),
|
||||
onFinished = callback,
|
||||
@@ -130,10 +130,10 @@ class VerifySelfSessionViewTest {
|
||||
|
||||
@Test
|
||||
fun `clicking on they match emits the expected event`() {
|
||||
val eventsRecorder = EventsRecorder<VerifySelfSessionViewEvents>()
|
||||
rule.setVerifySelfSessionView(
|
||||
aVerifySelfSessionState(
|
||||
step = VerifySelfSessionState.Step.Verifying(
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
state = AsyncData.Uninitialized,
|
||||
),
|
||||
@@ -141,15 +141,15 @@ class VerifySelfSessionViewTest {
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_session_verification_they_match)
|
||||
eventsRecorder.assertSingle(VerifySelfSessionViewEvents.ConfirmVerification)
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.ConfirmVerification)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking on they do not match emits the expected event`() {
|
||||
val eventsRecorder = EventsRecorder<VerifySelfSessionViewEvents>()
|
||||
rule.setVerifySelfSessionView(
|
||||
aVerifySelfSessionState(
|
||||
step = VerifySelfSessionState.Step.Verifying(
|
||||
val eventsRecorder = EventsRecorder<OutgoingVerificationViewEvents>()
|
||||
rule.setOutgoingVerificationView(
|
||||
anOutgoingVerificationState(
|
||||
step = OutgoingVerificationState.Step.Verifying(
|
||||
data = aEmojisSessionVerificationData(),
|
||||
state = AsyncData.Uninitialized,
|
||||
),
|
||||
@@ -157,17 +157,17 @@ class VerifySelfSessionViewTest {
|
||||
),
|
||||
)
|
||||
rule.clickOn(R.string.screen_session_verification_they_dont_match)
|
||||
eventsRecorder.assertSingle(VerifySelfSessionViewEvents.DeclineVerification)
|
||||
eventsRecorder.assertSingle(OutgoingVerificationViewEvents.DeclineVerification)
|
||||
}
|
||||
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setVerifySelfSessionView(
|
||||
state: VerifySelfSessionState,
|
||||
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setOutgoingVerificationView(
|
||||
state: OutgoingVerificationState,
|
||||
onLearnMoreClick: () -> Unit = EnsureNeverCalled(),
|
||||
onFinished: () -> Unit = EnsureNeverCalled(),
|
||||
onBack: () -> Unit = EnsureNeverCalled(),
|
||||
) {
|
||||
setContent {
|
||||
VerifySelfSessionView(
|
||||
OutgoingVerificationView(
|
||||
state = state,
|
||||
onLearnMoreClick = onLearnMoreClick,
|
||||
onFinish = onFinished,
|
||||
@@ -16,8 +16,6 @@ import androidx.core.text.util.LinkifyCompat
|
||||
import timber.log.Timber
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.isNotEmpty
|
||||
import kotlin.collections.iterator
|
||||
|
||||
/**
|
||||
* Helper class to linkify text while preserving existing URL spans.
|
||||
|
||||
@@ -27,8 +27,6 @@ import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.iterator
|
||||
import kotlin.collections.orEmpty
|
||||
|
||||
@ContributesMultibinding(AppScope::class)
|
||||
class SentryAnalyticsProvider @Inject constructor(
|
||||
|
||||
Reference in New Issue
Block a user