Issue#8 Take use of TestFixtures to keep MockWebServer TLS setup in the network module, while still being able to use it in Android Tests

This commit is contained in:
Gergely Hegedus 2022-01-27 22:46:03 +02:00
parent 555ad6d05f
commit 3f4d22528c
18 changed files with 117 additions and 77 deletions

View file

@ -121,5 +121,8 @@ dependencies {
androidTestRuntimeOnly "org.junit.vintage:junit-vintage-engine:$testing_junit5_version" androidTestRuntimeOnly "org.junit.vintage:junit-vintage-engine:$testing_junit5_version"
implementation "io.reactivex.rxjava3:rxjava:3.1.3" implementation "io.reactivex.rxjava3:rxjava:3.1.3"
testImplementation testFixtures(project(':core'))
androidTestImplementation testFixtures(project(':core'))
} }

View file

@ -1,18 +1,12 @@
package org.fnives.test.showcase.testutils package org.fnives.test.showcase.testutils
import okhttp3.OkHttpClient
import okhttp3.tls.HandshakeCertificates
import org.fnives.test.showcase.model.network.BaseUrl
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.fnives.test.showcase.network.testutil.NetworkTestConfigurationHelper
import org.fnives.test.showcase.testutils.idling.NetworkSynchronizationTestRule import org.fnives.test.showcase.testutils.idling.NetworkSynchronizationTestRule
import org.fnives.test.showcase.testutils.idling.NetworkSynchronizationTestRule.OkHttpClientTypes
import org.junit.rules.TestRule import org.junit.rules.TestRule
import org.junit.runner.Description import org.junit.runner.Description
import org.junit.runners.model.Statement import org.junit.runners.model.Statement
import org.koin.core.context.loadKoinModules
import org.koin.dsl.module
import org.koin.test.KoinTest import org.koin.test.KoinTest
import org.koin.test.get
/** /**
* TestRule which ensures Koin is reseted between each tests and setups Network mocking. * TestRule which ensures Koin is reseted between each tests and setups Network mocking.
@ -28,8 +22,6 @@ class MockServerScenarioSetupResetingTestRule(
lateinit var mockServerScenarioSetup: MockServerScenarioSetup lateinit var mockServerScenarioSetup: MockServerScenarioSetup
private val sessionlessQualifier get() = OkHttpClientTypes.SESSIONLESS.asQualifier()
override fun apply(base: Statement, description: Description): Statement = override fun apply(base: Statement, description: Description): Statement =
networkSynchronizationTestRule.apply(base, description) networkSynchronizationTestRule.apply(base, description)
.let(::createStatement) .let(::createStatement)
@ -48,29 +40,9 @@ class MockServerScenarioSetupResetingTestRule(
} }
private fun before() { private fun before() {
mockServerScenarioSetup = MockServerScenarioSetup() mockServerScenarioSetup = NetworkTestConfigurationHelper.startWithHTTPSMockWebServer()
val url = mockServerScenarioSetup.start(true)
val handshakeCertificates = mockServerScenarioSetup.clientCertificates
?: throw IllegalStateException("ClientCertificate should be accessable")
val okHttpClientWithCertificate = createUpdateOkHttpClient(handshakeCertificates)
loadKoinModules(
module {
// add https certificate to okhttp
single(qualifier = sessionlessQualifier) { okHttpClientWithCertificate }
// replace base url with mockWebServer's
single { BaseUrl(url) }
}
)
} }
private fun createUpdateOkHttpClient(handshakeCertificates: HandshakeCertificates) =
get<OkHttpClient>(sessionlessQualifier).newBuilder()
.sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager)
.build()
private fun after() { private fun after() {
mockServerScenarioSetup.stop() mockServerScenarioSetup.stop()
} }

View file

@ -3,12 +3,11 @@ package org.fnives.test.showcase.testutils.idling
import androidx.annotation.CheckResult import androidx.annotation.CheckResult
import androidx.test.espresso.IdlingResource import androidx.test.espresso.IdlingResource
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import org.fnives.test.showcase.network.testutil.NetworkTestConfigurationHelper
import org.junit.rules.TestRule import org.junit.rules.TestRule
import org.junit.runner.Description import org.junit.runner.Description
import org.junit.runners.model.Statement import org.junit.runners.model.Statement
import org.koin.core.qualifier.StringQualifier
import org.koin.test.KoinTest import org.koin.test.KoinTest
import org.koin.test.get
class NetworkSynchronizationTestRule : TestRule, KoinTest { class NetworkSynchronizationTestRule : TestRule, KoinTest {
@ -31,24 +30,14 @@ class NetworkSynchronizationTestRule : TestRule, KoinTest {
@CheckResult @CheckResult
private fun registerNetworkingSynchronization(): Disposable { private fun registerNetworkingSynchronization(): Disposable {
val idlingResources = OkHttpClientTypes.values() val idlingResources = NetworkTestConfigurationHelper.getOkHttpClients()
.map { it to getOkHttpClient(it) } .associateBy(keySelector = { it.toString() })
.associateBy { it.second.dispatcher } .map { (key, client) -> client.asIdlingResource(key) }
.values
.map { (key, client) -> client.asIdlingResource(key.qualifier) }
.map(::IdlingResourceDisposable) .map(::IdlingResourceDisposable)
return CompositeDisposable(idlingResources) return CompositeDisposable(idlingResources)
} }
private fun getOkHttpClient(type: OkHttpClientTypes): OkHttpClient = get(type.asQualifier())
private fun OkHttpClient.asIdlingResource(name: String): IdlingResource = private fun OkHttpClient.asIdlingResource(name: String): IdlingResource =
OkHttp3IdlingResource.create(name, this) OkHttp3IdlingResource.create(name, this)
enum class OkHttpClientTypes(val qualifier: String) {
SESSION("SESSION-NETWORKING"), SESSIONLESS("SESSIONLESS-NETWORKING");
fun asQualifier() = StringQualifier(qualifier)
}
} }

View file

@ -8,7 +8,7 @@ buildscript {
maven { url "https://plugins.gradle.org/m2/" } maven { url "https://plugins.gradle.org/m2/" }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.0.4' classpath 'com.android.tools.build:gradle:7.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jlleitschuh.gradle:ktlint-gradle:10.2.1" classpath "org.jlleitschuh.gradle:ktlint-gradle:10.2.1"
} }

View file

@ -2,6 +2,7 @@ plugins {
id 'java-library' id 'java-library'
id 'kotlin' id 'kotlin'
id 'kotlin-kapt' id 'kotlin-kapt'
id 'java-test-fixtures'
} }
java { java {
@ -30,4 +31,5 @@ dependencies {
testImplementation "org.junit.jupiter:junit-jupiter-params:$testing_junit5_version" testImplementation "org.junit.jupiter:junit-jupiter-params:$testing_junit5_version"
testImplementation project(':mockserver') testImplementation project(':mockserver')
testFixturesApi testFixtures(project(':network'))
} }

View file

@ -14,13 +14,14 @@ import org.fnives.test.showcase.model.auth.LoginStatus
import org.fnives.test.showcase.model.network.BaseUrl import org.fnives.test.showcase.model.network.BaseUrl
import org.fnives.test.showcase.model.shared.Answer import org.fnives.test.showcase.model.shared.Answer
import org.fnives.test.showcase.network.mockserver.ContentData import org.fnives.test.showcase.network.mockserver.ContentData
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario 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.AfterEach
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource import org.junit.jupiter.params.provider.MethodSource
@ -35,7 +36,10 @@ import java.util.stream.Stream
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
class AuthIntegrationTest : KoinTest { class AuthIntegrationTest : KoinTest {
private lateinit var mockServerScenarioSetup: MockServerScenarioSetup @RegisterExtension
@JvmField
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
private val mockServerScenarioSetup get() = mockServerScenarioSetupExtensions.mockServerScenarioSetup
private lateinit var fakeFavouriteContentLocalStorage: FakeFavouriteContentLocalStorage private lateinit var fakeFavouriteContentLocalStorage: FakeFavouriteContentLocalStorage
private lateinit var mockSessionExpirationListener: SessionExpirationListener private lateinit var mockSessionExpirationListener: SessionExpirationListener
private lateinit var fakeUserDataLocalStorage: FakeUserDataLocalStorage private lateinit var fakeUserDataLocalStorage: FakeUserDataLocalStorage
@ -46,15 +50,13 @@ class AuthIntegrationTest : KoinTest {
@BeforeEach @BeforeEach
fun setup() { fun setup() {
mockSessionExpirationListener = mock() mockSessionExpirationListener = mock()
mockServerScenarioSetup = MockServerScenarioSetup()
val url = mockServerScenarioSetup.start(false)
fakeFavouriteContentLocalStorage = FakeFavouriteContentLocalStorage() fakeFavouriteContentLocalStorage = FakeFavouriteContentLocalStorage()
fakeUserDataLocalStorage = FakeUserDataLocalStorage(null) fakeUserDataLocalStorage = FakeUserDataLocalStorage(null)
startKoin { startKoin {
modules( modules(
createCoreModule( createCoreModule(
baseUrl = BaseUrl(url), baseUrl = BaseUrl(mockServerScenarioSetupExtensions.url),
enableNetworkLogging = true, enableNetworkLogging = true,
favouriteContentLocalStorageProvider = { fakeFavouriteContentLocalStorage }, favouriteContentLocalStorageProvider = { fakeFavouriteContentLocalStorage },
sessionExpirationListenerProvider = { mockSessionExpirationListener }, sessionExpirationListenerProvider = { mockSessionExpirationListener },
@ -66,7 +68,6 @@ class AuthIntegrationTest : KoinTest {
@AfterEach @AfterEach
fun tearDown() { fun tearDown() {
mockServerScenarioSetup.stop()
stopKoin() stopKoin()
} }

View file

@ -23,15 +23,16 @@ import org.fnives.test.showcase.model.network.BaseUrl
import org.fnives.test.showcase.model.session.Session import org.fnives.test.showcase.model.session.Session
import org.fnives.test.showcase.model.shared.Resource import org.fnives.test.showcase.model.shared.Resource
import org.fnives.test.showcase.network.mockserver.ContentData import org.fnives.test.showcase.network.mockserver.ContentData
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.fnives.test.showcase.network.mockserver.scenario.content.ContentScenario 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.mockserver.scenario.refresh.RefreshTokenScenario
import org.fnives.test.showcase.network.testutil.MockServerScenarioSetupExtensions
import org.fnives.test.showcase.network.shared.exceptions.NetworkException import org.fnives.test.showcase.network.shared.exceptions.NetworkException
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
import org.koin.core.context.startKoin import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin import org.koin.core.context.stopKoin
import org.koin.test.KoinTest import org.koin.test.KoinTest
@ -42,7 +43,10 @@ import org.mockito.kotlin.verifyZeroInteractions
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
class ContentIntegrationTest : KoinTest { class ContentIntegrationTest : KoinTest {
private lateinit var mockServerScenarioSetup: MockServerScenarioSetup @RegisterExtension
@JvmField
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
private val mockServerScenarioSetup get() = mockServerScenarioSetupExtensions.mockServerScenarioSetup
private lateinit var fakeFavouriteContentLocalStorage: FakeFavouriteContentLocalStorage private lateinit var fakeFavouriteContentLocalStorage: FakeFavouriteContentLocalStorage
private lateinit var mockSessionExpirationListener: SessionExpirationListener private lateinit var mockSessionExpirationListener: SessionExpirationListener
private lateinit var fakeUserDataLocalStorage: FakeUserDataLocalStorage private lateinit var fakeUserDataLocalStorage: FakeUserDataLocalStorage
@ -55,15 +59,13 @@ class ContentIntegrationTest : KoinTest {
@BeforeEach @BeforeEach
fun setup() { fun setup() {
mockSessionExpirationListener = mock() mockSessionExpirationListener = mock()
mockServerScenarioSetup = MockServerScenarioSetup()
val url = mockServerScenarioSetup.start(false)
fakeFavouriteContentLocalStorage = FakeFavouriteContentLocalStorage() fakeFavouriteContentLocalStorage = FakeFavouriteContentLocalStorage()
fakeUserDataLocalStorage = FakeUserDataLocalStorage(session) fakeUserDataLocalStorage = FakeUserDataLocalStorage(session)
startKoin { startKoin {
modules( modules(
createCoreModule( createCoreModule(
baseUrl = BaseUrl(url), baseUrl = BaseUrl(mockServerScenarioSetupExtensions.url),
enableNetworkLogging = true, enableNetworkLogging = true,
favouriteContentLocalStorageProvider = { fakeFavouriteContentLocalStorage }, favouriteContentLocalStorageProvider = { fakeFavouriteContentLocalStorage },
sessionExpirationListenerProvider = { mockSessionExpirationListener }, sessionExpirationListenerProvider = { mockSessionExpirationListener },
@ -76,7 +78,6 @@ class ContentIntegrationTest : KoinTest {
@AfterEach @AfterEach
fun tearDown() { fun tearDown() {
stopKoin() stopKoin()
mockServerScenarioSetup.stop()
} }
@DisplayName("GIVEN normal response without favourites WHEN observed THEN data is returned") @DisplayName("GIVEN normal response without favourites WHEN observed THEN data is returned")

View file

@ -16,16 +16,17 @@ import org.fnives.test.showcase.core.session.SessionExpirationListener
import org.fnives.test.showcase.model.auth.LoginCredentials import org.fnives.test.showcase.model.auth.LoginCredentials
import org.fnives.test.showcase.model.network.BaseUrl import org.fnives.test.showcase.model.network.BaseUrl
import org.fnives.test.showcase.model.shared.Resource import org.fnives.test.showcase.model.shared.Resource
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario 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.mockserver.scenario.content.ContentScenario
import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshTokenScenario import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshTokenScenario
import org.fnives.test.showcase.network.shared.exceptions.NetworkException import org.fnives.test.showcase.network.shared.exceptions.NetworkException
import org.fnives.test.showcase.network.testutil.MockServerScenarioSetupExtensions
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.DisplayName import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
import org.koin.core.context.startKoin import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin import org.koin.core.context.stopKoin
import org.koin.test.KoinTest import org.koin.test.KoinTest
@ -39,7 +40,10 @@ import org.mockito.kotlin.verifyZeroInteractions
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
class SessionExpirationIntegrationTest : KoinTest { class SessionExpirationIntegrationTest : KoinTest {
private lateinit var mockServerScenarioSetup: MockServerScenarioSetup @RegisterExtension
@JvmField
val mockServerScenarioSetupExtensions = MockServerScenarioSetupExtensions()
private val mockServerScenarioSetup get() = mockServerScenarioSetupExtensions.mockServerScenarioSetup
private lateinit var fakeFavouriteContentLocalStorage: FakeFavouriteContentLocalStorage private lateinit var fakeFavouriteContentLocalStorage: FakeFavouriteContentLocalStorage
private lateinit var mockSessionExpirationListener: SessionExpirationListener private lateinit var mockSessionExpirationListener: SessionExpirationListener
private lateinit var fakeUserDataLocalStorage: FakeUserDataLocalStorage private lateinit var fakeUserDataLocalStorage: FakeUserDataLocalStorage
@ -51,15 +55,13 @@ class SessionExpirationIntegrationTest : KoinTest {
@BeforeEach @BeforeEach
fun setup() { fun setup() {
mockSessionExpirationListener = mock() mockSessionExpirationListener = mock()
mockServerScenarioSetup = MockServerScenarioSetup()
val url = mockServerScenarioSetup.start(false)
fakeFavouriteContentLocalStorage = FakeFavouriteContentLocalStorage() fakeFavouriteContentLocalStorage = FakeFavouriteContentLocalStorage()
fakeUserDataLocalStorage = FakeUserDataLocalStorage(null) fakeUserDataLocalStorage = FakeUserDataLocalStorage(null)
startKoin { startKoin {
modules( modules(
createCoreModule( createCoreModule(
baseUrl = BaseUrl(url), baseUrl = BaseUrl(mockServerScenarioSetupExtensions.url),
enableNetworkLogging = true, enableNetworkLogging = true,
favouriteContentLocalStorageProvider = { fakeFavouriteContentLocalStorage }, favouriteContentLocalStorageProvider = { fakeFavouriteContentLocalStorage },
sessionExpirationListenerProvider = { mockSessionExpirationListener }, sessionExpirationListenerProvider = { mockSessionExpirationListener },
@ -71,7 +73,6 @@ class SessionExpirationIntegrationTest : KoinTest {
@AfterEach @AfterEach
fun tearDown() { fun tearDown() {
mockServerScenarioSetup.stop()
stopKoin() stopKoin()
} }

View file

@ -1,6 +1,6 @@
#Sun Apr 11 21:03:49 EEST 2021 #Thu Jan 27 21:44:07 EET 2022
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip zipStoreBase=GRADLE_USER_HOME

View file

@ -72,6 +72,7 @@ task jvmTests(dependsOn: ["app:testDebugUnitTest", "core:test", "network:test"])
task robolectricTests(type: Exec) { task robolectricTests(type: Exec) {
group = 'Tests' group = 'Tests'
description = 'Run all Robolectric tests based on the Instrumented naming convention' description = 'Run all Robolectric tests based on the Instrumented naming convention'
// todo is there a better way?
commandLine 'sh', './gradlew', 'testDebugUnitTest', '--tests', 'org.fnives.test.*InstrumentedTest' commandLine 'sh', './gradlew', 'testDebugUnitTest', '--tests', 'org.fnives.test.*InstrumentedTest'
} }

View file

@ -2,6 +2,7 @@ plugins {
id 'java-library' id 'java-library'
id 'kotlin' id 'kotlin'
id 'kotlin-kapt' id 'kotlin-kapt'
id 'java-test-fixtures'
} }
java { java {
@ -25,9 +26,10 @@ dependencies {
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version" testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"
testImplementation "org.mockito.kotlin:mockito-kotlin:$testing_kotlin_mockito_version" testImplementation "org.mockito.kotlin:mockito-kotlin:$testing_kotlin_mockito_version"
testImplementation "org.junit.jupiter:junit-jupiter-engine:$testing_junit5_version"
testImplementation project(':mockserver')
testImplementation "io.insert-koin:koin-test-junit5:$koin_version"
testImplementation "org.skyscreamer:jsonassert:$testing_json_assert_version" testImplementation "org.skyscreamer:jsonassert:$testing_json_assert_version"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$testing_junit5_version" testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$testing_junit5_version"
testFixturesApi project(':mockserver')
testFixturesApi "org.junit.jupiter:junit-jupiter-engine:$testing_junit5_version"
testFixturesApi "io.insert-koin:koin-test-junit5:$koin_version"
} }

View file

@ -88,5 +88,5 @@ private fun sessionNetworkingModule(
single(qualifier = session) { get<Retrofit>(sessionless).newBuilder().client(get(session)).build() } single(qualifier = session) { get<Retrofit>(sessionless).newBuilder().client(get(session)).build() }
} }
private val session = StringQualifier("SESSION-NETWORKING") internal val session = StringQualifier("SESSION-NETWORKING")
private val sessionless = StringQualifier("SESSIONLESS-NETWORKING") internal val sessionless = StringQualifier("SESSIONLESS-NETWORKING")

View file

@ -6,7 +6,7 @@ import org.fnives.test.showcase.network.di.createNetworkModules
import org.fnives.test.showcase.network.mockserver.ContentData import org.fnives.test.showcase.network.mockserver.ContentData
import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshTokenScenario import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshTokenScenario
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions import org.fnives.test.showcase.network.testutil.MockServerScenarioSetupExtensions
import org.fnives.test.showcase.network.shared.exceptions.NetworkException import org.fnives.test.showcase.network.shared.exceptions.NetworkException
import org.fnives.test.showcase.network.shared.exceptions.ParsingException import org.fnives.test.showcase.network.shared.exceptions.ParsingException
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach

View file

@ -11,7 +11,7 @@ import org.fnives.test.showcase.network.mockserver.ContentData
import org.fnives.test.showcase.network.mockserver.ContentData.createExpectedLoginRequestJson 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.mockserver.scenario.auth.AuthScenario
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions import org.fnives.test.showcase.network.testutil.MockServerScenarioSetupExtensions
import org.fnives.test.showcase.network.shared.exceptions.NetworkException import org.fnives.test.showcase.network.shared.exceptions.NetworkException
import org.fnives.test.showcase.network.shared.exceptions.ParsingException import org.fnives.test.showcase.network.shared.exceptions.ParsingException
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach

View file

@ -6,7 +6,7 @@ import org.fnives.test.showcase.network.di.createNetworkModules
import org.fnives.test.showcase.network.mockserver.ContentData 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.content.ContentScenario
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions import org.fnives.test.showcase.network.testutil.MockServerScenarioSetupExtensions
import org.fnives.test.showcase.network.shared.exceptions.NetworkException import org.fnives.test.showcase.network.shared.exceptions.NetworkException
import org.fnives.test.showcase.network.shared.exceptions.ParsingException import org.fnives.test.showcase.network.shared.exceptions.ParsingException
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach

View file

@ -9,7 +9,7 @@ import org.fnives.test.showcase.network.mockserver.scenario.content.ContentScena
import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshTokenScenario 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.NetworkSessionExpirationListener
import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage import org.fnives.test.showcase.network.session.NetworkSessionLocalStorage
import org.fnives.test.showcase.network.shared.MockServerScenarioSetupExtensions import org.fnives.test.showcase.network.testutil.MockServerScenarioSetupExtensions
import org.fnives.test.showcase.network.shared.exceptions.NetworkException import org.fnives.test.showcase.network.shared.exceptions.NetworkException
import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions

View file

@ -1,4 +1,4 @@
package org.fnives.test.showcase.network.shared package org.fnives.test.showcase.network.testutil
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.junit.jupiter.api.extension.AfterEachCallback import org.junit.jupiter.api.extension.AfterEachCallback

View file

@ -0,0 +1,68 @@
package org.fnives.test.showcase.network.testutil
import okhttp3.OkHttpClient
import org.fnives.test.showcase.model.network.BaseUrl
import org.fnives.test.showcase.network.mockserver.MockServerScenarioSetup
import org.koin.core.context.loadKoinModules
import org.koin.core.qualifier.StringQualifier
import org.koin.dsl.module
import org.koin.test.KoinTest
import org.koin.test.get
/**
* Gives access to internals of Networking so it can be used in MockWebServer more easily.
*/
object NetworkTestConfigurationHelper : KoinTest {
/**
* For some reason importing these didn't work. Still keeping internal, cause it shouldn't leave the module.
*
* import org.fnives.test.showcase.network.di.session
* import org.fnives.test.showcase.network.di.sessionless
*/
internal val session = StringQualifier("SESSION-NETWORKING")
internal val sessionless = StringQualifier("SESSIONLESS-NETWORKING")
/**
* After koin started, this gives you access for the OkHttpClients, so you can synchronize or keep track of them
*/
fun getOkHttpClients(): List<OkHttpClient> = listOf(
get<OkHttpClient>(sessionless),
get<OkHttpClient>(session)
)
/**
* After koin started, this sets up MockServer to be used with HTTPs.
*
* Url, and injected OkHttpClient is modified for this.
*/
fun startWithHTTPSMockWebServer(): MockServerScenarioSetup{
val mockServerScenarioSetup = MockServerScenarioSetup()
val url = mockServerScenarioSetup.start(true)
val handshakeCertificates = mockServerScenarioSetup.clientCertificates
?: throw IllegalStateException("ClientCertificate should be accessable")
reload(baseUrl = BaseUrl(url)) {
it.newBuilder()
.sslSocketFactory(handshakeCertificates.sslSocketFactory(), handshakeCertificates.trustManager)
.build()
}
return mockServerScenarioSetup
}
private fun reload(baseUrl: BaseUrl, adjustments: (OkHttpClient) -> OkHttpClient) {
val current = get<OkHttpClient>(sessionless)
val adjusted = adjustments(current)
loadKoinModules(
module {
// add https certificate to okhttp
single(qualifier = sessionless) { adjusted }
// replace base url with mockWebServer's
single { baseUrl }
}
)
}
}