Add user verification and verification state violation badges (#4392)
* Move `observeRoomMemberIdentityStateChange` and associated classes to `libs:matrixui` module so they can be reused * Add `EncryptionService.getUserIdentity` method to retrieve not only if the user is verified or not, but in which state they are * Fix `IdentityChangePresenter` after the previous changes * Fix `withFakeLifecycleOwner` and add `testWithLifecycleOwner` helper * Display verified badge in DM top app bar when possible * Display a verification violation warning icon next to the 'People' item in room details screen * Display either a verified badge or a verification violation warning icon next to the room members in the room member list screen * Display either a verified badge or a verification violation warning and withdraw verification button in the room member profile. Generic user profiles won't display verification state anymore since we can't easily track changes in it. * Add preview for room member details screen with verification violation identity state * Add verified and violation badge to the `Profile` list item in room details screen * Update screenshots --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
parent
b0e6b50c79
commit
fd50ce4daf
75 changed files with 889 additions and 364 deletions
|
|
@ -9,31 +9,64 @@ package io.element.android.tests.testutils
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.InternalComposeApi
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.currentComposer
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LifecycleRegistry
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.TurbineTestContext
|
||||
import app.cash.turbine.test
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
|
||||
/**
|
||||
* Composable that provides a fake [LifecycleOwner] to the composition.
|
||||
*
|
||||
* **WARNING: DO NOT USE OUTSIDE TESTS.**
|
||||
*/
|
||||
@OptIn(InternalComposeApi::class)
|
||||
@Stable
|
||||
@Composable
|
||||
fun <T> withFakeLifecycleOwner(lifecycleOwner: FakeLifecycleOwner = FakeLifecycleOwner(), block: @Composable () -> T): T {
|
||||
var state: T? by remember { mutableStateOf(null) }
|
||||
CompositionLocalProvider(LocalLifecycleOwner provides lifecycleOwner) {
|
||||
state = block()
|
||||
}
|
||||
return state!!
|
||||
fun <T> withFakeLifecycleOwner(
|
||||
lifecycleOwner: FakeLifecycleOwner = FakeLifecycleOwner(),
|
||||
block: @Composable () -> T
|
||||
): T {
|
||||
currentComposer.startProvider(LocalLifecycleOwner provides lifecycleOwner)
|
||||
val state = block()
|
||||
currentComposer.endProvider()
|
||||
return state
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a [Presenter] with a fake [LifecycleOwner].
|
||||
*
|
||||
* **WARNING: DO NOT USE OUTSIDE TESTS.**
|
||||
*/
|
||||
suspend fun <T> Presenter<T>.testWithLifecycleOwner(
|
||||
lifecycleOwner: FakeLifecycleOwner = FakeLifecycleOwner(),
|
||||
block: suspend TurbineTestContext<T>.() -> Unit
|
||||
) {
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
val ret = withFakeLifecycleOwner(lifecycleOwner) {
|
||||
present()
|
||||
}
|
||||
ret
|
||||
}.test<T>(validate = block)
|
||||
}
|
||||
|
||||
@SuppressLint("VisibleForTests")
|
||||
class FakeLifecycleOwner : LifecycleOwner {
|
||||
class FakeLifecycleOwner(initialState: Lifecycle.State? = null) : LifecycleOwner {
|
||||
override val lifecycle: Lifecycle = LifecycleRegistry.createUnsafe(this)
|
||||
|
||||
init {
|
||||
initialState?.let { givenState(it) }
|
||||
}
|
||||
|
||||
fun givenState(state: Lifecycle.State) {
|
||||
(lifecycle as LifecycleRegistry).currentState = state
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue