Merge branch 'develop' into feature/fga/sending_queue_iteration

This commit is contained in:
ganfra 2024-06-19 13:54:24 +02:00 committed by GitHub
commit e93a41a5b5
31 changed files with 161 additions and 86 deletions

View file

@ -11,7 +11,7 @@ jobs:
- run: | - run: |
npm install --save-dev @babel/plugin-transform-flow-strip-types npm install --save-dev @babel/plugin-transform-flow-strip-types
- name: Danger - name: Danger
uses: danger/danger-js@12.3.1 uses: danger/danger-js@12.3.2
with: with:
args: "--dangerfile ./tools/danger/dangerfile.js" args: "--dangerfile ./tools/danger/dangerfile.js"
env: env:

View file

@ -245,7 +245,7 @@ jobs:
yarn add danger-plugin-lint-report --dev yarn add danger-plugin-lint-report --dev
- name: Danger lint - name: Danger lint
if: always() if: always()
uses: danger/danger-js@12.3.1 uses: danger/danger-js@12.3.2
with: with:
args: "--dangerfile ./tools/danger/dangerfile-lint.js" args: "--dangerfile ./tools/danger/dangerfile-lint.js"
env: env:

View file

@ -74,7 +74,7 @@ class MatrixClientsHolder @Inject constructor(private val authenticationService:
// Not ideal but should only happens in case of process recreation. This ensure we restore all the active sessions before restoring the node graphs. // Not ideal but should only happens in case of process recreation. This ensure we restore all the active sessions before restoring the node graphs.
runBlocking { runBlocking {
sessionIds.forEach { sessionId -> sessionIds.forEach { sessionId ->
restore(sessionId) getOrRestore(sessionId)
} }
} }
} }

View file

@ -40,7 +40,7 @@ class MatrixClientsHolderTest {
fakeAuthenticationService.givenMatrixClient(fakeMatrixClient) fakeAuthenticationService.givenMatrixClient(fakeMatrixClient)
assertThat(matrixClientsHolder.getOrNull(A_SESSION_ID)).isNull() assertThat(matrixClientsHolder.getOrNull(A_SESSION_ID)).isNull()
assertThat(matrixClientsHolder.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixClientsHolder.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient)
// Do it again to it the cache // Do it again to hit the cache
assertThat(matrixClientsHolder.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient) assertThat(matrixClientsHolder.getOrRestore(A_SESSION_ID).getOrNull()).isEqualTo(fakeMatrixClient)
assertThat(matrixClientsHolder.getOrNull(A_SESSION_ID)).isEqualTo(fakeMatrixClient) assertThat(matrixClientsHolder.getOrNull(A_SESSION_ID)).isEqualTo(fakeMatrixClient)
} }

View file

@ -17,16 +17,22 @@
package io.element.android.features.login.impl.changeserver package io.element.android.features.login.impl.changeserver
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.login.impl.error.ChangeServerError
import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.ui.strings.CommonStrings
open class ChangeServerStateProvider : PreviewParameterProvider<ChangeServerState> { open class ChangeServerStateProvider : PreviewParameterProvider<ChangeServerState> {
override val values: Sequence<ChangeServerState> override val values: Sequence<ChangeServerState>
get() = sequenceOf( get() = sequenceOf(
aChangeServerState(), aChangeServerState(),
aChangeServerState(changeServerAction = AsyncData.Failure(ChangeServerError.Error(CommonStrings.error_unknown))),
aChangeServerState(changeServerAction = AsyncData.Failure(ChangeServerError.SlidingSyncAlert)),
) )
} }
fun aChangeServerState() = ChangeServerState( fun aChangeServerState(
changeServerAction = AsyncData.Uninitialized, changeServerAction: AsyncData<Unit> = AsyncData.Uninitialized,
) = ChangeServerState(
changeServerAction = changeServerAction,
eventSink = {} eventSink = {}
) )

View file

@ -55,6 +55,7 @@ fun SecureBackupEnterRecoveryKeyView(
FlowStepPage( FlowStepPage(
modifier = modifier, modifier = modifier,
isScrollable = true,
onBackClick = onBackClick, onBackClick = onBackClick,
iconStyle = BigIcon.Style.Default(CompoundIcons.KeySolid()), iconStyle = BigIcon.Style.Default(CompoundIcons.KeySolid()),
title = stringResource(id = R.string.screen_recovery_key_confirm_title), title = stringResource(id = R.string.screen_recovery_key_confirm_title),
@ -70,7 +71,7 @@ private fun Content(
state: SecureBackupEnterRecoveryKeyState, state: SecureBackupEnterRecoveryKeyState,
) { ) {
RecoveryKeyView( RecoveryKeyView(
modifier = Modifier.padding(top = 52.dp), modifier = Modifier.padding(top = 52.dp, bottom = 32.dp),
state = state.recoveryKeyViewState, state = state.recoveryKeyViewState,
onClick = null, onClick = null,
onChange = { onChange = {

View file

@ -19,8 +19,12 @@ package io.element.android.features.securebackup.impl.enter
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performImeAction
import androidx.compose.ui.test.performTextInput
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import io.element.android.features.securebackup.impl.R import io.element.android.features.securebackup.impl.R
import io.element.android.features.securebackup.impl.setup.views.aFormattedRecoveryKey
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.tests.testutils.EnsureNeverCalled import io.element.android.tests.testutils.EnsureNeverCalled
@ -33,6 +37,7 @@ import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TestRule import org.junit.rules.TestRule
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.robolectric.annotation.Config
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class SecureBackupEnterRecoveryKeyViewTest { class SecureBackupEnterRecoveryKeyViewTest {
@ -61,6 +66,7 @@ class SecureBackupEnterRecoveryKeyViewTest {
} }
@Test @Test
@Config(qualifiers = "h1024dp")
fun `tapping on Continue when key is valid - calls expected action`() { fun `tapping on Continue when key is valid - calls expected action`() {
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>() val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
rule.setSecureBackupEnterRecoveryKeyView( rule.setSecureBackupEnterRecoveryKeyView(
@ -72,6 +78,31 @@ class SecureBackupEnterRecoveryKeyViewTest {
} }
@Test @Test
fun `entering a char emits the expected event`() {
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
val keyValue = aFormattedRecoveryKey()
rule.setSecureBackupEnterRecoveryKeyView(
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
)
rule.onNodeWithText(keyValue).performTextInput("X")
recorder.assertSingle(
SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange("X$keyValue")
)
}
@Test
fun `validating from keyboard emits the expected event`() {
val recorder = EventsRecorder<SecureBackupEnterRecoveryKeyEvents>()
val keyValue = aFormattedRecoveryKey()
rule.setSecureBackupEnterRecoveryKeyView(
aSecureBackupEnterRecoveryKeyState(isSubmitEnabled = true, eventSink = recorder),
)
rule.onNodeWithText(keyValue).performImeAction()
recorder.assertSingle(SecureBackupEnterRecoveryKeyEvents.Submit)
}
@Test
@Config(qualifiers = "h1024dp")
fun `tapping on Lost your recovery key - calls onCreateNewRecoveryKey`() { fun `tapping on Lost your recovery key - calls onCreateNewRecoveryKey`() {
ensureCalledOnce { callback -> ensureCalledOnce { callback ->
rule.setSecureBackupEnterRecoveryKeyView( rule.setSecureBackupEnterRecoveryKeyView(
@ -98,7 +129,7 @@ class SecureBackupEnterRecoveryKeyViewTest {
onBackClick: () -> Unit = EnsureNeverCalled(), onBackClick: () -> Unit = EnsureNeverCalled(),
onCreateNewRecoveryKey: () -> Unit = EnsureNeverCalled(), onCreateNewRecoveryKey: () -> Unit = EnsureNeverCalled(),
) { ) {
rule.setContent { setContent {
SecureBackupEnterRecoveryKeyView( SecureBackupEnterRecoveryKeyView(
state = state, state = state,
onSuccess = onDone, onSuccess = onDone,

View file

@ -218,7 +218,7 @@ class VerifySelfSessionViewTest {
onEnterRecoveryKey: () -> Unit = EnsureNeverCalled(), onEnterRecoveryKey: () -> Unit = EnsureNeverCalled(),
onFinished: () -> Unit = EnsureNeverCalled(), onFinished: () -> Unit = EnsureNeverCalled(),
) { ) {
rule.setContent { setContent {
VerifySelfSessionView( VerifySelfSessionView(
state = state, state = state,
onEnterRecoveryKey = onEnterRecoveryKey, onEnterRecoveryKey = onEnterRecoveryKey,

View file

@ -52,6 +52,7 @@ fun FlowStepPage(
iconStyle: BigIcon.Style, iconStyle: BigIcon.Style,
title: String, title: String,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
isScrollable: Boolean = false,
onBackClick: (() -> Unit)? = null, onBackClick: (() -> Unit)? = null,
subTitle: String? = null, subTitle: String? = null,
buttons: @Composable ColumnScope.() -> Unit = {}, buttons: @Composable ColumnScope.() -> Unit = {},
@ -62,6 +63,7 @@ fun FlowStepPage(
} }
HeaderFooterPage( HeaderFooterPage(
modifier = modifier, modifier = modifier,
isScrollable = isScrollable,
topBar = { topBar = {
TopAppBar( TopAppBar(
navigationIcon = { navigationIcon = {

View file

@ -22,7 +22,9 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -39,6 +41,7 @@ import io.element.android.libraries.designsystem.theme.components.Text
* @param modifier Classical modifier. * @param modifier Classical modifier.
* @param paddingValues padding values to apply to the content. * @param paddingValues padding values to apply to the content.
* @param containerColor color of the container. Set to [Color.Transparent] if you provide a background in the [modifier]. * @param containerColor color of the container. Set to [Color.Transparent] if you provide a background in the [modifier].
* @param isScrollable if the whole content should be scrollable.
* @param background optional background component. * @param background optional background component.
* @param topBar optional topBar. * @param topBar optional topBar.
* @param header optional header. * @param header optional header.
@ -50,6 +53,7 @@ fun HeaderFooterPage(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
paddingValues: PaddingValues = PaddingValues(20.dp), paddingValues: PaddingValues = PaddingValues(20.dp),
containerColor: Color = MaterialTheme.colorScheme.background, containerColor: Color = MaterialTheme.colorScheme.background,
isScrollable: Boolean = false,
background: @Composable () -> Unit = {}, background: @Composable () -> Unit = {},
topBar: @Composable () -> Unit = {}, topBar: @Composable () -> Unit = {},
header: @Composable () -> Unit = {}, header: @Composable () -> Unit = {},
@ -63,25 +67,53 @@ fun HeaderFooterPage(
) { padding -> ) { padding ->
Box { Box {
background() background()
Column( if (isScrollable) {
modifier = Modifier // Render in a LazyColumn
.padding(paddingValues = paddingValues) LazyColumn(
.padding(padding) modifier = Modifier
.consumeWindowInsets(padding) .padding(paddingValues = paddingValues)
) { .padding(padding)
// Header .consumeWindowInsets(padding)
header() .imePadding()
// Content ) {
// Header
item {
header()
}
// Content
item {
content()
}
// Footer
item {
Box(modifier = Modifier.padding(horizontal = 16.dp)) {
footer()
}
}
}
} else {
// Render in a Column
Column( Column(
modifier = Modifier modifier = Modifier
.weight(1f) .padding(paddingValues = paddingValues)
.fillMaxWidth(), .padding(padding)
.consumeWindowInsets(padding)
.imePadding()
) { ) {
content() // Header
} header()
// Footer // Content
Box(modifier = Modifier.padding(horizontal = 16.dp)) { Column(
footer() modifier = Modifier
.weight(1f)
.fillMaxWidth(),
) {
content()
}
// Footer
Box(modifier = Modifier.padding(horizontal = 16.dp)) {
footer()
}
} }
} }
} }

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.matrix.api.auth package io.element.android.libraries.matrix.api.auth
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData
import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
@ -31,6 +32,7 @@ interface MatrixAuthenticationService {
/** /**
* Restore a session from a [sessionId]. * Restore a session from a [sessionId].
* Do not restore anything it the access token is not valid anymore. * Do not restore anything it the access token is not valid anymore.
* Generally this method should not be used directly, prefer using [MatrixClientProvider.getOrRestore] instead.
*/ */
suspend fun restoreSession(sessionId: SessionId): Result<MatrixClient> suspend fun restoreSession(sessionId: SessionId): Result<MatrixClient>
fun getHomeserverDetails(): StateFlow<MatrixHomeServerDetails?> fun getHomeserverDetails(): StateFlow<MatrixHomeServerDetails?>

View file

@ -170,7 +170,7 @@ class RoomSummaryListProcessorTest {
override suspend fun applyInput(input: RoomListInput) = Unit override suspend fun applyInput(input: RoomListInput) = Unit
override suspend fun room(roomId: String): RoomListItem { override fun room(roomId: String): RoomListItem {
return RoomListItem(Pointer.NULL) return RoomListItem(Pointer.NULL)
} }

View file

@ -26,7 +26,6 @@ import kotlinx.coroutines.flow.StateFlow
class FakeRoomListService : RoomListService { class FakeRoomListService : RoomListService {
private val allRoomSummariesFlow = MutableStateFlow<List<RoomSummary>>(emptyList()) private val allRoomSummariesFlow = MutableStateFlow<List<RoomSummary>>(emptyList())
private val inviteRoomSummariesFlow = MutableStateFlow<List<RoomSummary>>(emptyList())
private val allRoomsLoadingStateFlow = MutableStateFlow<RoomList.LoadingState>(RoomList.LoadingState.NotLoaded) private val allRoomsLoadingStateFlow = MutableStateFlow<RoomList.LoadingState>(RoomList.LoadingState.NotLoaded)
private val roomListStateFlow = MutableStateFlow<RoomListService.State>(RoomListService.State.Idle) private val roomListStateFlow = MutableStateFlow<RoomListService.State>(RoomListService.State.Idle)
private val syncIndicatorStateFlow = MutableStateFlow<RoomListService.SyncIndicator>(RoomListService.SyncIndicator.Hide) private val syncIndicatorStateFlow = MutableStateFlow<RoomListService.SyncIndicator>(RoomListService.SyncIndicator.Hide)
@ -35,10 +34,6 @@ class FakeRoomListService : RoomListService {
allRoomSummariesFlow.emit(roomSummaries) allRoomSummariesFlow.emit(roomSummaries)
} }
suspend fun postInviteRooms(roomSummaries: List<RoomSummary>) {
inviteRoomSummariesFlow.emit(roomSummaries)
}
suspend fun postAllRoomsLoadingState(loadingState: RoomList.LoadingState) { suspend fun postAllRoomsLoadingState(loadingState: RoomList.LoadingState) {
allRoomsLoadingStateFlow.emit(loadingState) allRoomsLoadingStateFlow.emit(loadingState)
} }

View file

@ -20,7 +20,7 @@ import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.extensions.flatMap
import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.pushproviders.api.PusherSubscriber import io.element.android.libraries.pushproviders.api.PusherSubscriber
import io.element.android.libraries.pushstore.api.UserPushStoreFactory import io.element.android.libraries.pushstore.api.UserPushStoreFactory
@ -43,7 +43,7 @@ class DefaultFirebaseNewTokenHandler @Inject constructor(
private val pusherSubscriber: PusherSubscriber, private val pusherSubscriber: PusherSubscriber,
private val sessionStore: SessionStore, private val sessionStore: SessionStore,
private val userPushStoreFactory: UserPushStoreFactory, private val userPushStoreFactory: UserPushStoreFactory,
private val matrixAuthenticationService: MatrixAuthenticationService, private val matrixClientProvider: MatrixClientProvider,
private val firebaseStore: FirebaseStore, private val firebaseStore: FirebaseStore,
) : FirebaseNewTokenHandler { ) : FirebaseNewTokenHandler {
override suspend fun handle(firebaseToken: String) { override suspend fun handle(firebaseToken: String) {
@ -54,8 +54,8 @@ class DefaultFirebaseNewTokenHandler @Inject constructor(
.forEach { sessionId -> .forEach { sessionId ->
val userDataStore = userPushStoreFactory.getOrCreate(sessionId) val userDataStore = userPushStoreFactory.getOrCreate(sessionId)
if (userDataStore.getPushProviderName() == FirebaseConfig.NAME) { if (userDataStore.getPushProviderName() == FirebaseConfig.NAME) {
matrixAuthenticationService matrixClientProvider
.restoreSession(sessionId) .getOrRestore(sessionId)
.onFailure { .onFailure {
Timber.tag(loggerTag.value).e(it, "Failed to restore session $sessionId") Timber.tag(loggerTag.value).e(it, "Failed to restore session $sessionId")
} }

View file

@ -18,13 +18,13 @@ package io.element.android.libraries.pushproviders.firebase
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.AN_EXCEPTION
import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.A_USER_ID_2
import io.element.android.libraries.matrix.test.A_USER_ID_3 import io.element.android.libraries.matrix.test.A_USER_ID_3
import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
import io.element.android.libraries.push.test.FakePusherSubscriber import io.element.android.libraries.push.test.FakePusherSubscriber
import io.element.android.libraries.pushproviders.api.PusherSubscriber import io.element.android.libraries.pushproviders.api.PusherSubscriber
import io.element.android.libraries.pushstore.api.UserPushStoreFactory import io.element.android.libraries.pushstore.api.UserPushStoreFactory
@ -64,16 +64,14 @@ class DefaultFirebaseNewTokenHandlerTest {
storeData(aSessionData(A_USER_ID_2)) storeData(aSessionData(A_USER_ID_2))
storeData(aSessionData(A_USER_ID_3)) storeData(aSessionData(A_USER_ID_3))
}, },
matrixAuthenticationService = FakeMatrixAuthenticationService( matrixClientProvider = FakeMatrixClientProvider { sessionId ->
matrixClientResult = { sessionId -> when (sessionId) {
when (sessionId) { A_USER_ID -> Result.success(aMatrixClient1)
A_USER_ID -> Result.success(aMatrixClient1) A_USER_ID_2 -> Result.success(aMatrixClient2)
A_USER_ID_2 -> Result.success(aMatrixClient2) A_USER_ID_3 -> Result.success(aMatrixClient3)
A_USER_ID_3 -> Result.success(aMatrixClient3) else -> Result.failure(IllegalStateException())
else -> Result.failure(IllegalStateException())
}
} }
), },
userPushStoreFactory = FakeUserPushStoreFactory( userPushStoreFactory = FakeUserPushStoreFactory(
userPushStore = { sessionId -> userPushStore = { sessionId ->
when (sessionId) { when (sessionId) {
@ -103,11 +101,9 @@ class DefaultFirebaseNewTokenHandlerTest {
sessionStore = InMemoryMultiSessionsStore().apply { sessionStore = InMemoryMultiSessionsStore().apply {
storeData(aSessionData(A_USER_ID)) storeData(aSessionData(A_USER_ID))
}, },
matrixAuthenticationService = FakeMatrixAuthenticationService( matrixClientProvider = FakeMatrixClientProvider {
matrixClientResult = { _ -> Result.failure(IllegalStateException())
Result.failure(IllegalStateException()) },
}
),
userPushStoreFactory = FakeUserPushStoreFactory( userPushStoreFactory = FakeUserPushStoreFactory(
userPushStore = { _ -> userPushStore = { _ ->
FakeUserPushStore(pushProviderName = FirebaseConfig.NAME) FakeUserPushStore(pushProviderName = FirebaseConfig.NAME)
@ -129,11 +125,9 @@ class DefaultFirebaseNewTokenHandlerTest {
sessionStore = InMemoryMultiSessionsStore().apply { sessionStore = InMemoryMultiSessionsStore().apply {
storeData(aSessionData(A_USER_ID)) storeData(aSessionData(A_USER_ID))
}, },
matrixAuthenticationService = FakeMatrixAuthenticationService( matrixClientProvider = FakeMatrixClientProvider {
matrixClientResult = { _ -> Result.success(aMatrixClient1)
Result.success(aMatrixClient1) },
}
),
userPushStoreFactory = FakeUserPushStoreFactory( userPushStoreFactory = FakeUserPushStoreFactory(
userPushStore = { _ -> userPushStore = { _ ->
FakeUserPushStore(pushProviderName = FirebaseConfig.NAME) FakeUserPushStore(pushProviderName = FirebaseConfig.NAME)
@ -152,14 +146,14 @@ class DefaultFirebaseNewTokenHandlerTest {
pusherSubscriber: PusherSubscriber = FakePusherSubscriber(), pusherSubscriber: PusherSubscriber = FakePusherSubscriber(),
sessionStore: SessionStore = InMemorySessionStore(), sessionStore: SessionStore = InMemorySessionStore(),
userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(), userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(),
matrixAuthenticationService: MatrixAuthenticationService = FakeMatrixAuthenticationService(), matrixClientProvider: MatrixClientProvider = FakeMatrixClientProvider(),
firebaseStore: FirebaseStore = InMemoryFirebaseStore(), firebaseStore: FirebaseStore = InMemoryFirebaseStore(),
): FirebaseNewTokenHandler { ): FirebaseNewTokenHandler {
return DefaultFirebaseNewTokenHandler( return DefaultFirebaseNewTokenHandler(
pusherSubscriber = pusherSubscriber, pusherSubscriber = pusherSubscriber,
sessionStore = sessionStore, sessionStore = sessionStore,
userPushStoreFactory = userPushStoreFactory, userPushStoreFactory = userPushStoreFactory,
matrixAuthenticationService = matrixAuthenticationService, matrixClientProvider = matrixClientProvider,
firebaseStore = firebaseStore firebaseStore = firebaseStore
) )
} }

View file

@ -20,7 +20,7 @@ import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.core.extensions.flatMap
import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.AppScope
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.pushproviders.api.PusherSubscriber import io.element.android.libraries.pushproviders.api.PusherSubscriber
import io.element.android.libraries.pushstore.api.UserPushStoreFactory import io.element.android.libraries.pushstore.api.UserPushStoreFactory
import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret import io.element.android.libraries.pushstore.api.clientsecret.PushClientSecret
@ -41,7 +41,7 @@ class DefaultUnifiedPushNewGatewayHandler @Inject constructor(
private val pusherSubscriber: PusherSubscriber, private val pusherSubscriber: PusherSubscriber,
private val userPushStoreFactory: UserPushStoreFactory, private val userPushStoreFactory: UserPushStoreFactory,
private val pushClientSecret: PushClientSecret, private val pushClientSecret: PushClientSecret,
private val matrixAuthenticationService: MatrixAuthenticationService, private val matrixClientProvider: MatrixClientProvider,
) : UnifiedPushNewGatewayHandler { ) : UnifiedPushNewGatewayHandler {
override suspend fun handle(endpoint: String, pushGateway: String, clientSecret: String): Result<Unit> { override suspend fun handle(endpoint: String, pushGateway: String, clientSecret: String): Result<Unit> {
// Register the pusher for the session with this client secret, if is it using UnifiedPush. // Register the pusher for the session with this client secret, if is it using UnifiedPush.
@ -52,8 +52,8 @@ class DefaultUnifiedPushNewGatewayHandler @Inject constructor(
} }
val userDataStore = userPushStoreFactory.getOrCreate(userId) val userDataStore = userPushStoreFactory.getOrCreate(userId)
return if (userDataStore.getPushProviderName() == UnifiedPushConfig.NAME) { return if (userDataStore.getPushProviderName() == UnifiedPushConfig.NAME) {
matrixAuthenticationService matrixClientProvider
.restoreSession(userId) .getOrRestore(userId)
.flatMap { client -> .flatMap { client ->
pusherSubscriber.registerPusher(client, endpoint, pushGateway) pusherSubscriber.registerPusher(client, endpoint, pushGateway)
} }

View file

@ -18,11 +18,11 @@ package io.element.android.libraries.pushproviders.unifiedpush
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService import io.element.android.libraries.matrix.api.MatrixClientProvider
import io.element.android.libraries.matrix.test.A_SECRET import io.element.android.libraries.matrix.test.A_SECRET
import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService import io.element.android.libraries.matrix.test.FakeMatrixClientProvider
import io.element.android.libraries.push.test.FakePusherSubscriber import io.element.android.libraries.push.test.FakePusherSubscriber
import io.element.android.libraries.pushproviders.api.PusherSubscriber import io.element.android.libraries.pushproviders.api.PusherSubscriber
import io.element.android.libraries.pushstore.api.UserPushStoreFactory import io.element.android.libraries.pushstore.api.UserPushStoreFactory
@ -86,7 +86,7 @@ class DefaultUnifiedPushNewGatewayHandlerTest {
pusherSubscriber = FakePusherSubscriber( pusherSubscriber = FakePusherSubscriber(
registerPusherResult = { _, _, _ -> Result.failure(IllegalStateException("an error")) } registerPusherResult = { _, _, _ -> Result.failure(IllegalStateException("an error")) }
), ),
matrixAuthenticationService = FakeMatrixAuthenticationService(matrixClientResult = { Result.success(aMatrixClient) }), matrixClientProvider = FakeMatrixClientProvider { Result.success(aMatrixClient) },
) )
val result = defaultUnifiedPushNewGatewayHandler.handle( val result = defaultUnifiedPushNewGatewayHandler.handle(
endpoint = "aEndpoint", endpoint = "aEndpoint",
@ -114,7 +114,7 @@ class DefaultUnifiedPushNewGatewayHandlerTest {
pusherSubscriber = FakePusherSubscriber( pusherSubscriber = FakePusherSubscriber(
registerPusherResult = lambda registerPusherResult = lambda
), ),
matrixAuthenticationService = FakeMatrixAuthenticationService(matrixClientResult = { Result.success(aMatrixClient) }), matrixClientProvider = FakeMatrixClientProvider { Result.success(aMatrixClient) },
) )
val result = defaultUnifiedPushNewGatewayHandler.handle( val result = defaultUnifiedPushNewGatewayHandler.handle(
endpoint = "aEndpoint", endpoint = "aEndpoint",
@ -131,13 +131,13 @@ class DefaultUnifiedPushNewGatewayHandlerTest {
pusherSubscriber: PusherSubscriber = FakePusherSubscriber(), pusherSubscriber: PusherSubscriber = FakePusherSubscriber(),
userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(), userPushStoreFactory: UserPushStoreFactory = FakeUserPushStoreFactory(),
pushClientSecret: PushClientSecret = FakePushClientSecret(), pushClientSecret: PushClientSecret = FakePushClientSecret(),
matrixAuthenticationService: MatrixAuthenticationService = FakeMatrixAuthenticationService() matrixClientProvider: MatrixClientProvider = FakeMatrixClientProvider()
): DefaultUnifiedPushNewGatewayHandler { ): DefaultUnifiedPushNewGatewayHandler {
return DefaultUnifiedPushNewGatewayHandler( return DefaultUnifiedPushNewGatewayHandler(
pusherSubscriber = pusherSubscriber, pusherSubscriber = pusherSubscriber,
userPushStoreFactory = userPushStoreFactory, userPushStoreFactory = userPushStoreFactory,
pushClientSecret = pushClientSecret, pushClientSecret = pushClientSecret,
matrixAuthenticationService = matrixAuthenticationService matrixClientProvider = matrixClientProvider,
) )
} }
} }

View file

@ -37,6 +37,6 @@ class StableCharSequence(initialText: CharSequence = "") {
fun needsDisplaying(): Boolean = needsDisplaying fun needsDisplaying(): Boolean = needsDisplaying
override fun toString(): String { override fun toString(): String {
return "ImmutableCharSequence(value='$value', needsDisplaying=$needsDisplaying)" return "StableCharSequence(value='$value', needsDisplaying=$needsDisplaying)"
} }
} }

View file

@ -183,7 +183,7 @@ class MarkdownTextInputTest {
onTyping: (Boolean) -> Unit = {}, onTyping: (Boolean) -> Unit = {},
onSuggestionReceived: (Suggestion?) -> Unit = {}, onSuggestionReceived: (Suggestion?) -> Unit = {},
) { ) {
rule.setContent { setContent {
val style = ElementRichTextEditorStyle.composerStyle(hasFocus = state.hasFocus) val style = ElementRichTextEditorStyle.composerStyle(hasFocus = state.hasFocus)
MarkdownTextInput( MarkdownTextInput(
state = state, state = state,

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d6eee7bae50007c89720f7a0f14512828a202db0a6c139690d09dd2e051af8ed
size 11766

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:73d053268a0b2e968a35c02ab58dc5f0a9ff8e9b3412a6c88f5bfeb94031bc9a
size 18742

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a096a8e2170f14cf87063bf25c65b8a019531979b7702755bd86da84bb1a2eda
size 10257

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4fd3519872e9e0036da1cf158dc8c8c838545b281c9c5fa87c84a2220c066131
size 16723

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:d703bbf9fa2dd21d4b7e1dea3f9096520e04dddc61a66286f28e1be2b6deae41 oid sha256:485585964998ee6bb7bb6ba208f2f465795a1b1ef59b3e44535b2d60ba9ef8a4
size 37724 size 37761

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:278063037575311b7ad24f91c2403c5e9656871ab956938d163fa94a89a2b23e oid sha256:95a05799a39675cfbb8c2df269131e5dd236c3298a1dadafe15b7c89a62be962
size 49038 size 49077

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:eeca1217caff14f715fcc214dc7f2a01c5d022778c1d9331d41858b836df2abc oid sha256:254973e1b41987fb6dd9db63b5acae4557467e2541867a4fb9448b88851e5fe4
size 46971 size 46993

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:6c6277560b3b430a446fb4e87b3db59331e5e024798d85bf6be6672a6508c6ef oid sha256:cb58ee8ee32d1e308b898980f27317193bff4b0e00f800037834b02793b34dce
size 41076 size 41111

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:700e9c08e7407d2d81e1a090720885cc59b92ab95106258a646532a277cf2012 oid sha256:2d2fc075202325aece0e74f962e5e6a387934d7782a1b39a9226c2b529ecf0b1
size 36646 size 36809

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:db6b5ec486e460be8cc3df6d827ae04d67ba136d2cdf20b14d1c1ab08198136b oid sha256:6909fcc10374f46d14ed628a4c1df0f4aba1fba874d2aa1b5554a74409dae861
size 47557 size 47737

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:cf789850fac3937f98b7d0fc27f030fd0245212bc6087cb34e7d1aebae850e27 oid sha256:48e95b0eac9a83ce6abf5d82e904faf4081496d399eed9f8e4d806393f042a14
size 46279 size 46286

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:549c3981541b71058c6608a9cffee28a6cb95b1eab819db5de86c43eed9961e3 oid sha256:83c91d4e1bc3b9021c91d353b63a63c1893fdc79de57f91d8a6446b84bae657a
size 38319 size 38441