Browse Source

Add test for `LoginRootPresenter`

kittykat-patch-1
Benoit Marty 2 years ago
parent
commit
8fb1f2655e
  1. 135
      features/login/src/test/kotlin/io/element/android/features/login/root/LoginRootPresenterTest.kt
  2. 22
      libraries/matrixtest/src/main/kotlin/io/element/android/libraries/matrixtest/auth/FakeAuthenticationService.kt

135
features/login/src/test/kotlin/io/element/android/features/login/root/LoginRootPresenterTest.kt

@ -0,0 +1,135 @@ @@ -0,0 +1,135 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:OptIn(ExperimentalCoroutinesApi::class)
package io.element.android.features.login.root
import app.cash.molecule.RecompositionClock
import app.cash.molecule.moleculeFlow
import app.cash.turbine.test
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.matrix.core.SessionId
import io.element.android.libraries.matrixtest.auth.A_FAILURE
import io.element.android.libraries.matrixtest.auth.A_HOMESERVER
import io.element.android.libraries.matrixtest.auth.A_HOMESERVER_2
import io.element.android.libraries.matrixtest.auth.A_LOGIN
import io.element.android.libraries.matrixtest.auth.A_PASSWORD
import io.element.android.libraries.matrixtest.auth.A_SESSION_ID
import io.element.android.libraries.matrixtest.auth.FakeAuthenticationService
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.junit.Test
class LoginRootPresenterTest {
@Test
fun `present - initial state`() = runTest {
val presenter = LoginRootPresenter(
FakeAuthenticationService(),
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.homeserver).isEqualTo(A_HOMESERVER)
assertThat(initialState.loggedInState).isEqualTo(LoggedInState.NotLoggedIn)
assertThat(initialState.formState).isEqualTo(LoginFormState.Default)
assertThat(initialState.submitEnabled).isFalse()
}
}
@Test
fun `present - enter login and password`() = runTest {
val presenter = LoginRootPresenter(
FakeAuthenticationService(),
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
initialState.eventSink.invoke(LoginRootEvents.SetLogin(A_LOGIN))
val loginState = awaitItem()
assertThat(loginState.formState).isEqualTo(LoginFormState(login = A_LOGIN, password = ""))
assertThat(loginState.submitEnabled).isFalse()
initialState.eventSink.invoke(LoginRootEvents.SetPassword(A_PASSWORD))
val loginAndPasswordState = awaitItem()
assertThat(loginAndPasswordState.formState).isEqualTo(LoginFormState(login = A_LOGIN, password = A_PASSWORD))
assertThat(loginAndPasswordState.submitEnabled).isTrue()
}
}
@Test
fun `present - submit`() = runTest {
val presenter = LoginRootPresenter(
FakeAuthenticationService(),
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
initialState.eventSink.invoke(LoginRootEvents.SetLogin(A_LOGIN))
initialState.eventSink.invoke(LoginRootEvents.SetPassword(A_PASSWORD))
skipItems(1)
val loginAndPasswordState = awaitItem()
loginAndPasswordState.eventSink.invoke(LoginRootEvents.Submit)
val submitState = awaitItem()
assertThat(submitState.loggedInState).isEqualTo(LoggedInState.LoggingIn)
val loggedInState = awaitItem()
assertThat(loggedInState.loggedInState).isEqualTo(LoggedInState.LoggedIn(SessionId(A_SESSION_ID)))
}
}
@Test
fun `present - submit with error`() = runTest {
val authenticationService = FakeAuthenticationService()
val presenter = LoginRootPresenter(
authenticationService,
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
initialState.eventSink.invoke(LoginRootEvents.SetLogin(A_LOGIN))
initialState.eventSink.invoke(LoginRootEvents.SetPassword(A_PASSWORD))
skipItems(1)
val loginAndPasswordState = awaitItem()
authenticationService.givenLoginError(A_FAILURE)
loginAndPasswordState.eventSink.invoke(LoginRootEvents.Submit)
val submitState = awaitItem()
assertThat(submitState.loggedInState).isEqualTo(LoggedInState.LoggingIn)
val loggedInState = awaitItem()
assertThat(loggedInState.loggedInState).isEqualTo(LoggedInState.ErrorLoggingIn(A_FAILURE))
}
}
@Test
fun `present - refresh server`() = runTest {
val authenticationService = FakeAuthenticationService()
val presenter = LoginRootPresenter(
authenticationService,
)
moleculeFlow(RecompositionClock.Immediate) {
presenter.present()
}.test {
val initialState = awaitItem()
assertThat(initialState.homeserver).isEqualTo(A_HOMESERVER)
authenticationService.givenHomeserver(A_HOMESERVER_2)
initialState.eventSink.invoke(LoginRootEvents.RefreshHomeServer)
val refreshedState = awaitItem()
assertThat(refreshedState.homeserver).isEqualTo(A_HOMESERVER_2)
}
}
}

22
libraries/matrixtest/src/main/kotlin/io/element/android/libraries/matrixtest/auth/FakeAuthenticationService.kt

@ -24,8 +24,16 @@ import kotlinx.coroutines.flow.Flow @@ -24,8 +24,16 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
const val A_HOMESERVER = "matrix.org"
const val A_HOMESERVER_2 = "matrix-client.org"
const val A_SESSION_ID = "sessionId"
const val A_LOGIN = "login"
const val A_PASSWORD = "password"
val A_FAILURE = Throwable("error")
class FakeAuthenticationService : MatrixAuthenticationService {
private var homeserver: String = A_HOMESERVER
private var loginError: Throwable? = null
override fun isLoggedIn(): Flow<Boolean> {
return flowOf(false)
}
@ -42,8 +50,12 @@ class FakeAuthenticationService : MatrixAuthenticationService { @@ -42,8 +50,12 @@ class FakeAuthenticationService : MatrixAuthenticationService {
return null
}
fun givenHomeserver(homeserver: String) {
this.homeserver = homeserver
}
override fun getHomeserverOrDefault(): String {
return A_HOMESERVER
return homeserver
}
override suspend fun setHomeserver(homeserver: String) {
@ -51,6 +63,12 @@ class FakeAuthenticationService : MatrixAuthenticationService { @@ -51,6 +63,12 @@ class FakeAuthenticationService : MatrixAuthenticationService {
}
override suspend fun login(username: String, password: String): SessionId {
return SessionId("test")
delay(100)
loginError?.let { throw it }
return SessionId(A_SESSION_ID)
}
fun givenLoginError(throwable: Throwable?) {
loginError = throwable
}
}

Loading…
Cancel
Save