commonMain.com.apollographql.apollo.testing.TestNetworkTransport.kt Maven / Gradle / Ivy
package com.apollographql.apollo.testing
import com.apollographql.apollo.ApolloClient
import com.apollographql.apollo.annotations.ApolloExperimental
import com.apollographql.apollo.api.ApolloRequest
import com.apollographql.apollo.api.ApolloResponse
import com.apollographql.apollo.api.Error
import com.apollographql.apollo.api.Operation
import com.apollographql.apollo.exception.ApolloNetworkException
import com.apollographql.apollo.network.NetworkTransport
import com.benasher44.uuid.uuid4
import kotlinx.atomicfu.locks.reentrantLock
import kotlinx.atomicfu.locks.withLock
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.yield
private sealed interface TestResponse {
object NetworkError : TestResponse
class Response(val response: ApolloResponse) : TestResponse
}
@ApolloExperimental
class QueueTestNetworkTransport : NetworkTransport {
private val lock = reentrantLock()
private val queue = ArrayDeque()
override fun execute(request: ApolloRequest): Flow> {
return flow {
// "Emulate" a network call
yield()
val response = lock.withLock { queue.removeFirstOrNull() } ?: error("No more responses in queue")
val apolloResponse = when (response) {
is TestResponse.NetworkError -> {
ApolloResponse.Builder(operation = request.operation, requestUuid = request.requestUuid)
.exception(exception = ApolloNetworkException("Network error queued in QueueTestNetworkTransport"))
.build()
}
is TestResponse.Response -> {
@Suppress("UNCHECKED_CAST")
response.response as ApolloResponse
}
}
emit(apolloResponse.newBuilder().isLast(true).build())
}
}
fun enqueue(response: ApolloResponse) {
lock.withLock {
queue.add(TestResponse.Response(response))
}
}
fun enqueueNetworkError() {
lock.withLock {
queue.add(TestResponse.NetworkError)
}
}
override fun dispose() {}
}
@ApolloExperimental
class MapTestNetworkTransport : NetworkTransport {
private val lock = reentrantLock()
private val operationsToResponses = mutableMapOf, TestResponse>()
override fun execute(request: ApolloRequest): Flow> {
return flow {
// "Emulate" a network call
yield()
val response = lock.withLock { operationsToResponses[request.operation] }
?: error("No response registered for operation ${request.operation}")
val apolloResponse = when (response) {
is TestResponse.NetworkError -> {
ApolloResponse.Builder(operation = request.operation, requestUuid = request.requestUuid)
.exception(exception = ApolloNetworkException("Network error registered in MapTestNetworkTransport"))
.build()
}
is TestResponse.Response -> {
@Suppress("UNCHECKED_CAST")
response.response as ApolloResponse
}
}
emit(apolloResponse.newBuilder().isLast(true).build())
}
}
fun register(operation: Operation, response: ApolloResponse) {
lock.withLock {
operationsToResponses[operation] = TestResponse.Response(response)
}
}
fun registerNetworkError(operation: Operation) {
lock.withLock {
operationsToResponses[operation] = TestResponse.NetworkError
}
}
override fun dispose() {}
}
@ApolloExperimental
fun ApolloClient.enqueueTestResponse(response: ApolloResponse) =
(networkTransport as? QueueTestNetworkTransport)?.enqueue(response)
?: error("Apollo: ApolloClient.enqueueTestResponse() can be used only with QueueTestNetworkTransport")
@ApolloExperimental
fun ApolloClient.enqueueTestResponse(
operation: Operation,
data: D? = null,
errors: List? = null,
) = enqueueTestResponse(
ApolloResponse.Builder(
operation = operation,
requestUuid = uuid4(),
)
.data(data)
.errors(errors)
.build()
)
@ApolloExperimental
fun ApolloClient.enqueueTestNetworkError() =
(networkTransport as? QueueTestNetworkTransport)?.enqueueNetworkError()
?: error("Apollo: ApolloClient.enqueueTestNetworkError() can be used only with QueueTestNetworkTransport")
@ApolloExperimental
fun ApolloClient.registerTestResponse(
operation: Operation,
response: ApolloResponse,
) = (networkTransport as? MapTestNetworkTransport)?.register(operation, response)
?: error("Apollo: ApolloClient.registerTestResponse() can be used only with MapTestNetworkTransport")
@ApolloExperimental
fun ApolloClient.registerTestResponse(
operation: Operation,
data: D? = null,
errors: List? = null,
) = registerTestResponse(
operation,
ApolloResponse.Builder(
operation = operation,
requestUuid = uuid4(),
)
.data(data)
.errors(errors)
.build()
)
@ApolloExperimental
fun ApolloClient.registerTestNetworkError(operation: Operation) =
(networkTransport as? MapTestNetworkTransport)?.registerNetworkError(operation)
?: error("Apollo: ApolloClient.registerTestNetworkError() can be used only with MapTestNetworkTransport")
© 2015 - 2025 Weber Informatics LLC | Privacy Policy