git.iko.soy/opencode-android
on 8115408 help sign in
66 lines 2.3 kB history raw
1package soy.iko.opencode.data.network
3import io.ktor.client.HttpClient
4import io.ktor.client.engine.mock.MockEngine
5import io.ktor.client.engine.mock.respond
6import io.ktor.client.engine.mock.respondError
7import io.ktor.client.plugins.ClientRequestException
8import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
9import io.ktor.http.HttpStatusCode
10import io.ktor.http.headersOf
11import io.ktor.serialization.kotlinx.json.json
12import kotlinx.coroutines.test.runTest
13import org.junit.Assert.assertEquals
14import org.junit.Assert.assertTrue
15import org.junit.Test
16import soy.iko.opencode.data.model.PermissionResponse
17import java.io.IOException
19class OpencodeApiClientTest {
21 private fun makeClient(engine: MockEngine): HttpClient =
22 HttpClient(engine) {
23 expectSuccess = true
24 install(ContentNegotiation) { json(OpencodeJson) }
25 }
27 @Test
28 fun respondPermissionRetriesOnTransientFailure() = runTest {
29 var calls = 0
30 val engine = MockEngine {
31 calls++
32 if (calls < 3) throw IOException("transient")
33 respond("", HttpStatusCode.OK, headersOf("Content-Length", "0"))
34 }
35 val api = OpencodeApiClient(makeClient(engine))
36 api.respondPermission("s1", "p1", PermissionResponse.ALWAYS)
37 assertEquals("transient failures should be retried", 3, calls)
38 }
40 @Test
41 fun respondPermissionDoesNotRetryClientError() = runTest {
42 var calls = 0
43 val engine = MockEngine {
44 calls++
45 respondError(HttpStatusCode.BadRequest)
46 }
47 val api = OpencodeApiClient(makeClient(engine))
48 val error = runCatching {
49 api.respondPermission("s1", "p1", PermissionResponse.REJECT)
50 }.exceptionOrNull()!!
51 assertEquals("4xx must not be retried", 1, calls)
52 assertTrue("expected ClientRequestException, got $error", error is ClientRequestException)
53 }
55 @Test
56 fun respondPermissionSucceedsOnFirstTry() = runTest {
57 var calls = 0
58 val engine = MockEngine {
59 calls++
60 respond("", HttpStatusCode.OK, headersOf("Content-Length", "0"))
61 }
62 val api = OpencodeApiClient(makeClient(engine))
63 api.respondPermission("s1", "p1", PermissionResponse.ONCE)
64 assertEquals(1, calls)
65 }