initial commit
This commit is contained in:
parent
85ef73b2ba
commit
90a9426b7d
221 changed files with 7611 additions and 0 deletions
|
|
@ -0,0 +1,71 @@
|
|||
package org.fnives.test.showcase.network.auth
|
||||
|
||||
import com.squareup.moshi.JsonDataException
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import okhttp3.internal.http.RealResponseBody
|
||||
import okio.Buffer
|
||||
import org.fnives.test.showcase.model.session.Session
|
||||
import org.fnives.test.showcase.network.auth.model.LoginResponse
|
||||
import org.fnives.test.showcase.network.auth.model.LoginStatusResponses
|
||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
||||
import org.fnives.test.showcase.network.shared.exceptions.ParsingException
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import retrofit2.Response
|
||||
import java.io.IOException
|
||||
|
||||
@Suppress("TestFunctionName")
|
||||
class LoginErrorConverterTest {
|
||||
|
||||
private lateinit var sut: LoginErrorConverter
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
sut = LoginErrorConverter()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_throwing_lambda_WHEN_parsing_login_error_THEN_network_exception_is_thrown() {
|
||||
Assertions.assertThrows(NetworkException::class.java) {
|
||||
runBlocking {
|
||||
sut.invoke { throw IOException() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_jsonException_throwing_lambda_WHEN_parsing_login_error_THEN_network_exception_is_thrown() {
|
||||
Assertions.assertThrows(ParsingException::class.java) {
|
||||
runBlocking {
|
||||
sut.invoke { throw JsonDataException("") }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_400_error_response_WHEN_parsing_login_error_THEN_invalid_credentials_is_returned() = runBlockingTest {
|
||||
val expected = LoginStatusResponses.InvalidCredentials
|
||||
|
||||
val actual = sut.invoke {
|
||||
val responseBody = RealResponseBody(null, 0, Buffer())
|
||||
Response.error(400, responseBody)
|
||||
}
|
||||
|
||||
Assertions.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_successful_response_WHEN_parsing_login_error_THEN_successful_response_is_returned() = runBlockingTest {
|
||||
val loginResponse = LoginResponse("a", "r")
|
||||
val expectedSession = Session(accessToken = loginResponse.accessToken, refreshToken = loginResponse.refreshToken)
|
||||
val expected = LoginStatusResponses.Success(expectedSession)
|
||||
|
||||
val actual = sut.invoke {
|
||||
Response.success(200, loginResponse)
|
||||
}
|
||||
|
||||
Assertions.assertEquals(expected, actual)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
package org.fnives.test.showcase.network.auth
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.fnives.test.showcase.model.network.BaseUrl
|
||||
import org.fnives.test.showcase.network.di.createNetworkModules
|
||||
import org.fnives.test.showcase.network.mockserver.ContentData
|
||||
import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshTokenScenario
|
||||
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
||||
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions
|
||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
||||
import org.fnives.test.showcase.network.shared.exceptions.ParsingException
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.RegisterExtension
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.context.stopKoin
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.inject
|
||||
import org.mockito.kotlin.mock
|
||||
|
||||
@Suppress("TestFunctionName")
|
||||
class LoginRemoteSourceRefreshActionImplTest : KoinTest {
|
||||
|
||||
private val sut by inject<LoginRemoteSourceImpl>()
|
||||
private lateinit var mockNetworkSessionLocalStorage: NetworkSessionLocalStorage
|
||||
|
||||
@RegisterExtension
|
||||
@JvmField
|
||||
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
|
||||
private val mockServerScenarioSetup
|
||||
get() = mockServerScenarioSetupExtensions.mockServerScenarioSetup
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
mockNetworkSessionLocalStorage = mock()
|
||||
startKoin {
|
||||
modules(
|
||||
createNetworkModules(
|
||||
baseUrl = BaseUrl(mockServerScenarioSetupExtensions.url),
|
||||
enableLogging = true,
|
||||
networkSessionExpirationListenerProvider = { mock() },
|
||||
networkSessionLocalStorageProvider = { mockNetworkSessionLocalStorage }
|
||||
).toList()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
stopKoin()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_successful_response_WHEN_refresh_request_is_fired_THEN_session() = runBlocking {
|
||||
mockServerScenarioSetup.setScenario(RefreshTokenScenario.Success)
|
||||
val expected = ContentData.refreshSuccessResponse
|
||||
|
||||
val actual = sut.refresh(ContentData.refreshSuccessResponse.refreshToken)
|
||||
|
||||
Assertions.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_successful_response_WHEN_refresh_request_is_fired_THEN_the_request_is_setup_properly() = runBlocking {
|
||||
mockServerScenarioSetup.setScenario(RefreshTokenScenario.Success, false)
|
||||
|
||||
sut.refresh(ContentData.refreshSuccessResponse.refreshToken)
|
||||
val request = mockServerScenarioSetup.takeRequest()
|
||||
|
||||
Assertions.assertEquals("PUT", request.method)
|
||||
Assertions.assertEquals("Android", request.getHeader("Platform"))
|
||||
Assertions.assertEquals(null, request.getHeader("Authorization"))
|
||||
Assertions.assertEquals("/login/${ContentData.refreshSuccessResponse.refreshToken}", request.path)
|
||||
Assertions.assertEquals("", request.body.readUtf8())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_internal_error_response_WHEN_refresh_request_is_fired_THEN_network_exception_is_thrown() {
|
||||
mockServerScenarioSetup.setScenario(RefreshTokenScenario.Error)
|
||||
|
||||
Assertions.assertThrows(NetworkException::class.java) {
|
||||
runBlocking { sut.refresh(ContentData.refreshSuccessResponse.refreshToken) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_invalid_json_response_WHEN_refresh_request_is_fired_THEN_network_exception_is_thrown() {
|
||||
mockServerScenarioSetup.setScenario(RefreshTokenScenario.UnexpectedJsonAsSuccessResponse)
|
||||
|
||||
Assertions.assertThrows(ParsingException::class.java) {
|
||||
runBlocking { sut.refresh(ContentData.loginSuccessResponse.refreshToken) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_malformed_json_response_WHEN_refresh_request_is_fired_THEN_network_exception_is_thrown() {
|
||||
mockServerScenarioSetup.setScenario(RefreshTokenScenario.MalformedJson)
|
||||
|
||||
Assertions.assertThrows(ParsingException::class.java) {
|
||||
runBlocking { sut.refresh(ContentData.loginSuccessResponse.refreshToken) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
package org.fnives.test.showcase.network.auth
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.fnives.test.showcase.model.auth.LoginCredentials
|
||||
import org.fnives.test.showcase.model.network.BaseUrl
|
||||
import org.fnives.test.showcase.network.auth.model.LoginStatusResponses
|
||||
import org.fnives.test.showcase.network.di.createNetworkModules
|
||||
import org.fnives.test.showcase.network.mockserver.ContentData
|
||||
import org.fnives.test.showcase.network.mockserver.ContentData.createExpectedLoginRequestJson
|
||||
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
|
||||
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
||||
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions
|
||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
||||
import org.fnives.test.showcase.network.shared.exceptions.ParsingException
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.RegisterExtension
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.context.stopKoin
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.inject
|
||||
import org.mockito.kotlin.mock
|
||||
import org.skyscreamer.jsonassert.JSONAssert
|
||||
import org.skyscreamer.jsonassert.JSONCompareMode
|
||||
|
||||
@Suppress("TestFunctionName")
|
||||
class LoginRemoteSourceTest : KoinTest {
|
||||
|
||||
private val sut by inject<LoginRemoteSource>()
|
||||
@RegisterExtension
|
||||
@JvmField
|
||||
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
|
||||
private val mockServerScenarioSetup
|
||||
get() = mockServerScenarioSetupExtensions.mockServerScenarioSetup
|
||||
private lateinit var mockNetworkSessionLocalStorage: NetworkSessionLocalStorage
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
mockNetworkSessionLocalStorage = mock()
|
||||
startKoin {
|
||||
modules(
|
||||
createNetworkModules(
|
||||
baseUrl = BaseUrl(mockServerScenarioSetupExtensions.url),
|
||||
enableLogging = true,
|
||||
networkSessionExpirationListenerProvider = mock(),
|
||||
networkSessionLocalStorageProvider = { mockNetworkSessionLocalStorage }
|
||||
).toList()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
stopKoin()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_successful_response_WHEN_request_is_fired_THEN_login_status_success_is_returned() = runBlocking {
|
||||
mockServerScenarioSetup.setScenario(AuthScenario.Success("a", "b"))
|
||||
val expected = LoginStatusResponses.Success(ContentData.loginSuccessResponse)
|
||||
|
||||
val actual = sut.login(LoginCredentials("a", "b"))
|
||||
|
||||
Assertions.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_successful_response_WHEN_request_is_fired_THEN_the_request_is_setup_properly() = runBlocking {
|
||||
mockServerScenarioSetup.setScenario(AuthScenario.Success("a", "b"), false)
|
||||
|
||||
sut.login(LoginCredentials("a", "b"))
|
||||
val request = mockServerScenarioSetup.takeRequest()
|
||||
|
||||
Assertions.assertEquals("POST", request.method)
|
||||
Assertions.assertEquals("Android", request.getHeader("Platform"))
|
||||
Assertions.assertEquals(null, request.getHeader("Authorization"))
|
||||
Assertions.assertEquals("/login", request.path)
|
||||
val loginRequest = createExpectedLoginRequestJson("a", "b")
|
||||
JSONAssert.assertEquals(loginRequest, request.body.readUtf8(), JSONCompareMode.NON_EXTENSIBLE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_bad_request_response_WHEN_request_is_fired_THEN_login_status_invalid_credentials_is_returned() = runBlocking {
|
||||
mockServerScenarioSetup.setScenario(AuthScenario.InvalidCredentials("a", "b"))
|
||||
val expected = LoginStatusResponses.InvalidCredentials
|
||||
|
||||
val actual = sut.login(LoginCredentials("a", "b"))
|
||||
|
||||
Assertions.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_internal_error_response_WHEN_request_is_fired_THEN_network_exception_is_thrown() {
|
||||
mockServerScenarioSetup.setScenario(AuthScenario.GenericError("a", "b"))
|
||||
|
||||
Assertions.assertThrows(NetworkException::class.java) {
|
||||
runBlocking { sut.login(LoginCredentials("a", "b")) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_invalid_json_response_WHEN_request_is_fired_THEN_network_exception_is_thrown() {
|
||||
mockServerScenarioSetup.setScenario(AuthScenario.UnexpectedJsonAsSuccessResponse("a", "b"))
|
||||
|
||||
Assertions.assertThrows(ParsingException::class.java) {
|
||||
runBlocking { sut.login(LoginCredentials("a", "b")) }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_malformed_json_response_WHEN_request_is_fired_THEN_network_exception_is_thrown() {
|
||||
mockServerScenarioSetup.setScenario(AuthScenario.MalformedJsonAsSuccessResponse("a", "b"))
|
||||
|
||||
Assertions.assertThrows(ParsingException::class.java) {
|
||||
runBlocking { sut.login(LoginCredentials("a", "b")) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
package org.fnives.test.showcase.network.content
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.fnives.test.showcase.model.network.BaseUrl
|
||||
import org.fnives.test.showcase.network.di.createNetworkModules
|
||||
import org.fnives.test.showcase.network.mockserver.ContentData
|
||||
import org.fnives.test.showcase.network.mockserver.scenario.content.ContentScenario
|
||||
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
||||
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions
|
||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
||||
import org.fnives.test.showcase.network.shared.exceptions.ParsingException
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.RegisterExtension
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.context.stopKoin
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.inject
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@Suppress("TestFunctionName")
|
||||
class ContentRemoteSourceImplTest : KoinTest {
|
||||
|
||||
private val sut: ContentRemoteSourceImpl by inject()
|
||||
|
||||
@RegisterExtension
|
||||
@JvmField
|
||||
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
|
||||
private lateinit var mockNetworkSessionLocalStorage: NetworkSessionLocalStorage
|
||||
private val mockServerScenarioSetup
|
||||
get() = mockServerScenarioSetupExtensions.mockServerScenarioSetup
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
mockNetworkSessionLocalStorage = mock()
|
||||
startKoin {
|
||||
modules(
|
||||
createNetworkModules(
|
||||
baseUrl = BaseUrl(mockServerScenarioSetupExtensions.url),
|
||||
enableLogging = true,
|
||||
networkSessionExpirationListenerProvider = { mock() },
|
||||
networkSessionLocalStorageProvider = { mockNetworkSessionLocalStorage }
|
||||
).toList()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
stopKoin()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_successful_response_WHEN_getting_content_THEN_its_parsed_and_returned_correctly() = runBlocking {
|
||||
whenever(mockNetworkSessionLocalStorage.session).doReturn(ContentData.loginSuccessResponse)
|
||||
mockServerScenarioSetup.setScenario(ContentScenario.Success(false))
|
||||
val expected = ContentData.contentSuccess
|
||||
|
||||
val actual = sut.get()
|
||||
|
||||
Assertions.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_successful_response_WHEN_getting_content_THEN_the_request_is_setup_properly() = runBlocking {
|
||||
whenever(mockNetworkSessionLocalStorage.session).doReturn(ContentData.loginSuccessResponse)
|
||||
mockServerScenarioSetup.setScenario(ContentScenario.Success(false), false)
|
||||
|
||||
sut.get()
|
||||
val request = mockServerScenarioSetup.takeRequest()
|
||||
|
||||
Assertions.assertEquals("GET", request.method)
|
||||
Assertions.assertEquals("Android", request.getHeader("Platform"))
|
||||
Assertions.assertEquals(ContentData.loginSuccessResponse.accessToken, request.getHeader("Authorization"))
|
||||
Assertions.assertEquals("/content", request.path)
|
||||
Assertions.assertEquals("", request.body.readUtf8())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_response_with_missing_Field_WHEN_getting_content_THEN_invalid_is_ignored_others_are_returned() = runBlocking {
|
||||
whenever(mockNetworkSessionLocalStorage.session).doReturn(ContentData.loginSuccessResponse)
|
||||
mockServerScenarioSetup.setScenario(ContentScenario.SuccessWithMissingFields(false))
|
||||
|
||||
val expected = ContentData.contentSuccessWithMissingFields
|
||||
|
||||
val actual = sut.get()
|
||||
|
||||
Assertions.assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_error_response_WHEN_getting_content_THEN_network_request_is_thrown() {
|
||||
whenever(mockNetworkSessionLocalStorage.session).doReturn(ContentData.loginSuccessResponse)
|
||||
mockServerScenarioSetup.setScenario(ContentScenario.Error(false))
|
||||
|
||||
Assertions.assertThrows(NetworkException::class.java) {
|
||||
runBlocking { sut.get() }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_unexpected_json_response_WHEN_getting_content_THEN_parsing_request_is_thrown() {
|
||||
whenever(mockNetworkSessionLocalStorage.session).doReturn(ContentData.loginSuccessResponse)
|
||||
mockServerScenarioSetup.setScenario(ContentScenario.UnexpectedJsonAsSuccessResponse(false))
|
||||
|
||||
Assertions.assertThrows(ParsingException::class.java) {
|
||||
runBlocking { sut.get() }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_malformed_json_response_WHEN_getting_content_THEN_parsing_request_is_thrown() {
|
||||
whenever(mockNetworkSessionLocalStorage.session).doReturn(ContentData.loginSuccessResponse)
|
||||
mockServerScenarioSetup.setScenario(ContentScenario.MalformedJsonAsSuccessResponse(false))
|
||||
|
||||
Assertions.assertThrows(ParsingException::class.java) {
|
||||
runBlocking { sut.get() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
package org.fnives.test.showcase.network.content
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.fnives.test.showcase.model.network.BaseUrl
|
||||
import org.fnives.test.showcase.model.session.Session
|
||||
import org.fnives.test.showcase.network.di.createNetworkModules
|
||||
import org.fnives.test.showcase.network.mockserver.ContentData
|
||||
import org.fnives.test.showcase.network.mockserver.scenario.content.ContentScenario
|
||||
import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshTokenScenario
|
||||
import org.fnives.test.showcase.network.session.NetworkSessionExpirationListener
|
||||
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
|
||||
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions
|
||||
import org.fnives.test.showcase.network.shared.exceptions.NetworkException
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.RegisterExtension
|
||||
import org.koin.core.context.startKoin
|
||||
import org.koin.core.context.stopKoin
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.inject
|
||||
import org.mockito.kotlin.anyOrNull
|
||||
import org.mockito.kotlin.doAnswer
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||
import org.mockito.kotlin.verifyZeroInteractions
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@Suppress("TestFunctionName")
|
||||
class SessionExpirationTest : KoinTest {
|
||||
|
||||
private val sut: ContentRemoteSourceImpl by inject()
|
||||
|
||||
@RegisterExtension
|
||||
@JvmField
|
||||
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
|
||||
private val mockServerScenarioSetup
|
||||
get() = mockServerScenarioSetupExtensions.mockServerScenarioSetup
|
||||
private lateinit var mockNetworkSessionLocalStorage: NetworkSessionLocalStorage
|
||||
private lateinit var mockNetworkSessionExpirationListener: NetworkSessionExpirationListener
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
mockNetworkSessionLocalStorage = mock()
|
||||
mockNetworkSessionExpirationListener = mock()
|
||||
startKoin {
|
||||
modules(
|
||||
createNetworkModules(
|
||||
baseUrl = BaseUrl(mockServerScenarioSetupExtensions.url),
|
||||
enableLogging = true,
|
||||
networkSessionExpirationListenerProvider = { mockNetworkSessionExpirationListener },
|
||||
networkSessionLocalStorageProvider = { mockNetworkSessionLocalStorage }
|
||||
).toList()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
stopKoin()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_401_THEN_refresh_token_ok_response_WHEN_content_requested_THE_tokens_are_refreshed_and_request_retried_with_new_tokens() =
|
||||
runBlocking {
|
||||
var sessionToReturnByMock: Session? = ContentData.loginSuccessResponse
|
||||
mockServerScenarioSetup.setScenario(
|
||||
ContentScenario.Unauthorized(false)
|
||||
.then(ContentScenario.Success(true)),
|
||||
false
|
||||
)
|
||||
mockServerScenarioSetup.setScenario(RefreshTokenScenario.Success, false)
|
||||
whenever(mockNetworkSessionLocalStorage.session).doAnswer { sessionToReturnByMock }
|
||||
doAnswer { sessionToReturnByMock = it.arguments[0] as Session? }
|
||||
.whenever(mockNetworkSessionLocalStorage).session = anyOrNull()
|
||||
|
||||
sut.get()
|
||||
|
||||
mockServerScenarioSetup.takeRequest()
|
||||
val refreshRequest = mockServerScenarioSetup.takeRequest()
|
||||
val retryAfterTokenRefreshRequest = mockServerScenarioSetup.takeRequest()
|
||||
|
||||
Assertions.assertEquals("PUT", refreshRequest.method)
|
||||
Assertions.assertEquals("/login/${ContentData.loginSuccessResponse.refreshToken}", refreshRequest.path)
|
||||
Assertions.assertEquals(null, refreshRequest.getHeader("Authorization"))
|
||||
Assertions.assertEquals("Android", refreshRequest.getHeader("Platform"))
|
||||
Assertions.assertEquals("", refreshRequest.body.readUtf8())
|
||||
Assertions.assertEquals(
|
||||
ContentData.refreshSuccessResponse.accessToken,
|
||||
retryAfterTokenRefreshRequest.getHeader("Authorization")
|
||||
)
|
||||
verify(mockNetworkSessionLocalStorage, times(1)).session = ContentData.refreshSuccessResponse
|
||||
verifyZeroInteractions(mockNetworkSessionExpirationListener)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun GIVEN_401_THEN_failing_refresh_WHEN_content_requested_THE_error_is_returned_and_callback_is_Called() = runBlocking {
|
||||
whenever(mockNetworkSessionLocalStorage.session).doReturn(ContentData.loginSuccessResponse)
|
||||
mockServerScenarioSetup.setScenario(ContentScenario.Unauthorized(false))
|
||||
mockServerScenarioSetup.setScenario(RefreshTokenScenario.Error)
|
||||
|
||||
Assertions.assertThrows(NetworkException::class.java) {
|
||||
runBlocking { sut.get() }
|
||||
}
|
||||
verify(mockNetworkSessionLocalStorage, times(3)).session
|
||||
verify(mockNetworkSessionLocalStorage, times(1)).session = null
|
||||
verifyNoMoreInteractions(mockNetworkSessionLocalStorage)
|
||||
verify(mockNetworkSessionExpirationListener, times(1)).onSessionExpired()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package org.fnives.test.showcase.network.shared
|
||||
|
||||
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
|
||||
import org.junit.jupiter.api.extension.AfterEachCallback
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback
|
||||
import org.junit.jupiter.api.extension.ExtensionContext
|
||||
|
||||
class MockServerScenarioSetupExtensions : BeforeEachCallback, AfterEachCallback {
|
||||
|
||||
val url: String = "${MockServerScenarioSetup.HTTP_BASE_URL}:${MockServerScenarioSetup.PORT}/"
|
||||
lateinit var mockServerScenarioSetup: MockServerScenarioSetup
|
||||
|
||||
override fun beforeEach(context: ExtensionContext?) {
|
||||
mockServerScenarioSetup = MockServerScenarioSetup()
|
||||
mockServerScenarioSetup.start(false)
|
||||
}
|
||||
|
||||
override fun afterEach(context: ExtensionContext?) {
|
||||
mockServerScenarioSetup.stop()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue