Fix flaky test using deterministic awaitFirstItem instead of awaitLastSequentialItem

This commit is contained in:
Benoit Marty
2024-01-05 09:31:54 +01:00
parent 9cfc5a5c80
commit d4c41e38cc
2 changed files with 22 additions and 18 deletions

View File

@@ -18,6 +18,7 @@ package io.element.android.features.logout.impl
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.ReceiveTurbine
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.architecture.AsyncAction
@@ -32,7 +33,6 @@ import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.awaitLastSequentialItem
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.test.runTest
@@ -50,7 +50,7 @@ class LogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitLastSequentialItem()
val initialState = awaitFirstItem()
assertThat(initialState.isLastSession).isFalse()
assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
assertThat(initialState.doesBackupExistOnServer).isTrue()
@@ -117,7 +117,7 @@ class LogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitLastSequentialItem()
val initialState = awaitFirstItem()
initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
@@ -133,7 +133,7 @@ class LogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitLastSequentialItem()
val initialState = awaitFirstItem()
initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
@@ -156,15 +156,13 @@ class LogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
skipItems(1)
val initialState = awaitItem()
val initialState = awaitFirstItem()
initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
confirmationState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
val loadingState = awaitItem()
assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
skipItems(1)
val errorState = awaitItem()
assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(A_THROWABLE))
errorState.eventSink.invoke(LogoutEvents.CloseDialogs)
@@ -184,15 +182,13 @@ class LogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
skipItems(1)
val initialState = awaitItem()
val initialState = awaitFirstItem()
initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
confirmationState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
val loadingState = awaitItem()
assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
skipItems(1)
val errorState = awaitItem()
assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(A_THROWABLE))
errorState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = true))
@@ -203,6 +199,11 @@ class LogoutPresenterTest {
}
}
private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
skipItems(2)
return awaitItem()
}
private fun createLogoutPresenter(
matrixClient: MatrixClient = FakeMatrixClient(),
encryptionService: EncryptionService = FakeEncryptionService(),

View File

@@ -18,6 +18,7 @@ package io.element.android.features.logout.impl.direct
import app.cash.molecule.RecompositionMode
import app.cash.molecule.moleculeFlow
import app.cash.turbine.ReceiveTurbine
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.features.logout.api.direct.DirectLogoutEvents
@@ -31,7 +32,6 @@ import io.element.android.libraries.matrix.test.A_THROWABLE
import io.element.android.libraries.matrix.test.FakeMatrixClient
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
import io.element.android.tests.testutils.WarmUpRule
import io.element.android.tests.testutils.awaitLastSequentialItem
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.test.runTest
import org.junit.Rule
@@ -48,7 +48,7 @@ class DefaultDirectLogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitLastSequentialItem()
val initialState = awaitFirstItem()
assertThat(initialState.canDoDirectSignOut).isTrue()
assertThat(initialState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
}
@@ -98,7 +98,7 @@ class DefaultDirectLogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitLastSequentialItem()
val initialState = awaitFirstItem()
initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
@@ -114,7 +114,7 @@ class DefaultDirectLogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
val initialState = awaitLastSequentialItem()
val initialState = awaitFirstItem()
initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
@@ -137,8 +137,7 @@ class DefaultDirectLogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
skipItems(1)
val initialState = awaitItem()
val initialState = awaitFirstItem()
initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
@@ -164,8 +163,7 @@ class DefaultDirectLogoutPresenterTest {
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
skipItems(1)
val initialState = awaitItem()
val initialState = awaitFirstItem()
initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
val confirmationState = awaitItem()
assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
@@ -182,6 +180,11 @@ class DefaultDirectLogoutPresenterTest {
}
}
private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
skipItems(1)
return awaitItem()
}
private fun createDefaultDirectLogoutPresenter(
matrixClient: MatrixClient = FakeMatrixClient(),
encryptionService: EncryptionService = FakeEncryptionService(),