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