initial commit

This commit is contained in:
Gergely Hegedus 2021-04-07 21:12:10 +03:00
parent 85ef73b2ba
commit 90a9426b7d
221 changed files with 7611 additions and 0 deletions

1
mockserver/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

22
mockserver/build.gradle Normal file
View file

@ -0,0 +1,22 @@
plugins {
id 'java-library'
id 'kotlin'
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
dependencies {
api "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
api project(":model")
api "com.squareup.okhttp3:mockwebserver:$okhttp_version"
api "com.squareup.okhttp3:okhttp-tls:$okhttp_version"
implementation "org.skyscreamer:jsonassert:$testing_json_assert_version"
implementation "junit:junit:$testing_junit4_version"
}

View file

@ -0,0 +1,45 @@
package org.fnives.test.showcase.network.mockserver
import org.fnives.test.showcase.model.content.Content
import org.fnives.test.showcase.model.content.ContentId
import org.fnives.test.showcase.model.content.ImageUrl
import org.fnives.test.showcase.model.session.Session
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthRequestMatchingChecker
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.refresh.RefreshTokenScenario
object ContentData {
/**
* Returned for [ContentScenario.Success]
*/
val contentSuccess: List<Content> = listOf(
Content(ContentId("1"), "title_1", "says_1", ImageUrl("img_1")),
Content(ContentId("2"), "title_2", "says_2", ImageUrl("img_2")),
Content(ContentId("3"), "title_3", "says_3", ImageUrl("img_3"))
)
/**
* Returned for [ContentScenario.SuccessWithMissingFields]
*/
val contentSuccessWithMissingFields: List<Content> = listOf(
Content(ContentId("1"), "title_1", "says_1", ImageUrl("img_1"))
)
/**
* Returned for [AuthScenario.Success]
*/
val loginSuccessResponse = Session("login-access", "login-refresh")
/**
* Expected for [AuthScenario.Success]
*/
fun createExpectedLoginRequestJson(username: String, password: String) =
AuthRequestMatchingChecker.createExpectedJson(username = username, password = password)
/**
* Returned for [RefreshTokenScenario.Success]
*/
val refreshSuccessResponse = Session("refreshed-access", "refreshed-refresh")
}

View file

@ -0,0 +1,95 @@
package org.fnives.test.showcase.network.mockserver
import okhttp3.mockwebserver.MockWebServer
import okhttp3.tls.HandshakeCertificates
import okhttp3.tls.HeldCertificate
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.refresh.RefreshTokenScenario
import java.net.InetAddress
class MockServerScenarioSetup internal constructor(
private val networkDispatcher: NetworkDispatcher,
private val scenarioToRequestScenario: ScenarioToRequestScenario
) {
constructor() : this(NetworkDispatcher(), ScenarioToRequestScenario())
lateinit var mockWebServer: MockWebServer
private set
var clientCertificates: HandshakeCertificates? = null
private set
fun start(useHttps: Boolean) {
val mockWebServer = MockWebServer().also { this.mockWebServer = it }
if (useHttps) {
clientCertificates = mockWebServer.useHttps()
}
mockWebServer.dispatcher = networkDispatcher
mockWebServer.start(InetAddress.getLocalHost(), PORT)
}
/**
* Sets AuthScenario to what to return to the Refresh token request
* @param validateArguments if true the request type / body / headers will be verified, otherwise just the path
*/
fun setScenario(authScenario: AuthScenario, validateArguments: Boolean = true) = apply {
networkDispatcher.set(
NetworkDispatcher.ScenarioType.AUTH,
scenarioToRequestScenario.get(authScenario, validateArguments)
)
}
/**
* Sets Scenario to what to return to the Refresh token request
* @param validateArguments if true the request type / body / headers will be verified, otherwise just the path
*/
fun setScenario(refreshTokenScenario: RefreshTokenScenario, validateArguments: Boolean = true) = apply {
networkDispatcher.set(
NetworkDispatcher.ScenarioType.REFRESH,
scenarioToRequestScenario.get(refreshTokenScenario, validateArguments)
)
}
/**
* Sets ContentScenario to what to return to the Refresh token request
* @param validateArguments if true the request type / body / headers will be verified, otherwise just the path
*/
fun setScenario(contentScenario: ContentScenario, validateArguments: Boolean = true) = apply {
networkDispatcher.set(
NetworkDispatcher.ScenarioType.CONTENT,
scenarioToRequestScenario.get(contentScenario, validateArguments)
)
}
fun takeRequest() = mockWebServer.takeRequest()
fun stop() {
mockWebServer.shutdown()
}
companion object {
const val PORT: Int = 7335
val HTTP_BASE_URL get() = "http://${InetAddress.getLocalHost().hostName}"
val HTTPS_BASE_URL get() = "https://localhost"
private fun MockWebServer.useHttps(): HandshakeCertificates {
val localhost = InetAddress.getByName("localhost").canonicalHostName
val localhostCertificate = HeldCertificate.Builder()
.addSubjectAlternativeName(localhost)
.build()
val serverCertificates = HandshakeCertificates.Builder()
.heldCertificate(localhostCertificate)
.build()
useHttps(serverCertificates.sslSocketFactory(), false)
val clientCertificates = HandshakeCertificates.Builder()
.addTrustedCertificate(localhostCertificate.certificate)
.build()
return clientCertificates
}
}
}

View file

@ -0,0 +1,29 @@
package org.fnives.test.showcase.network.mockserver
import okhttp3.mockwebserver.Dispatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.RecordedRequest
import org.fnives.test.showcase.network.mockserver.scenario.RequestScenario
import org.fnives.test.showcase.network.mockserver.scenario.general.NotFoundRequestScenario
internal class NetworkDispatcher : Dispatcher() {
private var scenarios: Map<ScenarioType, RequestScenario> = emptyMap()
override fun dispatch(request: RecordedRequest): MockResponse =
scenarios.values
.asSequence()
.mapNotNull { it.getResponse(request) }
.firstOrNull()
?: NotFoundRequestScenario.getResponse(request)
fun set(type: ScenarioType, scenario: RequestScenario) {
scenarios = scenarios.plus(type to scenario)
}
enum class ScenarioType {
AUTH,
REFRESH,
CONTENT
}
}

View file

@ -0,0 +1,80 @@
package org.fnives.test.showcase.network.mockserver
import org.fnives.test.showcase.network.mockserver.scenario.RequestScenario
import org.fnives.test.showcase.network.mockserver.scenario.RequestScenarioChain
import org.fnives.test.showcase.network.mockserver.scenario.SpecificRequestScenario
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthRequestMatchingChecker
import org.fnives.test.showcase.network.mockserver.scenario.auth.AuthScenario
import org.fnives.test.showcase.network.mockserver.scenario.auth.CreateAuthInvalidCredentialsResponse
import org.fnives.test.showcase.network.mockserver.scenario.auth.CreateAuthSuccessResponse
import org.fnives.test.showcase.network.mockserver.scenario.content.ContentRequestMatchingChecker
import org.fnives.test.showcase.network.mockserver.scenario.content.ContentScenario
import org.fnives.test.showcase.network.mockserver.scenario.content.CreateContentSuccessResponse
import org.fnives.test.showcase.network.mockserver.scenario.content.CreateContentSuccessWithMissingFields
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateGeneralErrorResponse
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateGenericSuccessResponseByJson
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateMalformedJsonSuccessResponse
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateUnauthorizedResponse
import org.fnives.test.showcase.network.mockserver.scenario.general.GenericScenario
import org.fnives.test.showcase.network.mockserver.scenario.refresh.CreateRefreshResponse
import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshRequestMatchingChecker
import org.fnives.test.showcase.network.mockserver.scenario.refresh.RefreshTokenScenario
internal class ScenarioToRequestScenario {
fun get(authScenario: AuthScenario, validateArguments: Boolean): RequestScenario =
wrap(authScenario, ::convert, validateArguments)
fun get(contentScenario: ContentScenario, validateArguments: Boolean): RequestScenario =
wrap(contentScenario, ::convert, validateArguments)
fun get(refreshTokenScenario: RefreshTokenScenario, validateArguments: Boolean): RequestScenario =
wrap(refreshTokenScenario, ::convert, validateArguments)
private fun convert(validateArguments: Boolean, authScenario: AuthScenario): RequestScenario {
val createResponse = when (authScenario) {
is AuthScenario.GenericError -> CreateGeneralErrorResponse()
is AuthScenario.InvalidCredentials -> CreateAuthInvalidCredentialsResponse()
is AuthScenario.Success -> CreateAuthSuccessResponse()
is AuthScenario.MalformedJsonAsSuccessResponse -> CreateMalformedJsonSuccessResponse()
is AuthScenario.UnexpectedJsonAsSuccessResponse -> CreateGenericSuccessResponseByJson("[]")
}
val requestMatchingChecker = AuthRequestMatchingChecker(authScenario, validateArguments)
return SpecificRequestScenario(requestMatchingChecker, createResponse)
}
private fun convert(validateArguments: Boolean, contentScenario: ContentScenario): RequestScenario {
val createResponse = when (contentScenario) {
is ContentScenario.Error -> CreateGeneralErrorResponse()
is ContentScenario.Success -> CreateContentSuccessResponse()
is ContentScenario.SuccessWithMissingFields -> CreateContentSuccessWithMissingFields()
is ContentScenario.Unauthorized -> CreateUnauthorizedResponse()
is ContentScenario.MalformedJsonAsSuccessResponse -> CreateMalformedJsonSuccessResponse()
is ContentScenario.UnexpectedJsonAsSuccessResponse -> CreateGenericSuccessResponseByJson("{}")
}
val requestMatchingChecker = ContentRequestMatchingChecker(contentScenario, validateArguments)
return SpecificRequestScenario(requestMatchingChecker, createResponse)
}
private fun convert(validateArguments: Boolean, refreshTokenScenario: RefreshTokenScenario): RequestScenario {
val contentResponse = when (refreshTokenScenario) {
RefreshTokenScenario.Error -> CreateGeneralErrorResponse()
RefreshTokenScenario.Success -> CreateRefreshResponse()
RefreshTokenScenario.UnexpectedJsonAsSuccessResponse -> CreateGenericSuccessResponseByJson("{}")
RefreshTokenScenario.MalformedJson -> CreateMalformedJsonSuccessResponse()
}
val requestMatchingChecker = RefreshRequestMatchingChecker(validateArguments)
return SpecificRequestScenario(requestMatchingChecker, contentResponse)
}
private fun <T : GenericScenario<T>> wrap(
scenario: T,
convert: (Boolean, T) -> RequestScenario,
validateArguments: Boolean
): RequestScenario {
val requestScenario = convert(validateArguments, scenario)
val previousScenario = scenario.previousScenario ?: return requestScenario
return RequestScenarioChain(current = convert(validateArguments, previousScenario), next = requestScenario)
}
}

View file

@ -0,0 +1,11 @@
package org.fnives.test.showcase.network.mockserver.scenario
import okhttp3.mockwebserver.RecordedRequest
import org.json.JSONException
import kotlin.jvm.Throws
internal interface RequestMatchingChecker {
@Throws(AssertionError::class, JSONException::class)
fun isValidRequest(request: RecordedRequest): Boolean
}

View file

@ -0,0 +1,9 @@
package org.fnives.test.showcase.network.mockserver.scenario
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.RecordedRequest
internal interface RequestScenario {
fun getResponse(request: RecordedRequest): MockResponse?
}

View file

@ -0,0 +1,19 @@
package org.fnives.test.showcase.network.mockserver.scenario
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.RecordedRequest
internal class RequestScenarioChain(
private val current: RequestScenario,
private val next: RequestScenario
) : RequestScenario {
private var isConsumed = false
override fun getResponse(request: RecordedRequest): MockResponse? =
if (isConsumed) {
next.getResponse(request)
} else {
current.getResponse(request)?.also { isConsumed = true }
}
}

View file

@ -0,0 +1,34 @@
package org.fnives.test.showcase.network.mockserver.scenario
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.RecordedRequest
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateResponse
import org.json.JSONException
internal class SpecificRequestScenario(
private val requestMatchingChecker: RequestMatchingChecker,
private val createResponse: CreateResponse
) : RequestScenario {
override fun getResponse(request: RecordedRequest): MockResponse? = wrapExceptionsIntoMockResponse {
if (requestMatchingChecker.isValidRequest(request)) {
createResponse.getResponse()
} else {
null
}
}
private fun wrapExceptionsIntoMockResponse(responseFactory: () -> MockResponse?): MockResponse? =
try {
responseFactory()
} catch (jsonException: JSONException) {
MockResponse().setBody("JSONException while asserting your request, message: ${jsonException.message}")
.setResponseCode(400)
} catch (assertionError: AssertionError) {
MockResponse().setBody("AssertionError while asserting your request, message: ${assertionError.message}")
.setResponseCode(400)
} catch (throwable: Throwable) {
MockResponse().setBody("Unexpected Exception while asserting your request, message: ${throwable.message}")
.setResponseCode(400)
}
}

View file

@ -0,0 +1,39 @@
package org.fnives.test.showcase.network.mockserver.scenario.auth
import okhttp3.mockwebserver.RecordedRequest
import org.fnives.test.showcase.network.mockserver.scenario.RequestMatchingChecker
import org.junit.Assert
import org.skyscreamer.jsonassert.JSONAssert
import org.skyscreamer.jsonassert.JSONCompareMode
internal class AuthRequestMatchingChecker(
private val authScenario: AuthScenario,
private val validateArguments: Boolean
) : RequestMatchingChecker {
override fun isValidRequest(request: RecordedRequest): Boolean {
if (request.path != "/login") return false
if (!validateArguments) return true
Assert.assertEquals("POST", request.method)
Assert.assertEquals("Android", request.getHeader("Platform"))
Assert.assertEquals(null, request.getHeader("Authorization"))
val expectedJson = createExpectedJson(
username = authScenario.username,
password = authScenario.password
)
JSONAssert.assertEquals(expectedJson, request.body.readUtf8(), JSONCompareMode.LENIENT)
return true
}
companion object {
internal fun createExpectedJson(username: String, password: String): String =
"""
{
"username": "$username",
"password": "$password"
}
""".trimIndent()
}
}

View file

@ -0,0 +1,15 @@
package org.fnives.test.showcase.network.mockserver.scenario.auth
import org.fnives.test.showcase.network.mockserver.scenario.general.GenericScenario
sealed class AuthScenario : GenericScenario<AuthScenario>() {
abstract val username: String
abstract val password: String
class Success(override val username: String, override val password: String) : AuthScenario()
class InvalidCredentials(override val username: String, override val password: String) : AuthScenario()
class GenericError(override val username: String, override val password: String) : AuthScenario()
class UnexpectedJsonAsSuccessResponse(override val username: String, override val password: String) : AuthScenario()
class MalformedJsonAsSuccessResponse(override val username: String, override val password: String) : AuthScenario()
}

View file

@ -0,0 +1,10 @@
package org.fnives.test.showcase.network.mockserver.scenario.auth
import okhttp3.mockwebserver.MockResponse
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateResponse
internal class CreateAuthInvalidCredentialsResponse : CreateResponse {
override fun getResponse(): MockResponse =
MockResponse().setResponseCode(400).setBody("{}")
}

View file

@ -0,0 +1,13 @@
package org.fnives.test.showcase.network.mockserver.scenario.auth
import okhttp3.mockwebserver.MockResponse
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateResponse
import org.fnives.test.showcase.network.mockserver.utils.readResourceFile
internal class CreateAuthSuccessResponse : CreateResponse {
override fun getResponse(): MockResponse {
val responseBody = readResourceFile("response/auth/success_response_login.json")
return MockResponse().setResponseCode(200).setBody(responseBody)
}
}

View file

@ -0,0 +1,29 @@
package org.fnives.test.showcase.network.mockserver.scenario.content
import okhttp3.mockwebserver.RecordedRequest
import org.fnives.test.showcase.network.mockserver.ContentData
import org.fnives.test.showcase.network.mockserver.scenario.RequestMatchingChecker
import org.junit.Assert
internal class ContentRequestMatchingChecker(
private val contentScenario: ContentScenario,
private val validateArguments: Boolean
) : RequestMatchingChecker {
override fun isValidRequest(request: RecordedRequest): Boolean {
if (request.path != "/content") return false
if (!validateArguments) return true
Assert.assertEquals("GET", request.method)
Assert.assertEquals("Android", request.getHeader("Platform"))
val expectedToken = if (contentScenario.usingRefreshedToken) {
ContentData.refreshSuccessResponse.accessToken
} else {
ContentData.loginSuccessResponse.accessToken
}
Assert.assertEquals(expectedToken, request.getHeader("Authorization"))
Assert.assertEquals("", request.body.readUtf8())
return true
}
}

View file

@ -0,0 +1,15 @@
package org.fnives.test.showcase.network.mockserver.scenario.content
import org.fnives.test.showcase.network.mockserver.scenario.general.GenericScenario
sealed class ContentScenario : GenericScenario<ContentScenario>() {
abstract val usingRefreshedToken: Boolean
class Success(override val usingRefreshedToken: Boolean) : ContentScenario()
class SuccessWithMissingFields(override val usingRefreshedToken: Boolean) : ContentScenario()
class Unauthorized(override val usingRefreshedToken: Boolean) : ContentScenario()
class Error(override val usingRefreshedToken: Boolean) : ContentScenario()
class UnexpectedJsonAsSuccessResponse(override val usingRefreshedToken: Boolean) : ContentScenario()
class MalformedJsonAsSuccessResponse(override val usingRefreshedToken: Boolean) : ContentScenario()
}

View file

@ -0,0 +1,13 @@
package org.fnives.test.showcase.network.mockserver.scenario.content
import okhttp3.mockwebserver.MockResponse
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateResponse
import org.fnives.test.showcase.network.mockserver.utils.readResourceFile
internal class CreateContentSuccessResponse : CreateResponse {
override fun getResponse(): MockResponse {
val responseBody = readResourceFile("response/content/success_response_content.json")
return MockResponse().setResponseCode(200).setBody(responseBody)
}
}

View file

@ -0,0 +1,13 @@
package org.fnives.test.showcase.network.mockserver.scenario.content
import okhttp3.mockwebserver.MockResponse
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateResponse
import org.fnives.test.showcase.network.mockserver.utils.readResourceFile
internal class CreateContentSuccessWithMissingFields : CreateResponse {
override fun getResponse(): MockResponse {
val responseBody = readResourceFile("response/content/content_missing_field_response.json")
return MockResponse().setResponseCode(200).setBody(responseBody)
}
}

View file

@ -0,0 +1,7 @@
package org.fnives.test.showcase.network.mockserver.scenario.createresponse
import okhttp3.mockwebserver.MockResponse
internal class CreateGeneralErrorResponse : CreateResponse {
override fun getResponse(): MockResponse = MockResponse().setResponseCode(500).setBody("{}")
}

View file

@ -0,0 +1,7 @@
package org.fnives.test.showcase.network.mockserver.scenario.createresponse
import okhttp3.mockwebserver.MockResponse
internal class CreateGenericSuccessResponseByJson(val json: String) : CreateResponse {
override fun getResponse(): MockResponse = MockResponse().setResponseCode(200).setBody(json)
}

View file

@ -0,0 +1,7 @@
package org.fnives.test.showcase.network.mockserver.scenario.createresponse
import okhttp3.mockwebserver.MockResponse
internal class CreateMalformedJsonSuccessResponse : CreateResponse {
override fun getResponse(): MockResponse = MockResponse().setResponseCode(200).setBody("[")
}

View file

@ -0,0 +1,8 @@
package org.fnives.test.showcase.network.mockserver.scenario.createresponse
import okhttp3.mockwebserver.MockResponse
internal interface CreateResponse {
fun getResponse(): MockResponse
}

View file

@ -0,0 +1,8 @@
package org.fnives.test.showcase.network.mockserver.scenario.createresponse
import okhttp3.mockwebserver.MockResponse
internal class CreateUnauthorizedResponse : CreateResponse {
override fun getResponse(): MockResponse =
MockResponse().setResponseCode(401).setBody("{}")
}

View file

@ -0,0 +1,14 @@
package org.fnives.test.showcase.network.mockserver.scenario.general
@Suppress("UnnecessaryAbstractClass")
abstract class GenericScenario<T : GenericScenario<T>> internal constructor() {
internal var previousScenario: T? = null
private set
@Suppress("UNCHECKED_CAST")
fun then(scenario: T): T {
scenario.previousScenario = this as T
return scenario
}
}

View file

@ -0,0 +1,10 @@
package org.fnives.test.showcase.network.mockserver.scenario.general
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.RecordedRequest
import org.fnives.test.showcase.network.mockserver.scenario.RequestScenario
internal object NotFoundRequestScenario : RequestScenario {
override fun getResponse(request: RecordedRequest): MockResponse =
MockResponse().setResponseCode(404).setBody("Not Found")
}

View file

@ -0,0 +1,12 @@
package org.fnives.test.showcase.network.mockserver.scenario.refresh
import okhttp3.mockwebserver.MockResponse
import org.fnives.test.showcase.network.mockserver.scenario.createresponse.CreateResponse
import org.fnives.test.showcase.network.mockserver.utils.readResourceFile
internal class CreateRefreshResponse : CreateResponse {
override fun getResponse(): MockResponse {
val responseBody = readResourceFile("response/refresh/success_response_refresh.json")
return MockResponse().setResponseCode(200).setBody(responseBody)
}
}

View file

@ -0,0 +1,21 @@
package org.fnives.test.showcase.network.mockserver.scenario.refresh
import okhttp3.mockwebserver.RecordedRequest
import org.fnives.test.showcase.network.mockserver.scenario.RequestMatchingChecker
import org.junit.Assert
internal class RefreshRequestMatchingChecker(val validateArguments: Boolean) : RequestMatchingChecker {
override fun isValidRequest(request: RecordedRequest): Boolean {
if (request.path != "/login/login-refresh" && request.path != "/login/refreshed-refresh") {
return false
}
if (!validateArguments) return true
Assert.assertEquals("PUT", request.method)
Assert.assertEquals("Android", request.getHeader("Platform"))
Assert.assertEquals(null, request.getHeader("Authorization"))
Assert.assertEquals("", request.body.readUtf8())
return true
}
}

View file

@ -0,0 +1,10 @@
package org.fnives.test.showcase.network.mockserver.scenario.refresh
import org.fnives.test.showcase.network.mockserver.scenario.general.GenericScenario
sealed class RefreshTokenScenario : GenericScenario<RefreshTokenScenario>() {
object Success : RefreshTokenScenario()
object Error : RefreshTokenScenario()
object UnexpectedJsonAsSuccessResponse : RefreshTokenScenario()
object MalformedJson : RefreshTokenScenario()
}

View file

@ -0,0 +1,20 @@
package org.fnives.test.showcase.network.mockserver.utils
import java.io.BufferedReader
import java.io.InputStreamReader
internal fun Any.readResourceFile(filePath: String): String = try {
BufferedReader(InputStreamReader(this.javaClass.classLoader.getResourceAsStream(filePath)!!))
.readLines().joinToString("\n")
} catch (nullPointerException: NullPointerException) {
throw IllegalArgumentException("$filePath file not found!", nullPointerException)
}
private fun BufferedReader.readLines(): List<String> {
val result = mutableListOf<String>()
use {
do {
readLine()?.let(result::add) ?: return result
} while (true)
}
}

View file

@ -0,0 +1,4 @@
{
"accessToken": "login-access",
"refreshToken": "login-refresh"
}

View file

@ -0,0 +1,13 @@
[
{
"id": "1",
"title": "title_1",
"says": "says_1",
"image": "img_1"
},
{
"id": "2",
"title": "title_2",
"says": "says_2"
}
]

View file

@ -0,0 +1,20 @@
[
{
"id": "1",
"title": "title_1",
"says": "says_1",
"image": "img_1"
},
{
"id": "2",
"title": "title_2",
"says": "says_2",
"image": "img_2"
},
{
"id": "3",
"title": "title_3",
"says": "says_3",
"image": "img_3"
}
]

View file

@ -0,0 +1,4 @@
{
"accessToken": "refreshed-access",
"refreshToken": "refreshed-refresh"
}