Issue#49 Add Integration Test instruction set for Core

This commit is contained in:
Gergely Hegedus 2022-01-28 00:24:22 +02:00
parent 9a63cdba38
commit 24cffc5057
7 changed files with 495 additions and 24 deletions

View file

@ -1,7 +1,10 @@
package org.fnives.test.showcase.core.integration
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.last
import kotlinx.coroutines.flow.take
import kotlinx.coroutines.test.runTest
import org.fnives.test.showcase.core.content.GetAllContentUseCase
import org.fnives.test.showcase.core.di.createCoreModule
import org.fnives.test.showcase.core.integration.fake.FakeFavouriteContentLocalStorage
import org.fnives.test.showcase.core.integration.fake.FakeUserDataLocalStorage
@ -9,12 +12,16 @@ import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
import org.fnives.test.showcase.core.login.LoginUseCase
import org.fnives.test.showcase.core.login.LogoutUseCase
import org.fnives.test.showcase.core.session.SessionExpirationListener
import org.fnives.test.showcase.core.storage.UserDataLocalStorage
import org.fnives.test.showcase.core.storage.content.FavouriteContentLocalStorage
import org.fnives.test.showcase.model.auth.LoginCredentials
import org.fnives.test.showcase.model.auth.LoginStatus
import org.fnives.test.showcase.model.network.BaseUrl
import org.fnives.test.showcase.model.shared.Answer
import org.fnives.test.showcase.model.shared.Resource
import org.fnives.test.showcase.network.mockserver.ContentData
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
import org.fnives.test.showcase.network.mockserver.scenario.content.ContentScenario
import org.fnives.test.showcase.network.testutil.MockServerScenarioSetupExtensions
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions
@ -28,6 +35,7 @@ import org.junit.jupiter.params.provider.MethodSource
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import org.koin.test.KoinTest
import org.koin.test.get
import org.koin.test.inject
import org.mockito.kotlin.mock
import org.mockito.kotlin.verifyZeroInteractions
@ -40,9 +48,9 @@ class AuthIntegrationTest : KoinTest {
@JvmField
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
private val mockServerScenarioSetup get() = mockServerScenarioSetupExtensions.mockServerScenarioSetup
private lateinit var fakeFavouriteContentLocalStorage: FakeFavouriteContentLocalStorage
private lateinit var fakeFavouriteContentLocalStorage: FavouriteContentLocalStorage
private lateinit var mockSessionExpirationListener: SessionExpirationListener
private lateinit var fakeUserDataLocalStorage: FakeUserDataLocalStorage
private lateinit var fakeUserDataLocalStorage: UserDataLocalStorage
private val isUserLoggedInUseCase by inject<IsUserLoggedInUseCase>()
private val loginUseCase by inject<LoginUseCase>()
private val logoutUseCase by inject<LogoutUseCase>()
@ -83,7 +91,7 @@ class AuthIntegrationTest : KoinTest {
@DisplayName("GIVEN no session WHEN user is logging in THEN they get session")
@Test
fun login() = runTest {
fun loginSuccess() = runTest {
mockServerScenarioSetup.setScenario(AuthScenario.Success(username = "usr", password = "sEc"), validateArguments = true)
val expectedSession = ContentData.loginSuccessResponse
@ -108,20 +116,6 @@ class AuthIntegrationTest : KoinTest {
verifyZeroInteractions(mockSessionExpirationListener)
}
@DisplayName("GIVEN no session WHEN user is logging in THEN they get session")
@Test
fun loginInvalidCredentials() = runTest {
mockServerScenarioSetup.setScenario(AuthScenario.InvalidCredentials(username = "usr", password = "sEc"), validateArguments = true)
val answer = loginUseCase.invoke(LoginCredentials(username = "usr", password = "sEc"))
val actual = isUserLoggedInUseCase.invoke()
Assertions.assertEquals(Answer.Success(LoginStatus.INVALID_CREDENTIALS), answer)
Assertions.assertFalse(actual, "User is expected to be not logged in")
Assertions.assertEquals(null, fakeUserDataLocalStorage.session)
verifyZeroInteractions(mockSessionExpirationListener)
}
@MethodSource("networkErrorArguments")
@ParameterizedTest(name = "GIVEN {0} network response WHEN login called THEN error is shown")
fun networkInputError(authScenario: AuthScenario) = runTest {
@ -136,7 +130,21 @@ class AuthIntegrationTest : KoinTest {
verifyZeroInteractions(mockSessionExpirationListener)
}
@DisplayName("GIVEN logged in user WHEN user is login out THEN they no longer have a session and content is cleared")
@DisplayName("GIVEN no session WHEN user is logging in THEN they get session")
@Test
fun loginInvalidCredentials() = runTest {
mockServerScenarioSetup.setScenario(AuthScenario.InvalidCredentials(username = "usr", password = "sEc"), validateArguments = true)
val answer = loginUseCase.invoke(LoginCredentials(username = "usr", password = "sEc"))
val actual = isUserLoggedInUseCase.invoke()
Assertions.assertEquals(Answer.Success(LoginStatus.INVALID_CREDENTIALS), answer)
Assertions.assertFalse(actual, "User is expected to be not logged in")
Assertions.assertEquals(null, fakeUserDataLocalStorage.session)
verifyZeroInteractions(mockSessionExpirationListener)
}
@DisplayName("GIVEN logged in user WHEN user is login out THEN they no longer have a session")
@Test
fun logout() = runTest {
mockServerScenarioSetup.setScenario(AuthScenario.Success(username = "usr", password = "sEc"), validateArguments = true)
@ -145,10 +153,26 @@ class AuthIntegrationTest : KoinTest {
logoutUseCase.invoke()
val actual = isUserLoggedInUseCase.invoke()
Assertions.assertEquals(false, actual, "User is expected to be logged out")
Assertions.assertFalse(actual, "User is expected to be logged out")
Assertions.assertEquals(null, fakeUserDataLocalStorage.session)
verifyZeroInteractions(mockSessionExpirationListener)
}
@DisplayName("GIVEN logged in user WHEN user is login out THEN content is cleared")
@Test
fun logoutReleasesContent() = runTest {
mockServerScenarioSetup.setScenario(AuthScenario.Success(username = "usr", password = "sEc"), validateArguments = true)
.setScenario(ContentScenario.Success(usingRefreshedToken = false), validateArguments = true)
loginUseCase.invoke(LoginCredentials(username = "usr", password = "sEc"))
val valuesBeforeLogout = get<GetAllContentUseCase>().get().take(2).last()
logoutUseCase.invoke()
val valuesAfterLogout = get<GetAllContentUseCase>().get().take(2).last()
Assertions.assertTrue(valuesBeforeLogout is Resource.Success, "Before we expect a cached Success")
Assertions.assertTrue(valuesAfterLogout is Resource.Error, "After we expect an error, since our request no longer is authenticated")
}
companion object {
@JvmStatic

View file

@ -0,0 +1,101 @@
package org.fnives.test.showcase.core.integration
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.fnives.test.showcase.core.di.createCoreModule
import org.fnives.test.showcase.core.integration.fake.FakeFavouriteContentLocalStorage
import org.fnives.test.showcase.core.integration.fake.FakeUserDataLocalStorage
import org.fnives.test.showcase.core.login.IsUserLoggedInUseCase
import org.fnives.test.showcase.core.login.LoginUseCase
import org.fnives.test.showcase.core.login.LogoutUseCase
import org.fnives.test.showcase.core.session.SessionExpirationListener
import org.fnives.test.showcase.core.storage.UserDataLocalStorage
import org.fnives.test.showcase.core.storage.content.FavouriteContentLocalStorage
import org.fnives.test.showcase.model.auth.LoginCredentials
import org.fnives.test.showcase.model.auth.LoginStatus
import org.fnives.test.showcase.model.network.BaseUrl
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
import org.fnives.test.showcase.network.testutil.MockServerScenarioSetupExtensions
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
import org.koin.core.context.GlobalContext.startKoin
import org.koin.core.context.GlobalContext.stopKoin
import org.koin.test.KoinTest
import org.koin.test.inject
import org.mockito.kotlin.mock
@OptIn(ExperimentalCoroutinesApi::class)
@Disabled("CodeKata")
class CodeKataAuthIntegrationTest : KoinTest {
@RegisterExtension
@JvmField
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
private val isUserLoggedInUseCase by inject<IsUserLoggedInUseCase>()
private val loginUseCase by inject<LoginUseCase>()
private val logoutUseCase by inject<LogoutUseCase>()
private lateinit var fakeFavouriteContentLocalStorage: FavouriteContentLocalStorage
private lateinit var mockSessionExpirationListener: SessionExpirationListener
private lateinit var fakeUserDataLocalStorage: UserDataLocalStorage
@BeforeEach
fun setup() {
mockSessionExpirationListener = mock() // we are using mock, since it only has 1 function so we just want to verify if it's called
fakeFavouriteContentLocalStorage = FakeFavouriteContentLocalStorage()
fakeUserDataLocalStorage = FakeUserDataLocalStorage(null)
startKoin {
modules(
createCoreModule(
baseUrl = BaseUrl(mockServerScenarioSetupExtensions.url),
enableNetworkLogging = true,
favouriteContentLocalStorageProvider = { fakeFavouriteContentLocalStorage },
sessionExpirationListenerProvider = { mockSessionExpirationListener },
userDataLocalStorageProvider = { fakeUserDataLocalStorage }
).toList()
)
}
}
@AfterEach
fun tearDown() {
stopKoin()
}
@DisplayName("GIVEN no session saved WHEN checking if user is logged in THEN they are not")
@Test
fun withoutSessionTheUserIsNotLoggedIn() = runTest {
}
@DisplayName("GIVEN no session WHEN user is logging in THEN they get session")
@Test
fun loginSuccess() = runTest {
}
@DisplayName("GIVEN credentials WHEN login called THEN error is shown")
@Test
fun localInputError(credentials: LoginCredentials, loginError: LoginStatus) = runTest {
}
@DisplayName("GIVEN network response WHEN login called THEN error is shown")
@Test
fun networkInputError(authScenario: AuthScenario) = runTest {
}
@DisplayName("GIVEN no session WHEN user is logging in THEN they get session")
@Test
fun loginInvalidCredentials() = runTest {
}
@DisplayName("GIVEN logged in user WHEN user is login out THEN they no longer have a session and content is cleared")
@Test
fun logout() = runTest {
}
@DisplayName("GIVEN logged in user WHEN user is login out THEN content is cleared")
@Test
fun logoutReleasesContent() = runTest {
}
}

View file

@ -0,0 +1,4 @@
package org.fnives.test.showcase.core.integration.fake
class CodeKataFavouriteContentLocalStorage {
}

View file

@ -0,0 +1,4 @@
package org.fnives.test.showcase.core.integration.fake
class CodeKataUserDataLocalStorage {
}