2018-01-21 13:46:36 +01:00
|
|
|
@file:Suppress("MemberVisibilityCanBePrivate")
|
|
|
|
|
2018-01-12 10:01:25 +01:00
|
|
|
package jp.juggler.subwaytooter.api
|
|
|
|
|
2023-01-15 08:51:13 +01:00
|
|
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
2021-10-28 01:37:39 +02:00
|
|
|
import androidx.test.platform.app.InstrumentationRegistry
|
2020-02-04 03:04:07 +01:00
|
|
|
import jp.juggler.subwaytooter.api.entity.Host
|
2019-10-08 23:57:21 +02:00
|
|
|
import jp.juggler.subwaytooter.api.entity.TootInstance
|
2018-01-13 07:15:52 +01:00
|
|
|
import jp.juggler.subwaytooter.table.SavedAccount
|
2023-01-15 08:51:13 +01:00
|
|
|
import jp.juggler.subwaytooter.testutil.MainDispatcherRule
|
2018-01-12 10:01:25 +01:00
|
|
|
import jp.juggler.subwaytooter.util.SimpleHttpClient
|
2023-01-14 11:19:01 +01:00
|
|
|
import jp.juggler.util.data.JsonObject
|
|
|
|
import jp.juggler.util.data.buildJsonArray
|
|
|
|
import jp.juggler.util.data.buildJsonObject
|
|
|
|
import jp.juggler.util.log.LogCategory
|
|
|
|
import jp.juggler.util.network.MEDIA_TYPE_JSON
|
2023-01-15 08:51:13 +01:00
|
|
|
import kotlinx.coroutines.test.runTest
|
2018-01-12 10:01:25 +01:00
|
|
|
import okhttp3.*
|
2020-12-11 22:25:45 +01:00
|
|
|
import okhttp3.MediaType.Companion.toMediaType
|
|
|
|
import okhttp3.ResponseBody.Companion.toResponseBody
|
2018-01-12 10:01:25 +01:00
|
|
|
import okio.Buffer
|
|
|
|
import okio.BufferedSource
|
2018-01-13 07:15:52 +01:00
|
|
|
import okio.ByteString
|
2018-01-12 10:01:25 +01:00
|
|
|
import org.junit.Assert.*
|
2023-01-15 08:51:13 +01:00
|
|
|
import org.junit.Rule
|
2018-01-12 10:01:25 +01:00
|
|
|
import org.junit.Test
|
|
|
|
import org.junit.runner.RunWith
|
2021-05-11 08:12:43 +02:00
|
|
|
import java.util.concurrent.atomic.AtomicReference
|
2018-01-12 10:01:25 +01:00
|
|
|
|
2018-01-13 07:15:52 +01:00
|
|
|
@Suppress("MemberVisibilityCanPrivate")
|
2018-01-12 10:01:25 +01:00
|
|
|
@RunWith(AndroidJUnit4::class)
|
|
|
|
class TestTootApiClient {
|
2023-01-15 08:51:13 +01:00
|
|
|
|
|
|
|
// テスト毎に書くと複数テストで衝突するので、MainDispatcherRuleに任せる
|
|
|
|
// プロパティは記述順に初期化されることに注意
|
|
|
|
@get:Rule
|
|
|
|
val mainDispatcherRule = MainDispatcherRule()
|
|
|
|
|
2023-01-14 11:19:01 +01:00
|
|
|
companion object {
|
|
|
|
private val log = LogCategory("TestTootApiClient")
|
|
|
|
}
|
2020-12-11 22:25:45 +01:00
|
|
|
|
2021-10-28 01:37:39 +02:00
|
|
|
private val appContext = InstrumentationRegistry.getInstrumentation().targetContext!!
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
class SimpleHttpClientMock(
|
2021-10-28 01:37:39 +02:00
|
|
|
private val responseGenerator: (request: Request) -> Response,
|
2023-01-14 11:19:01 +01:00
|
|
|
val webSocketGenerator: (request: Request, ws_listener: WebSocketListener) -> WebSocket,
|
2021-10-28 01:37:39 +02:00
|
|
|
) : SimpleHttpClient {
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
override var onCallCreated: (Call) -> Unit = {}
|
|
|
|
|
|
|
|
// override var currentCallCallback : CurrentCallCallback? = null
|
|
|
|
|
2021-10-28 01:37:39 +02:00
|
|
|
override suspend fun getResponse(
|
|
|
|
request: Request,
|
2023-01-14 11:19:01 +01:00
|
|
|
tmpOkhttpClient: OkHttpClient?,
|
2021-10-28 01:37:39 +02:00
|
|
|
): Response {
|
2020-12-11 22:25:45 +01:00
|
|
|
return responseGenerator(request)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getWebSocket(
|
2021-10-28 01:37:39 +02:00
|
|
|
request: Request,
|
2023-01-14 11:19:01 +01:00
|
|
|
webSocketListener: WebSocketListener,
|
2021-10-28 01:37:39 +02:00
|
|
|
): WebSocket {
|
2020-12-11 22:25:45 +01:00
|
|
|
return webSocketGenerator(request, webSocketListener)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-28 01:37:39 +02:00
|
|
|
private fun <T> assertOneOf(actual: T?, vararg expect: T?) {
|
|
|
|
if (!expect.any { it == actual }) {
|
|
|
|
fail("actual=$actual, expected = one of [${expect.joinToString(", ")}]")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun assertParsingResponse(callback: ProgressRecordTootApiCallback) {
|
|
|
|
assertOneOf(
|
|
|
|
callback.progressString,
|
|
|
|
"Parsing response…",
|
|
|
|
"応答の解析中…"
|
|
|
|
)
|
|
|
|
}
|
2023-01-14 11:19:01 +01:00
|
|
|
|
|
|
|
private fun assertReading(
|
|
|
|
callback: ProgressRecordTootApiCallback,
|
|
|
|
@Suppress("SameParameterValue")
|
|
|
|
path: String,
|
|
|
|
) {
|
2021-10-28 01:37:39 +02:00
|
|
|
assertOneOf(
|
|
|
|
callback.progressString,
|
|
|
|
"Reading: GET $path",
|
|
|
|
"読込中: GET $path",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-12-11 22:25:45 +01:00
|
|
|
private fun requestBodyString(request: Request?): String? {
|
|
|
|
try {
|
|
|
|
val copyBody = request?.newBuilder()?.build()?.body ?: return null
|
|
|
|
val buffer = Buffer()
|
|
|
|
copyBody.writeTo(buffer)
|
|
|
|
return buffer.readUtf8()
|
|
|
|
} catch (ex: Throwable) {
|
2023-01-14 11:19:01 +01:00
|
|
|
log.e(ex, "requestBodyString failed.")
|
2020-12-11 22:25:45 +01:00
|
|
|
return null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun createHttpClientNormal(): SimpleHttpClient {
|
|
|
|
return SimpleHttpClientMock(
|
2021-10-28 01:37:39 +02:00
|
|
|
responseGenerator = { request: Request ->
|
|
|
|
|
|
|
|
val bodyString = requestBodyString(request)
|
|
|
|
|
|
|
|
when (request.url.encodedPath) {
|
|
|
|
|
|
|
|
// クライアント登録
|
|
|
|
"/api/v1/apps" -> Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(
|
|
|
|
"""{"id":999,"redirect_uri":"urn:ietf:wg:oauth:2.0:oob","client_id":"DUMMY_ID","client_secret":"DUMMY_SECRET"}"""
|
|
|
|
.toResponseBody(MEDIA_TYPE_JSON)
|
|
|
|
)
|
|
|
|
.build()
|
|
|
|
|
|
|
|
// client credentialの検証
|
|
|
|
"/api/v1/apps/verify_credentials" -> Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(
|
|
|
|
"""{"id":999,"redirect_uri":"urn:ietf:wg:oauth:2.0:oob","client_id":"DUMMY_ID","client_secret":"DUMMY_SECRET"}"""
|
|
|
|
.toResponseBody(MEDIA_TYPE_JSON)
|
|
|
|
)
|
|
|
|
.build()
|
|
|
|
|
|
|
|
"/oauth/token" -> when {
|
|
|
|
// client credential の作成
|
|
|
|
bodyString?.contains("grant_type=client_credentials") == true -> {
|
|
|
|
Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(
|
|
|
|
"""{"access_token":"DUMMY_CLIENT_CREDENTIAL"}""".toResponseBody(
|
|
|
|
MEDIA_TYPE_JSON
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.build()
|
|
|
|
}
|
|
|
|
// アクセストークンの作成
|
|
|
|
bodyString?.contains("grant_type=authorization_code") == true -> {
|
|
|
|
Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(
|
|
|
|
"""{"access_token":"DUMMY_ACCESS_TOKEN"}""".toResponseBody(
|
|
|
|
MEDIA_TYPE_JSON
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.build()
|
|
|
|
}
|
|
|
|
|
|
|
|
else -> {
|
|
|
|
createResponseErrorCode()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// ログインユーザの情報
|
|
|
|
"/api/v1/accounts/verify_credentials" -> {
|
|
|
|
val instance = request.url.host
|
|
|
|
val account1Json = JsonObject()
|
|
|
|
account1Json.apply {
|
|
|
|
put("username", "user1")
|
|
|
|
put("acct", "user1")
|
|
|
|
put("id", 1L)
|
|
|
|
put("url", "http://$instance/@user1")
|
|
|
|
}
|
|
|
|
|
|
|
|
Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(account1Json.toString().toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
}
|
|
|
|
// インスタンス情報
|
|
|
|
"/api/v1/instance" -> Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(JsonObject().apply {
|
|
|
|
put("uri", "http://${request.url.host}/")
|
|
|
|
put("title", "dummy instance")
|
|
|
|
put("description", "dummy description")
|
|
|
|
put("version", "0.0.1")
|
|
|
|
}.toString().toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
// 公開タイムライン
|
|
|
|
"/api/v1/timelines/public" -> {
|
|
|
|
val instance = request.url.host
|
|
|
|
|
|
|
|
val username = "user1"
|
|
|
|
|
|
|
|
val account1Json = JsonObject()
|
|
|
|
account1Json.apply {
|
|
|
|
put("username", username)
|
|
|
|
put("acct", username)
|
|
|
|
put("id", 1L)
|
|
|
|
put("url", "http://$instance/@$username")
|
|
|
|
}
|
|
|
|
|
2023-01-14 11:19:01 +01:00
|
|
|
val array = buildJsonArray {
|
2021-10-28 01:37:39 +02:00
|
|
|
for (i in 0 until 10) {
|
2023-01-14 11:19:01 +01:00
|
|
|
add(buildJsonObject {
|
2021-10-28 01:37:39 +02:00
|
|
|
put("account", account1Json)
|
|
|
|
put("id", i.toLong())
|
|
|
|
put("uri", "https://$instance/@$username/$i")
|
|
|
|
put("url", "https://$instance/@$username/$i")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(array.toString().toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
}
|
|
|
|
|
2023-01-15 08:51:13 +01:00
|
|
|
"/api/meta" -> Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(404)
|
|
|
|
.message("not found")
|
|
|
|
.body("""{"error":"404 not found"}""".toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
else -> Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(request.url.toString().toResponseBody(mediaTypeTextPlain))
|
|
|
|
.build()
|
2021-10-28 01:37:39 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
webSocketGenerator = { request: Request, _: WebSocketListener ->
|
|
|
|
object : WebSocket {
|
|
|
|
override fun queueSize(): Long = 4096L
|
|
|
|
|
|
|
|
override fun send(text: String): Boolean = true
|
|
|
|
|
|
|
|
override fun send(bytes: ByteString): Boolean = true
|
|
|
|
|
|
|
|
override fun close(code: Int, reason: String?): Boolean = true
|
|
|
|
|
|
|
|
override fun cancel() = Unit
|
|
|
|
|
|
|
|
override fun request(): Request = request
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private fun createHttpClientNotImplemented(): SimpleHttpClient {
|
|
|
|
return SimpleHttpClientMock(
|
2021-10-28 01:37:39 +02:00
|
|
|
responseGenerator = { throw NotImplementedError() },
|
|
|
|
webSocketGenerator = { _, _ -> throw NotImplementedError() }
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
class ProgressRecordTootApiCallback : TootApiCallback {
|
|
|
|
|
|
|
|
var cancelled: Boolean = false
|
|
|
|
|
|
|
|
var progressString: String? = null
|
|
|
|
|
2023-01-14 11:19:01 +01:00
|
|
|
override suspend fun isApiCancelled(): Boolean {
|
|
|
|
return cancelled
|
|
|
|
}
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
override suspend fun publishApiProgress(s: String) {
|
|
|
|
progressString = s
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private val requestSimple: Request = Request.Builder().url("https://dummy-url.net/").build()
|
|
|
|
|
|
|
|
private val strJsonOk = """{"a":"A!"}"""
|
|
|
|
private val strJsonError = """{"error":"Error!"}"""
|
|
|
|
private fun createResponseOk() = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(strJsonOk.toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
private fun createResponseOkButJsonError() = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(strJsonError.toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
private fun createResponseErrorCode() = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(500)
|
|
|
|
.message("status-message")
|
|
|
|
.body(strJsonError.toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
private fun createResponseEmptyBody(code: Int = 200) = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(code)
|
|
|
|
.message("status-message")
|
|
|
|
.body("".toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
private fun createResponseWithoutBody() = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
// without body
|
|
|
|
.build()
|
|
|
|
|
|
|
|
private fun createResponseExceptionBody() = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(
|
2021-10-28 01:37:39 +02:00
|
|
|
object : ResponseBody() {
|
|
|
|
override fun contentLength() = 10L
|
|
|
|
override fun contentType(): MediaType = MEDIA_TYPE_JSON
|
|
|
|
override fun source(): BufferedSource = error("ExceptionBody")
|
|
|
|
}
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
.build()
|
|
|
|
|
|
|
|
private val strJsonArray1 = """["A!"]"""
|
|
|
|
private val strJsonArray2 = """ [ "A!" ] """
|
|
|
|
private val strJsonObject2 = """ { "a" : "A!" } """
|
|
|
|
private val strPlainText = "Hello!"
|
|
|
|
|
|
|
|
private fun createResponseJsonArray1() = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(strJsonArray1.toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
private fun createResponseJsonArray2() = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(strJsonArray2.toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
private fun createResponseJsonObject2() = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(strJsonObject2.toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
private val mediaTypeTextPlain = "text/plain".toMediaType()
|
|
|
|
private val mediaTypeHtml = "text/html".toMediaType()
|
|
|
|
|
|
|
|
private fun createResponsePlainText() = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(200)
|
|
|
|
.message("status-message")
|
|
|
|
.body(strPlainText.toResponseBody(mediaTypeTextPlain))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testSimplifyErrorHtml() {
|
|
|
|
var request: Request
|
|
|
|
var response: Response
|
|
|
|
var message: String
|
|
|
|
|
|
|
|
// json error
|
|
|
|
response = createResponseErrorCode()
|
2021-05-11 08:12:43 +02:00
|
|
|
message = TootApiClient.simplifyErrorHtml(response)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("Error!", message)
|
|
|
|
|
|
|
|
// HTML error
|
|
|
|
|
|
|
|
response = Response.Builder()
|
|
|
|
.request(requestSimple)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(500)
|
|
|
|
.message("This is test")
|
|
|
|
.body("""<html><body>Error!</body></html>""".toResponseBody(mediaTypeHtml))
|
|
|
|
.build()
|
|
|
|
|
2021-05-11 08:12:43 +02:00
|
|
|
message = TootApiClient.simplifyErrorHtml(response)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("Error!", message)
|
|
|
|
|
|
|
|
// other error
|
|
|
|
request = Request.Builder()
|
|
|
|
.url("https://dummy-url.net/")
|
|
|
|
.build()
|
|
|
|
|
|
|
|
response = Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(500)
|
|
|
|
.message("This is test")
|
|
|
|
.body("Error!".toResponseBody("text/plain".toMediaType()))
|
|
|
|
.build()
|
|
|
|
|
2021-10-28 01:37:39 +02:00
|
|
|
message = TootApiClient.simplifyErrorHtml(response)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("Error!", message)
|
|
|
|
|
|
|
|
// empty body
|
|
|
|
request = Request.Builder()
|
|
|
|
.url("https://dummy-url.net/")
|
|
|
|
.build()
|
|
|
|
|
|
|
|
response = Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(500)
|
|
|
|
.message("This is test")
|
|
|
|
.body("".toResponseBody("text/plain".toMediaType()))
|
|
|
|
.build()
|
|
|
|
|
2021-10-28 01:37:39 +02:00
|
|
|
message = TootApiClient.simplifyErrorHtml(response = response, caption = "caption")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("", message)
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testFormatResponse() {
|
|
|
|
|
|
|
|
var request: Request
|
|
|
|
var response: Response
|
|
|
|
var bodyString: String?
|
|
|
|
var message: String
|
|
|
|
|
|
|
|
// without response body
|
|
|
|
request = Request.Builder()
|
|
|
|
.url("https://dummy-url.net/")
|
|
|
|
.build()
|
|
|
|
|
|
|
|
response = Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(500)
|
|
|
|
.message("This is test")
|
|
|
|
.build()
|
|
|
|
|
2021-10-28 01:37:39 +02:00
|
|
|
message = TootApiClient.formatResponse(response, "caption")
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
assertEquals("(HTTP 500 This is test) caption", message)
|
|
|
|
|
|
|
|
// json error
|
|
|
|
request = Request.Builder()
|
|
|
|
.url("https://dummy-url.net/")
|
|
|
|
.build()
|
|
|
|
|
|
|
|
response = Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(500)
|
|
|
|
.message("status-message")
|
|
|
|
.body("""{"error":"Error!"}""".toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
2021-10-28 01:37:39 +02:00
|
|
|
message = TootApiClient.formatResponse(response, "caption")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("Error! (HTTP 500 status-message) caption", message)
|
|
|
|
|
|
|
|
// json error (after reading body)
|
|
|
|
|
|
|
|
request = Request.Builder()
|
|
|
|
.url("https://dummy-url.net/")
|
|
|
|
.build()
|
|
|
|
|
|
|
|
response = Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(500)
|
|
|
|
.message("status-message")
|
|
|
|
.body("""{"error":"Error!"}""".toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
bodyString = response.body?.string()
|
|
|
|
|
2021-10-28 01:37:39 +02:00
|
|
|
message = TootApiClient.formatResponse(response, "caption", bodyString)
|
|
|
|
assertEquals("(HTTP 500 status-message) caption", message)
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
// without status message
|
|
|
|
request = Request.Builder()
|
|
|
|
.url("https://dummy-url.net/")
|
|
|
|
.build()
|
|
|
|
|
|
|
|
response = Response.Builder()
|
|
|
|
.request(request)
|
|
|
|
.protocol(Protocol.HTTP_1_1)
|
|
|
|
.code(500)
|
|
|
|
.message("")
|
|
|
|
.body("""{"error":"Error!"}""".toResponseBody(MEDIA_TYPE_JSON))
|
|
|
|
.build()
|
|
|
|
|
|
|
|
bodyString = response.body?.string()
|
|
|
|
|
2021-10-28 01:37:39 +02:00
|
|
|
message = TootApiClient.formatResponse(
|
|
|
|
response = response,
|
|
|
|
caption = "caption",
|
|
|
|
bodyString = bodyString
|
|
|
|
)
|
|
|
|
assertEquals("(HTTP 500) caption", message)
|
2020-12-11 22:25:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testIsApiCancelled() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2020-12-11 22:25:45 +01:00
|
|
|
var flag = 0
|
|
|
|
var progressString: String? = null
|
|
|
|
var progressValue: Int? = null
|
|
|
|
var progressMax: Int? = null
|
|
|
|
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNotImplemented(),
|
|
|
|
callback = object : TootApiCallback {
|
2023-01-14 11:19:01 +01:00
|
|
|
override suspend fun isApiCancelled(): Boolean {
|
|
|
|
++flag
|
|
|
|
return true
|
|
|
|
}
|
2021-10-28 01:37:39 +02:00
|
|
|
|
|
|
|
override suspend fun publishApiProgress(s: String) {
|
|
|
|
++flag
|
|
|
|
progressString = s
|
|
|
|
}
|
|
|
|
|
|
|
|
override suspend fun publishApiProgressRatio(value: Int, max: Int) {
|
|
|
|
++flag
|
|
|
|
progressValue = value
|
|
|
|
progressMax = max
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
2023-01-14 11:19:01 +01:00
|
|
|
val isApiCancelled = client.isApiCancelled()
|
2020-12-11 22:25:45 +01:00
|
|
|
client.publishApiProgress("testing")
|
|
|
|
client.publishApiProgressRatio(50, 100)
|
|
|
|
assertEquals(3, flag)
|
|
|
|
assertEquals(true, isApiCancelled)
|
|
|
|
assertEquals("testing", progressString)
|
|
|
|
assertEquals(50, progressValue)
|
|
|
|
assertEquals(100, progressMax)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testSendRequest() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
val callback = ProgressRecordTootApiCallback()
|
|
|
|
|
|
|
|
// 正常ケースではResponseが返ってくること
|
|
|
|
run {
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val bOk = client.sendRequest(result) { requestSimple }
|
|
|
|
assertEquals(true, bOk)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertOneOf(
|
|
|
|
callback.progressString,
|
|
|
|
"Acquiring: GET /",
|
|
|
|
"取得中: GET /",
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals(null, result.error)
|
|
|
|
assertNotNull(result.response)
|
|
|
|
}
|
|
|
|
|
|
|
|
// httpClient.getResponseが例外を出す場合に対応できること
|
|
|
|
run {
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNotImplemented(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val bOk = client.sendRequest(result) { requestSimple }
|
|
|
|
assertEquals(false, bOk)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertOneOf(
|
|
|
|
callback.progressString,
|
|
|
|
"Acquiring: GET /",
|
|
|
|
"取得中: GET /",
|
|
|
|
)
|
|
|
|
assertOneOf(
|
|
|
|
result.error,
|
|
|
|
"instance: Network error.: NotImplementedError An operation is not implemented.",
|
|
|
|
"instance: 通信エラー。: NotImplementedError An operation is not implemented.",
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertNull(result.response)
|
|
|
|
}
|
|
|
|
|
|
|
|
// progressPath を指定したらpublishApiProgressに渡されること
|
|
|
|
run {
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val bOk = client.sendRequest(result, progressPath = "XXX") { requestSimple }
|
|
|
|
assertEquals(true, bOk)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertOneOf(
|
|
|
|
callback.progressString,
|
|
|
|
"Acquiring: GET XXX",
|
|
|
|
"取得中: GET XXX",
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals(null, result.error)
|
|
|
|
assertNotNull(result.response)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testReadBodyString() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2020-12-11 22:25:45 +01:00
|
|
|
val callback = ProgressRecordTootApiCallback()
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
// キャンセルされてたらnullを返すこと
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseOk()
|
|
|
|
callback.progressString = null
|
|
|
|
callback.cancelled = true
|
|
|
|
val bodyString = client.readBodyString(result)
|
|
|
|
callback.cancelled = false
|
|
|
|
assertNull(bodyString)
|
|
|
|
assertNull(result.bodyString)
|
|
|
|
assertNull(result.data)
|
|
|
|
assertNull(result.error)
|
|
|
|
assertNull(callback.progressString)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 正常ケースなら progressを更新してbodyStringを返す
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseOk()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val bodyString = client.readBodyString(result)
|
|
|
|
assertEquals(strJsonOk, bodyString)
|
|
|
|
assertEquals(strJsonOk, result.bodyString)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertParsingResponse(callback)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertNull(result.error)
|
|
|
|
assertNull(result.data)
|
|
|
|
}
|
|
|
|
|
|
|
|
// レスポンスコードがエラーなら
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseErrorCode()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val bodyString = client.readBodyString(result)
|
|
|
|
assertEquals(null, bodyString)
|
|
|
|
assertEquals(null, result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("Error! (HTTP 500 status-message) instance", result.error)
|
|
|
|
assertNull(result.data)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ボディが空なら
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseEmptyBody()
|
|
|
|
callback.progressString = null
|
|
|
|
val bodyString = client.readBodyString(result)
|
|
|
|
assertEquals("", bodyString)
|
|
|
|
assertEquals("", result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals(null, result.error)
|
|
|
|
assertNull(result.data)
|
|
|
|
}
|
|
|
|
// ボディがnullなら
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseWithoutBody()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val bodyString = client.readBodyString(result)
|
|
|
|
assertEquals("", bodyString)
|
|
|
|
assertEquals("", result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals(null, result.error)
|
|
|
|
assertNull(result.data)
|
|
|
|
}
|
|
|
|
|
|
|
|
// string() が例外
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseExceptionBody()
|
|
|
|
|
|
|
|
var catched: Throwable? = null
|
|
|
|
val bodyString = try {
|
|
|
|
client.readBodyString(result)
|
|
|
|
} catch (ex: Throwable) {
|
|
|
|
ex.printStackTrace()
|
|
|
|
catched = ex
|
|
|
|
null
|
|
|
|
}
|
|
|
|
assertEquals(null, bodyString)
|
|
|
|
assertNotNull(catched)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testParseString() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
val callback = ProgressRecordTootApiCallback()
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
// キャンセルされてたらnullを返すこと
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseOk()
|
|
|
|
callback.progressString = null
|
|
|
|
callback.cancelled = true
|
|
|
|
val r2 = client.parseString(result)
|
|
|
|
callback.cancelled = false
|
|
|
|
assertNull(r2)
|
|
|
|
assertNull(result.bodyString)
|
|
|
|
assertNull(result.data)
|
|
|
|
assertNull(result.error)
|
|
|
|
assertNull(callback.progressString)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 正常ケースなら progressを更新してbodyStringを返す
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseOk()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseString(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(strJsonOk, result.string)
|
|
|
|
assertEquals(strJsonOk, result.bodyString)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertParsingResponse(callback)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertNull(result.error)
|
|
|
|
}
|
|
|
|
// 正常レスポンスならJSONにエラーがあってもreadStringは関知しない
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseOkButJsonError()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseString(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(strJsonError, result.string)
|
|
|
|
assertEquals(strJsonError, result.bodyString)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertParsingResponse(callback)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertNull(result.error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// レスポンスコードがエラーなら
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseErrorCode()
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseString(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(null, result.string)
|
|
|
|
assertEquals(null, result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("Error! (HTTP 500 status-message) instance", result.error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ボディが空で応答コードがエラーなら
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseEmptyBody(code = 404)
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseString(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(null, result.string)
|
|
|
|
assertEquals(null, result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("(no information) (HTTP 404 status-message) instance", result.error)
|
|
|
|
assertNull(result.data)
|
|
|
|
}
|
|
|
|
// ボディがnullでも応答コードが成功ならエラーではない
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseWithoutBody()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseString(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals("", result.string)
|
|
|
|
assertEquals("", result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals(null, result.error)
|
|
|
|
assertEquals("", result.data)
|
|
|
|
}
|
|
|
|
|
|
|
|
// string() が例外
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseExceptionBody()
|
|
|
|
val r2 = client.parseString(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(null, result.string)
|
|
|
|
assertEquals(null, result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("(no information) (HTTP 200 status-message) instance", result.error)
|
|
|
|
assertNull(result.data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testParseJson() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2020-12-11 22:25:45 +01:00
|
|
|
val callback = ProgressRecordTootApiCallback()
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
// キャンセルされてたらnullを返すこと
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseOk()
|
|
|
|
callback.progressString = null
|
|
|
|
callback.cancelled = true
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
callback.cancelled = false
|
|
|
|
assertNull(r2)
|
|
|
|
assertNull(result.bodyString)
|
|
|
|
assertNull(result.data)
|
|
|
|
assertNull(result.error)
|
|
|
|
assertNull(callback.progressString)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 正常ケースなら progressを更新してbodyStringを返す
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseOk()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals("A!", result.jsonObject?.optString("a"))
|
|
|
|
assertEquals(strJsonOk, result.bodyString)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertParsingResponse(callback)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertNull(result.error)
|
|
|
|
}
|
|
|
|
// 正常ケースでもjsonデータにerror項目があれば
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseOkButJsonError()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(null, result.data)
|
|
|
|
assertEquals(strJsonError, result.bodyString)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertParsingResponse(callback)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("Error!", result.error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// レスポンスコードがエラーなら
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseErrorCode()
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(null, result.data)
|
|
|
|
assertEquals(null, result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("Error! (HTTP 500 status-message) instance", result.error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ボディが空なら
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseEmptyBody()
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(0, result.jsonObject?.size)
|
|
|
|
assertEquals("", result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals(null, result.error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ボディがnullなら
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseWithoutBody()
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(0, result.jsonObject?.size)
|
|
|
|
assertEquals("", result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals(null, result.error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// string() が例外
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseExceptionBody()
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(null, result.data)
|
|
|
|
assertEquals(null, result.bodyString)
|
2023-01-14 11:19:01 +01:00
|
|
|
assertReading(callback, "instance")
|
2020-12-11 22:25:45 +01:00
|
|
|
assertEquals("(no information) (HTTP 200 status-message) instance", result.error)
|
|
|
|
assertNull(result.data)
|
|
|
|
}
|
|
|
|
|
|
|
|
// JSON Arrayを処理する
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseJsonArray1()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals("A!", result.jsonArray?.optString(0))
|
|
|
|
assertEquals(strJsonArray1, result.bodyString)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertParsingResponse(callback)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertNull(result.error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 空白が余計に入ってるJSON Arrayを処理する
|
|
|
|
run {
|
|
|
|
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseJsonArray2()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals("A!", result.jsonArray?.optString(0))
|
|
|
|
assertEquals(strJsonArray2, result.bodyString)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertParsingResponse(callback)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertNull(result.error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 空白が余計に入ってるJSON Objectを処理する
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponseJsonObject2()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals("A!", result.jsonObject?.optString("a"))
|
|
|
|
assertEquals(strJsonObject2, result.bodyString)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertParsingResponse(callback)
|
2020-12-11 22:25:45 +01:00
|
|
|
assertNull(result.error)
|
|
|
|
}
|
|
|
|
// JSONじゃない
|
|
|
|
run {
|
|
|
|
val result = TootApiResult.makeWithCaption("instance")
|
|
|
|
assertEquals(null, result.error)
|
|
|
|
result.response = createResponsePlainText()
|
|
|
|
|
|
|
|
callback.progressString = null
|
|
|
|
val r2 = client.parseJson(result)
|
|
|
|
assertNotNull(r2)
|
|
|
|
assertEquals(null, result.data)
|
|
|
|
assertEquals(strPlainText, result.bodyString)
|
2021-10-28 01:37:39 +02:00
|
|
|
assertParsingResponse(callback)
|
|
|
|
assertOneOf(
|
|
|
|
result.error,
|
|
|
|
"API response is not JSON. Hello! (HTTP 200 status-message) https://dummy-url.net/",
|
|
|
|
"APIの応答がJSONではありません Hello! (HTTP 200 status-message) https://dummy-url.net/",
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testRegisterClient() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2020-12-11 22:25:45 +01:00
|
|
|
val callback = ProgressRecordTootApiCallback()
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
val instance = Host.parse("unit-test")
|
|
|
|
client.apiHost = instance
|
|
|
|
val clientName = "SubwayTooterUnitTest"
|
|
|
|
val scope_string = "read+write+follow+push"
|
|
|
|
|
|
|
|
// まずクライアント情報を作らないとcredentialのテストができない
|
|
|
|
var result = client.registerClient(scope_string, clientName)
|
|
|
|
assertNotNull(result)
|
|
|
|
assertEquals(null, result?.error)
|
|
|
|
var jsonObject = result?.jsonObject
|
|
|
|
assertNotNull(jsonObject)
|
2023-01-15 08:51:13 +01:00
|
|
|
if (jsonObject == null) return@runTest
|
2020-12-11 22:25:45 +01:00
|
|
|
val clientInfo = jsonObject
|
|
|
|
|
|
|
|
// clientCredential の作成
|
|
|
|
result = client.getClientCredential(clientInfo)
|
|
|
|
assertNotNull(result)
|
|
|
|
assertEquals(null, result?.error)
|
|
|
|
val clientCredential = result?.string
|
|
|
|
assertNotNull(clientCredential)
|
2023-01-15 08:51:13 +01:00
|
|
|
if (clientCredential == null) return@runTest
|
2020-12-11 22:25:45 +01:00
|
|
|
clientInfo[TootApiClient.KEY_CLIENT_CREDENTIAL] = clientCredential
|
|
|
|
|
|
|
|
// clientCredential の検証
|
|
|
|
result = client.verifyClientCredential(clientCredential)
|
|
|
|
assertNotNull(result)
|
|
|
|
assertEquals(null, result?.error)
|
|
|
|
jsonObject = result?.jsonObject
|
|
|
|
assertNotNull(jsonObject) // 中味は別に見てない。jsonObjectなら良いらしい
|
2023-01-15 08:51:13 +01:00
|
|
|
if (jsonObject == null) return@runTest
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
var url: String?
|
|
|
|
|
|
|
|
// ブラウザURLの作成
|
|
|
|
url = client.prepareBrowserUrl(scope_string, clientInfo)
|
|
|
|
assertNotNull(url)
|
|
|
|
println(url)
|
|
|
|
|
|
|
|
// ここまでと同じことをauthorize1でまとめて行う
|
|
|
|
result = client.authentication1(clientName)
|
|
|
|
url = result?.string
|
|
|
|
assertNotNull(url)
|
2023-01-15 08:51:13 +01:00
|
|
|
if (url == null) return@runTest
|
2020-12-11 22:25:45 +01:00
|
|
|
println(url)
|
|
|
|
|
|
|
|
// ブラウザからコールバックで受け取ったcodeを処理する
|
2021-05-11 08:12:43 +02:00
|
|
|
val refToken = AtomicReference<String>(null)
|
2021-10-28 01:37:39 +02:00
|
|
|
result = client.authentication2Mastodon(clientName, "DUMMY_CODE", refToken)
|
2020-12-11 22:25:45 +01:00
|
|
|
jsonObject = result?.jsonObject
|
|
|
|
assertNotNull(jsonObject)
|
2023-01-15 08:51:13 +01:00
|
|
|
if (jsonObject == null) return@runTest
|
2020-12-11 22:25:45 +01:00
|
|
|
println(jsonObject.toString())
|
|
|
|
|
|
|
|
// 認証できたならアクセストークンがある
|
|
|
|
val tokenInfo = result?.tokenInfo
|
|
|
|
assertNotNull(tokenInfo)
|
2023-01-15 08:51:13 +01:00
|
|
|
if (tokenInfo == null) return@runTest
|
2020-12-11 22:25:45 +01:00
|
|
|
val accessToken = tokenInfo.string("access_token")
|
|
|
|
assertNotNull(accessToken)
|
2023-01-15 08:51:13 +01:00
|
|
|
if (accessToken == null) return@runTest
|
2020-12-11 22:25:45 +01:00
|
|
|
|
|
|
|
// アカウント手動入力でログインする場合はこの関数を直接呼び出す
|
|
|
|
result = client.getUserCredential(accessToken, tokenInfo)
|
|
|
|
jsonObject = result?.jsonObject
|
|
|
|
assertNotNull(jsonObject)
|
2023-01-15 08:51:13 +01:00
|
|
|
if (jsonObject == null) return@runTest
|
2020-12-11 22:25:45 +01:00
|
|
|
println(jsonObject.toString())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testGetInstanceInformation() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2020-12-11 22:25:45 +01:00
|
|
|
val callback = ProgressRecordTootApiCallback()
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
val instance = Host.parse("unit-test")
|
|
|
|
client.apiHost = instance
|
2021-10-28 01:37:39 +02:00
|
|
|
val (instanceInfo, instanceResult) = TootInstance.get(client)
|
2023-01-15 08:51:13 +01:00
|
|
|
assertNull("no error", instanceResult?.error)
|
|
|
|
assertNotNull("instance info", instanceInfo)
|
2020-12-11 22:25:45 +01:00
|
|
|
val json = instanceResult?.jsonObject
|
|
|
|
if (json != null) println(json.toString())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testGetHttp() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2020-12-11 22:25:45 +01:00
|
|
|
val callback = ProgressRecordTootApiCallback()
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
val result = client.getHttp("http://juggler.jp/")
|
|
|
|
val content = result?.string
|
|
|
|
assertNotNull(content)
|
|
|
|
println(content.toString())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testRequest() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2020-12-11 22:25:45 +01:00
|
|
|
val tokenInfo = JsonObject()
|
|
|
|
tokenInfo["access_token"] = "DUMMY_ACCESS_TOKEN"
|
|
|
|
|
|
|
|
val accessInfo = SavedAccount(
|
2021-10-28 01:37:39 +02:00
|
|
|
db_id = 1,
|
|
|
|
acctArg = "user1@host1",
|
|
|
|
apiHostArg = null,
|
|
|
|
token_info = tokenInfo
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
val callback = ProgressRecordTootApiCallback()
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
client.account = accessInfo
|
|
|
|
val result = client.request("/api/v1/timelines/public")
|
|
|
|
println(result?.bodyString)
|
|
|
|
|
|
|
|
val content = result?.jsonArray
|
|
|
|
assertNotNull(content)
|
|
|
|
println(content?.jsonObject(0).toString())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testWebSocket() {
|
2023-01-15 08:51:13 +01:00
|
|
|
runTest {
|
2023-01-14 11:19:01 +01:00
|
|
|
val tokenInfo = buildJsonObject {
|
2020-12-11 22:25:45 +01:00
|
|
|
put("access_token", "DUMMY_ACCESS_TOKEN")
|
|
|
|
}
|
|
|
|
|
|
|
|
val accessInfo = SavedAccount(
|
2021-10-28 01:37:39 +02:00
|
|
|
db_id = 1,
|
|
|
|
acctArg = "user1@host1",
|
|
|
|
apiHostArg = null,
|
|
|
|
token_info = tokenInfo
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
val callback = ProgressRecordTootApiCallback()
|
|
|
|
val client = TootApiClient(
|
2021-10-28 01:37:39 +02:00
|
|
|
appContext,
|
|
|
|
httpClient = createHttpClientNormal(),
|
|
|
|
callback = callback
|
|
|
|
)
|
2020-12-11 22:25:45 +01:00
|
|
|
client.account = accessInfo
|
2021-10-28 01:37:39 +02:00
|
|
|
val (_, ws) = client.webSocket("/api/v1/streaming/?stream=public:local",
|
|
|
|
object : WebSocketListener() {
|
|
|
|
})
|
2020-12-11 22:25:45 +01:00
|
|
|
assertNotNull(ws)
|
|
|
|
ws?.cancel()
|
|
|
|
}
|
|
|
|
}
|
2018-01-12 10:01:25 +01:00
|
|
|
}
|