Skip to content

Commit

Permalink
Fixing a bug that was causing that a response with a different method (
Browse files Browse the repository at this point in the history
…#19)

* Fixing a bug that was causing that a response with a different method was returned.

* Commited by mistake
  • Loading branch information
gmerinojimenez authored Jul 19, 2023
1 parent c5882e1 commit e06d83d
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 125 deletions.
116 changes: 0 additions & 116 deletions mock/src/main/java/com/telefonica/mock/MockApiClient.kt

This file was deleted.

8 changes: 4 additions & 4 deletions mock/src/main/java/com/telefonica/mock/MockHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import javax.inject.Inject
class MockHelper(context: Context) {

@Inject
lateinit var mockApiClient: MockApiClient
lateinit var mockApiClient: MockedServer

@Inject
lateinit var fileReader: FileReader
Expand Down Expand Up @@ -66,7 +66,7 @@ class MockResponseBuilderWithRequestInfo(
) {
mockHelper.mockApiClient.enqueue(
requestInfo = requestInfo,
mock = MockedApiResponse(
mockedResponse = MockedApiResponse(
body = body,
httpResponseCode = httpResponseCode,
delayInMillis = delayInMillis,
Expand All @@ -80,7 +80,7 @@ class MockResponseBuilderWithRequestInfo(
) {
mockHelper.mockApiClient.enqueue(
requestInfo = requestInfo,
mock = MockedApiResponse(
mockedResponse = MockedApiResponse(
body = mockHelper.fileReader.readJsonFile(pathFromFile) ?: MockedApiResponse.DEFAULT_BODY,
httpResponseCode = httpResponseCode,
delayInMillis = delayInMillis,
Expand All @@ -95,7 +95,7 @@ class MockResponseBuilderWithRequestInfo(
) {
mockHelper.mockApiClient.enqueue(
requestInfo = requestInfo,
mock = MockedBufferedResponse(
mockedResponse = MockedBufferedResponse(
buffer = mockHelper.fileReader.readRawFile(fileName),
httpResponseCode = httpResponseCode,
delayInMillis = delayInMillis,
Expand Down
68 changes: 68 additions & 0 deletions mock/src/main/java/com/telefonica/mock/MockedServer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.telefonica.mock

import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
import okhttp3.mockwebserver.Dispatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okhttp3.mockwebserver.RecordedRequest
import java.net.InetAddress
import okhttp3.tls.HandshakeCertificates
import okhttp3.tls.HeldCertificate
import javax.inject.Inject

open class MockedServer @Inject constructor(
private val coroutineDispatcher: CoroutineDispatcher,
private val mockWebServer: MockWebServer,
private val responseDispatcher: ResponseDispatcher,
) {

private val dispatcher = object : Dispatcher() {
override fun dispatch(request: RecordedRequest): MockResponse = responseDispatcher.dispatch(
recordedMethod = request.method,
recordedPath = request.path
)
}

internal suspend fun startServer(inetAddress: InetAddress, port: Int = 0) {
withContext(coroutineDispatcher) {
runCatching {
mockWebServer.start(inetAddress = inetAddress, port = port)
}
}
}

fun stopServer() {
mockWebServer.shutdown()
}

suspend fun getBaseUrl(): String = withContext(coroutineDispatcher) {
mockWebServer.url("/").toString()
}

internal fun enqueue(requestInfo: RequestInfo, mockedResponse: MockedResponse) {
responseDispatcher.enqueue(requestInfo, mockedResponse)
}

internal fun setUp(address: InetAddress, enableSsl: Boolean) {
mockWebServer.dispatcher = dispatcher
if (enableSsl) {
enableHttpsFor(mockWebServer, address)
}
}

private fun enableHttpsFor(mockWebServer: MockWebServer, address: InetAddress) {
val serverCertificates = HandshakeCertificates.Builder()
.heldCertificate(buildCertificate(address.canonicalHostName))
.build()
mockWebServer.useHttps(serverCertificates.sslSocketFactory(), false)
}

private fun buildCertificate(altName: String): HeldCertificate = HeldCertificate.Builder()
.addSubjectAlternativeName(altName)
.build()

companion object {
const val RESPONSE_NOT_FOUND_CODE = 404
}
}
49 changes: 49 additions & 0 deletions mock/src/main/java/com/telefonica/mock/ResponseDispatcher.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.telefonica.mock

import android.os.PatternMatcher
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.SocketPolicy
import java.util.*
import java.util.concurrent.*
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ResponseDispatcher @Inject constructor() {

private val responses: MutableMap<RequestInfo, LinkedList<MockedResponse>> = mutableMapOf()

fun dispatch(recordedMethod: String?, recordedPath: String?): MockResponse {
val responseList = responses
.filterKeys { requestInfo -> requestInfo.method.value == recordedMethod && requestInfo.path.toPattern().match(recordedPath) }
.entries
.firstOrNull()
?.value

return when {
responseList.isNullOrEmpty() -> MockResponse().setResponseCode(MockedServer.RESPONSE_NOT_FOUND_CODE)
else -> {
val response = responseList.poll()
responseList.add(response)
when (response) {
is MockedApiResponse -> MockResponse()
.setResponseCode(response.httpResponseCode)
.setBodyDelay(response.delayInMillis, TimeUnit.MILLISECONDS)
.setBody(response.body)
is MockedBufferedResponse -> MockResponse()
.setResponseCode(response.httpResponseCode)
.setBodyDelay(response.delayInMillis, TimeUnit.MILLISECONDS)
.setBody(response.buffer)
.setSocketPolicy(SocketPolicy.DISCONNECT_AT_END)
}
}
}
}

internal fun enqueue(requestInfo: RequestInfo, mockedResponse: MockedResponse) {
val mockListUpdated = (responses[requestInfo] ?: LinkedList()).apply { add(mockedResponse) }
responses[requestInfo] = mockListUpdated
}

private fun Path.toPattern(): PatternMatcher = PatternMatcher(this, PatternMatcher.PATTERN_SIMPLE_GLOB)
}
9 changes: 5 additions & 4 deletions mock/src/main/java/com/telefonica/mock/di/MockApiModule.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.telefonica.mock.di

import android.content.Context
import com.google.gson.Gson
import com.telefonica.mock.MockApiClient
import com.telefonica.mock.MockedServer
import com.telefonica.mock.FileReader
import com.telefonica.mock.ResponseDispatcher
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.Dispatchers
Expand All @@ -25,6 +25,7 @@ class MockApiModule(private val context: Context) {

@Provides
fun provideMockApiClient(
mockWebServer: MockWebServer
): MockApiClient = MockApiClient(Dispatchers.IO, mockWebServer)
mockWebServer: MockWebServer,
responseDispatcher: ResponseDispatcher,
): MockedServer = MockedServer(Dispatchers.IO, mockWebServer, responseDispatcher)
}
5 changes: 4 additions & 1 deletion mock/src/main/java/com/telefonica/mock/models.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.telefonica.mock

import android.os.PatternMatcher
import okio.Buffer

sealed class Method(val value: String) {
Expand Down Expand Up @@ -45,4 +46,6 @@ class MockedBufferedResponse(
internal class RequestAndResponse(val requestInfo: RequestInfo, val mockedResponse: MockedResponse)

data class RequestInfo(val path: Path, val method: Method)
typealias Path=String
typealias Path=String

internal class RequestInfoWithPattern(val pathPattern: PatternMatcher, val method: Method)

0 comments on commit e06d83d

Please sign in to comment.