OnBoardingEvents -> OnBoardingEvent

This commit is contained in:
Benoit Marty
2026-08-25 10:03:05 +02:00
parent 835690a1c2
commit b75d8bb6c1
7 changed files with 33 additions and 33 deletions
@@ -8,11 +8,11 @@
package io.element.android.features.login.impl.screens.onboarding package io.element.android.features.login.impl.screens.onboarding
sealed interface OnBoardingEvents { sealed interface OnBoardingEvent {
data class OnSignIn( data class OnSignIn(
val defaultAccountProvider: String val defaultAccountProvider: String
) : OnBoardingEvents ) : OnBoardingEvent
data object OnVersionClick : OnBoardingEvents data object OnVersionClick : OnBoardingEvent
data object ClearError : OnBoardingEvents data object ClearError : OnBoardingEvent
} }
@@ -101,9 +101,9 @@ class OnBoardingPresenter(
val loginModeState = loginModePresenter.present() val loginModeState = loginModePresenter.present()
fun handleEvent(event: OnBoardingEvents) { fun handleEvent(event: OnBoardingEvent) {
when (event) { when (event) {
is OnBoardingEvents.OnSignIn -> localCoroutineScope.launch { is OnBoardingEvent.OnSignIn -> localCoroutineScope.launch {
// Ensure that the current account provider is set // Ensure that the current account provider is set
accountProviderDataSource.setUrl(event.defaultAccountProvider) accountProviderDataSource.setUrl(event.defaultAccountProvider)
loginModeState.eventSink( loginModeState.eventSink(
@@ -115,8 +115,8 @@ class OnBoardingPresenter(
) )
) )
} }
OnBoardingEvents.ClearError -> loginModeState.eventSink(LoginModeEvent.ClearError) OnBoardingEvent.ClearError -> loginModeState.eventSink(LoginModeEvent.ClearError)
OnBoardingEvents.OnVersionClick -> { OnBoardingEvent.OnVersionClick -> {
if (canReportBug) { if (canReportBug) {
if (multipleTapToUnlock.unlock(localCoroutineScope)) { if (multipleTapToUnlock.unlock(localCoroutineScope)) {
showReportBug = true showReportBug = true
@@ -26,7 +26,7 @@ data class OnBoardingState(
@DrawableRes @DrawableRes
val onBoardingLogoResId: Int?, val onBoardingLogoResId: Int?,
val loginModeState: LoginModeState, val loginModeState: LoginModeState,
val eventSink: (OnBoardingEvents) -> Unit, val eventSink: (OnBoardingEvent) -> Unit,
) { ) {
val submitEnabled: Boolean val submitEnabled: Boolean
get() = defaultAccountProvider != null && get() = defaultAccountProvider != null &&
@@ -50,7 +50,7 @@ fun anOnBoardingState(
@DrawableRes @DrawableRes
customLogoResId: Int? = null, customLogoResId: Int? = null,
loginModeState: LoginModeState = aLoginModeState(), loginModeState: LoginModeState = aLoginModeState(),
eventSink: (OnBoardingEvents) -> Unit = {}, eventSink: (OnBoardingEvent) -> Unit = {},
) = OnBoardingState( ) = OnBoardingState(
isAddingAccount = isAddingAccount, isAddingAccount = isAddingAccount,
showBackButton = showBackButton, showBackButton = showBackButton,
@@ -78,7 +78,7 @@ fun OnBoardingView(
LoginModeView( LoginModeView(
loginMode = state.loginModeState.loginMode, loginMode = state.loginModeState.loginMode,
onClearError = { onClearError = {
state.eventSink(OnBoardingEvents.ClearError) state.eventSink(OnBoardingEvent.ClearError)
}, },
onLearnMoreClick = onLearnMoreClick, onLearnMoreClick = onLearnMoreClick,
onOAuthDetails = onOAuthDetails, onOAuthDetails = onOAuthDetails,
@@ -306,7 +306,7 @@ private fun OnBoardingButtons(
text = stringResource(id = R.string.screen_onboarding_sign_in_to, defaultAccountProvider), text = stringResource(id = R.string.screen_onboarding_sign_in_to, defaultAccountProvider),
showProgress = isLoading, showProgress = isLoading,
onClick = { onClick = {
state.eventSink(OnBoardingEvents.OnSignIn(defaultAccountProvider)) state.eventSink(OnBoardingEvent.OnSignIn(defaultAccountProvider))
}, },
enabled = state.submitEnabled || isLoading, enabled = state.submitEnabled || isLoading,
modifier = Modifier modifier = Modifier
@@ -336,7 +336,7 @@ private fun OnBoardingButtons(
Text( Text(
modifier = Modifier modifier = Modifier
.clickable(role = Role.Button) { .clickable(role = Role.Button) {
state.eventSink(OnBoardingEvents.OnVersionClick) state.eventSink(OnBoardingEvent.OnVersionClick)
} }
.padding(16.dp), .padding(16.dp),
text = stringResource(id = R.string.screen_onboarding_app_version, state.version), text = stringResource(id = R.string.screen_onboarding_app_version, state.version),
@@ -153,7 +153,7 @@ class OnBoardingPresenterTest {
awaitItem().also { state -> awaitItem().also { state ->
assertThat(state.canReportBug).isFalse() assertThat(state.canReportBug).isFalse()
repeat(7) { repeat(7) {
state.eventSink(OnBoardingEvents.OnVersionClick) state.eventSink(OnBoardingEvent.OnVersionClick)
} }
} }
expectNoEvents() expectNoEvents()
@@ -168,7 +168,7 @@ class OnBoardingPresenterTest {
awaitItem().also { state -> awaitItem().also { state ->
assertThat(state.canReportBug).isFalse() assertThat(state.canReportBug).isFalse()
repeat(7) { repeat(7) {
state.eventSink(OnBoardingEvents.OnVersionClick) state.eventSink(OnBoardingEvent.OnVersionClick)
} }
} }
assertThat(awaitItem().canReportBug).isTrue() assertThat(awaitItem().canReportBug).isTrue()
@@ -272,7 +272,7 @@ class OnBoardingPresenterTest {
awaitItem().also { awaitItem().also {
assertThat(it.defaultAccountProvider).isEqualTo(A_HOMESERVER_URL) assertThat(it.defaultAccountProvider).isEqualTo(A_HOMESERVER_URL)
assertThat(accountProviderDataSource.flow.first().url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL) assertThat(accountProviderDataSource.flow.first().url).isEqualTo(AuthenticationConfig.MATRIX_ORG_URL)
it.eventSink(OnBoardingEvents.OnSignIn(A_HOMESERVER_URL_2)) it.eventSink(OnBoardingEvent.OnSignIn(A_HOMESERVER_URL_2))
skipItems(1) // Loading skipItems(1) // Loading
// Account data source has been updated // Account data source has been updated
assertThat(accountProviderDataSource.flow.first().url).isEqualTo(A_HOMESERVER_URL_2) assertThat(accountProviderDataSource.flow.first().url).isEqualTo(A_HOMESERVER_URL_2)
@@ -281,7 +281,7 @@ class OnBoardingPresenterTest {
assertThat(submittedState.loginModeState.loginMode).isInstanceOf(AsyncData.Failure::class.java) assertThat(submittedState.loginModeState.loginMode).isInstanceOf(AsyncData.Failure::class.java)
// Assert the error is then cleared // Assert the error is then cleared
submittedState.eventSink(OnBoardingEvents.ClearError) submittedState.eventSink(OnBoardingEvent.ClearError)
val clearedState = awaitItem() val clearedState = awaitItem()
assertThat(clearedState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized) assertThat(clearedState.loginModeState.loginMode).isEqualTo(AsyncData.Uninitialized)
} }
@@ -39,7 +39,7 @@ import org.junit.Test
class OnboardingViewTest : RobolectricTestParameter() { class OnboardingViewTest : RobolectricTestParameter() {
@Test @Test
fun `when can create account - clicking on create account calls the expected callback`() = runAndroidComposeUiTest { fun `when can create account - clicking on create account calls the expected callback`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false) val eventSink = EventsRecorder<OnBoardingEvent>(expectEvents = false)
ensureCalledOnce { callback -> ensureCalledOnce { callback ->
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
@@ -58,7 +58,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test @Test
fun `when can go back - clicking on back calls the expected callback`() = runAndroidComposeUiTest { fun `when can go back - clicking on back calls the expected callback`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false) val eventSink = EventsRecorder<OnBoardingEvent>(expectEvents = false)
ensureCalledOnce { callback -> ensureCalledOnce { callback ->
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
@@ -73,7 +73,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test @Test
fun `when can login with QR code - clicking on sign in with QR code calls the expected callback`() = runAndroidComposeUiTest { fun `when can login with QR code - clicking on sign in with QR code calls the expected callback`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false) val eventSink = EventsRecorder<OnBoardingEvent>(expectEvents = false)
ensureCalledOnce { callback -> ensureCalledOnce { callback ->
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
@@ -93,7 +93,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
"cannot search account provider" to true, "cannot search account provider" to true,
) )
) = runAndroidComposeUiTest { ) = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false) val eventSink = EventsRecorder<OnBoardingEvent>(expectEvents = false)
ensureCalledOnceWithParam(mustChooseAccountProvider) { callback -> ensureCalledOnceWithParam(mustChooseAccountProvider) { callback ->
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
@@ -114,7 +114,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
"cannot search account provider" to true, "cannot search account provider" to true,
) )
) = runAndroidComposeUiTest { ) = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false) val eventSink = EventsRecorder<OnBoardingEvent>(expectEvents = false)
ensureCalledOnceWithParam(mustChooseAccountProvider) { callback -> ensureCalledOnceWithParam(mustChooseAccountProvider) { callback ->
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
@@ -131,7 +131,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test @Test
fun `when sign in to pre defined account provider - clicking on button emits the expected event`() = runAndroidComposeUiTest { fun `when sign in to pre defined account provider - clicking on button emits the expected event`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>() val eventSink = EventsRecorder<OnBoardingEvent>()
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
defaultAccountProvider = "element.io", defaultAccountProvider = "element.io",
@@ -140,12 +140,12 @@ class OnboardingViewTest : RobolectricTestParameter() {
) )
val buttonText = activity!!.getString(R.string.screen_onboarding_sign_in_to, "element.io") val buttonText = activity!!.getString(R.string.screen_onboarding_sign_in_to, "element.io")
onNodeWithText(buttonText).performClick() onNodeWithText(buttonText).performClick()
eventSink.assertSingle(OnBoardingEvents.OnSignIn("element.io")) eventSink.assertSingle(OnBoardingEvent.OnSignIn("element.io"))
} }
@Test @Test
fun `when error is displayed - closing the dialog emits the expected event`() = runAndroidComposeUiTest { fun `when error is displayed - closing the dialog emits the expected event`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>() val eventSink = EventsRecorder<OnBoardingEvent>()
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
defaultAccountProvider = "element.io", defaultAccountProvider = "element.io",
@@ -154,12 +154,12 @@ class OnboardingViewTest : RobolectricTestParameter() {
), ),
) )
clickOn(CommonStrings.action_ok) clickOn(CommonStrings.action_ok)
eventSink.assertSingle(OnBoardingEvents.ClearError) eventSink.assertSingle(OnBoardingEvent.ClearError)
} }
@Test @Test
fun `clicking on report a problem calls the sign in callback`() = runAndroidComposeUiTest { fun `clicking on report a problem calls the sign in callback`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false) val eventSink = EventsRecorder<OnBoardingEvent>(expectEvents = false)
ensureCalledOnce { callback -> ensureCalledOnce { callback ->
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
@@ -176,7 +176,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test @Test
fun `clicking on settings calls the developer settings callback`() = runAndroidComposeUiTest { fun `clicking on settings calls the developer settings callback`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false) val eventSink = EventsRecorder<OnBoardingEvent>(expectEvents = false)
ensureCalledOnce { callback -> ensureCalledOnce { callback ->
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
@@ -192,7 +192,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test @Test
fun `cannot report a problem when the feature is disabled`() = runAndroidComposeUiTest { fun `cannot report a problem when the feature is disabled`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>(expectEvents = false) val eventSink = EventsRecorder<OnBoardingEvent>(expectEvents = false)
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
canReportBug = false, canReportBug = false,
@@ -205,7 +205,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
@Test @Test
fun `when success PasswordLogin - the expected callback is invoked and the event is received`() = runAndroidComposeUiTest { fun `when success PasswordLogin - the expected callback is invoked and the event is received`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>() val eventSink = EventsRecorder<OnBoardingEvent>()
ensureCalledOnce { callback -> ensureCalledOnce { callback ->
setOnboardingView( setOnboardingView(
state = anOnBoardingState( state = anOnBoardingState(
@@ -215,12 +215,12 @@ class OnboardingViewTest : RobolectricTestParameter() {
onNeedLoginPassword = callback, onNeedLoginPassword = callback,
) )
} }
eventSink.assertSingle(OnBoardingEvents.ClearError) eventSink.assertSingle(OnBoardingEvent.ClearError)
} }
@Test @Test
fun `when success Oidc - the expected callback is invoked and the event is received`() = runAndroidComposeUiTest { fun `when success Oidc - the expected callback is invoked and the event is received`() = runAndroidComposeUiTest {
val eventSink = EventsRecorder<OnBoardingEvents>() val eventSink = EventsRecorder<OnBoardingEvent>()
val oAuthDetails = OAuthDetails("aUrl") val oAuthDetails = OAuthDetails("aUrl")
ensureCalledOnceWithParam(oAuthDetails) { callback -> ensureCalledOnceWithParam(oAuthDetails) { callback ->
setOnboardingView( setOnboardingView(
@@ -231,7 +231,7 @@ class OnboardingViewTest : RobolectricTestParameter() {
onOAuthDetails = callback, onOAuthDetails = callback,
) )
} }
eventSink.assertSingle(OnBoardingEvents.ClearError) eventSink.assertSingle(OnBoardingEvent.ClearError)
} }
private fun AndroidComposeUiTest<ComponentActivity>.setOnboardingView( private fun AndroidComposeUiTest<ComponentActivity>.setOnboardingView(