fix: support plain data board wrapper parsing
This commit is contained in:
@@ -487,6 +487,7 @@ class HttpKanbnApiClient : KanbnApiClient {
|
|||||||
?: return BoardDetail(id = fallbackId, title = "Board", lists = emptyList())
|
?: return BoardDetail(id = fallbackId, title = "Board", lists = emptyList())
|
||||||
val data = root["data"] as? Map<*, *>
|
val data = root["data"] as? Map<*, *>
|
||||||
val board = (data?.get("board") as? Map<*, *>)
|
val board = (data?.get("board") as? Map<*, *>)
|
||||||
|
?: data
|
||||||
?: (root["board"] as? Map<*, *>)
|
?: (root["board"] as? Map<*, *>)
|
||||||
?: root
|
?: root
|
||||||
|
|
||||||
|
|||||||
@@ -141,6 +141,51 @@ class HttpKanbnApiClientBoardDetailParsingTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getBoardDetailParsesPlainDataWrapperWithoutBoardKey() = runTest {
|
||||||
|
TestServer().use { server ->
|
||||||
|
server.register(
|
||||||
|
path = "/api/v1/boards/data-only",
|
||||||
|
status = 200,
|
||||||
|
responseBody =
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"id": "data-only",
|
||||||
|
"name": "Wrapped board",
|
||||||
|
"lists": [
|
||||||
|
{
|
||||||
|
"public_id": "list-9",
|
||||||
|
"name": "Queue",
|
||||||
|
"cards": [
|
||||||
|
{
|
||||||
|
"publicId": "card-99",
|
||||||
|
"name": "Card in data wrapper",
|
||||||
|
"labels": [
|
||||||
|
{"public_id": "tag-77", "title": "Infra", "color": "#ABCDEF"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""".trimIndent(),
|
||||||
|
)
|
||||||
|
|
||||||
|
val result = HttpKanbnApiClient().getBoardDetail(server.baseUrl, "key", "data-only")
|
||||||
|
|
||||||
|
assertTrue(result is BoardsApiResult.Success<*>)
|
||||||
|
val detail = (result as BoardsApiResult.Success<*>).value as BoardDetail
|
||||||
|
assertEquals("data-only", detail.id)
|
||||||
|
assertEquals("Wrapped board", detail.title)
|
||||||
|
assertEquals(1, detail.lists.size)
|
||||||
|
assertEquals("list-9", detail.lists[0].id)
|
||||||
|
assertEquals("card-99", detail.lists[0].cards[0].id)
|
||||||
|
assertEquals("tag-77", detail.lists[0].cards[0].tags[0].id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun requestMappingMatchesContractForBoardDetailAndMutations() = runTest {
|
fun requestMappingMatchesContractForBoardDetailAndMutations() = runTest {
|
||||||
TestServer().use { server ->
|
TestServer().use { server ->
|
||||||
@@ -209,6 +254,56 @@ class HttpKanbnApiClientBoardDetailParsingTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun moveCardFailureUsesServerMessageAndFallback() = runTest {
|
||||||
|
TestServer().use { server ->
|
||||||
|
server.register(
|
||||||
|
path = "/api/v1/cards/c-msg",
|
||||||
|
status = 409,
|
||||||
|
responseBody = """{"error":"Card cannot be moved"}""",
|
||||||
|
)
|
||||||
|
server.register(
|
||||||
|
path = "/api/v1/cards/c-fallback",
|
||||||
|
status = 500,
|
||||||
|
responseBody = "{}",
|
||||||
|
)
|
||||||
|
|
||||||
|
val client = HttpKanbnApiClient()
|
||||||
|
val messageResult = client.moveCard(server.baseUrl, "api", "c-msg", "l-1")
|
||||||
|
val fallbackResult = client.moveCard(server.baseUrl, "api", "c-fallback", "l-1")
|
||||||
|
|
||||||
|
assertTrue(messageResult is BoardsApiResult.Failure)
|
||||||
|
assertEquals("Card cannot be moved", (messageResult as BoardsApiResult.Failure).message)
|
||||||
|
assertTrue(fallbackResult is BoardsApiResult.Failure)
|
||||||
|
assertEquals("Server error: 500", (fallbackResult as BoardsApiResult.Failure).message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun deleteCardFailureUsesServerMessageAndFallback() = runTest {
|
||||||
|
TestServer().use { server ->
|
||||||
|
server.register(
|
||||||
|
path = "/api/v1/cards/c-del-msg",
|
||||||
|
status = 403,
|
||||||
|
responseBody = """{"detail":"No permission to delete card"}""",
|
||||||
|
)
|
||||||
|
server.register(
|
||||||
|
path = "/api/v1/cards/c-del-fallback",
|
||||||
|
status = 502,
|
||||||
|
responseBody = "[]",
|
||||||
|
)
|
||||||
|
|
||||||
|
val client = HttpKanbnApiClient()
|
||||||
|
val messageResult = client.deleteCard(server.baseUrl, "api", "c-del-msg")
|
||||||
|
val fallbackResult = client.deleteCard(server.baseUrl, "api", "c-del-fallback")
|
||||||
|
|
||||||
|
assertTrue(messageResult is BoardsApiResult.Failure)
|
||||||
|
assertEquals("No permission to delete card", (messageResult as BoardsApiResult.Failure).message)
|
||||||
|
assertTrue(fallbackResult is BoardsApiResult.Failure)
|
||||||
|
assertEquals("Server error: 502", (fallbackResult as BoardsApiResult.Failure).message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private data class CapturedRequest(
|
private data class CapturedRequest(
|
||||||
val method: String,
|
val method: String,
|
||||||
val path: String,
|
val path: String,
|
||||||
@@ -316,7 +411,11 @@ class HttpKanbnApiClientBoardDetailParsingTest {
|
|||||||
val reason = when (status) {
|
val reason = when (status) {
|
||||||
200 -> "OK"
|
200 -> "OK"
|
||||||
400 -> "Bad Request"
|
400 -> "Bad Request"
|
||||||
|
403 -> "Forbidden"
|
||||||
|
409 -> "Conflict"
|
||||||
404 -> "Not Found"
|
404 -> "Not Found"
|
||||||
|
500 -> "Internal Server Error"
|
||||||
|
502 -> "Bad Gateway"
|
||||||
503 -> "Service Unavailable"
|
503 -> "Service Unavailable"
|
||||||
else -> "Error"
|
else -> "Error"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user