fix: filter template boards by type in board list parsing

This commit is contained in:
2026-04-30 15:04:52 -04:00
parent d162841708
commit de59a1d0e7
4 changed files with 4 additions and 89 deletions
@@ -996,15 +996,11 @@ class HttpKanbnApiClient : KanbnApiClient {
private fun isTemplateBoard(item: JSONObject): Boolean { private fun isTemplateBoard(item: JSONObject): Boolean {
val typeKeys = listOf("type", "boardType", "kind") val typeKeys = listOf("type", "boardType", "kind")
val hasTemplateType = typeKeys.any { key -> return typeKeys.any { key ->
item.optString(key) item.optString(key)
.trim() .trim()
.equals("template", ignoreCase = true) .equals("template", ignoreCase = true)
} }
if (hasTemplateType) {
return true
}
return item.optBoolean("isTemplate", false)
} }
private fun parseSingleBoard(body: String, fallbackName: String): BoardSummary { private fun parseSingleBoard(body: String, fallbackName: String): BoardSummary {
@@ -93,30 +93,11 @@ class BoardsRepository(
is BoardsApiResult.Success -> sessionResult.value is BoardsApiResult.Success -> sessionResult.value
is BoardsApiResult.Failure -> return sessionResult is BoardsApiResult.Failure -> return sessionResult
} }
val boardsResult = apiClient.listBoards( return apiClient.listBoards(
baseUrl = session.baseUrl, baseUrl = session.baseUrl,
apiKey = session.apiKey, apiKey = session.apiKey,
workspaceId = session.workspaceId, workspaceId = session.workspaceId,
) )
if (boardsResult is BoardsApiResult.Failure) {
return boardsResult
}
val boards = (boardsResult as BoardsApiResult.Success).value
val templatesResult = apiClient.listBoardTemplates(
baseUrl = session.baseUrl,
apiKey = session.apiKey,
workspaceId = session.workspaceId,
)
return when (templatesResult) {
is BoardsApiResult.Success -> {
val templateIds = templatesResult.value.map { it.id }.toSet()
BoardsApiResult.Success(boards.filterNot { it.id in templateIds })
}
is BoardsApiResult.Failure -> BoardsApiResult.Success(boards)
}
} }
suspend fun listTemplates(): BoardsApiResult<List<BoardTemplate>> { suspend fun listTemplates(): BoardsApiResult<List<BoardTemplate>> {
@@ -32,7 +32,6 @@ class HttpKanbnApiClientBoardsParsingTest {
{"id":"board-1","name":"Roadmap"}, {"id":"board-1","name":"Roadmap"},
{"id":"tmpl-1","name":"Template A","type":"template"}, {"id":"tmpl-1","name":"Template A","type":"template"},
{"id":"tmpl-2","name":"Template B","kind":"template"}, {"id":"tmpl-2","name":"Template B","kind":"template"},
{"id":"tmpl-3","name":"Template C","isTemplate":true},
{"id":"tmpl-4","name":"Template D","boardType":" Template "}, {"id":"tmpl-4","name":"Template D","boardType":" Template "},
{"publicId":"board-2","title":"Backlog"} {"publicId":"board-2","title":"Backlog"}
] ]
@@ -59,7 +58,7 @@ class HttpKanbnApiClientBoardsParsingTest {
"boards": [ "boards": [
{"id":"tmpl-1","name":"Template A","type":"template"}, {"id":"tmpl-1","name":"Template A","type":"template"},
{"id":"tmpl-2","name":"Template B","kind":"template"}, {"id":"tmpl-2","name":"Template B","kind":"template"},
{"id":"tmpl-3","name":"Template C","isTemplate":true} {"id":"tmpl-3","name":"Template C","boardType":"TEMPLATE"}
] ]
} }
""".trimIndent(), """.trimIndent(),
@@ -109,65 +109,6 @@ class BoardsRepositoryTest {
assertEquals("No workspaces available for this account.", (result as BoardsApiResult.Failure).message) assertEquals("No workspaces available for this account.", (result as BoardsApiResult.Failure).message)
} }
@Test
fun listBoardsExcludesBoardsWhoseIdsMatchTemplates() = runTest {
val fakeApi = FakeBoardsApiClient().apply {
workspacesResult = BoardsApiResult.Success(listOf(WorkspaceSummary("ws-1", "Main")))
listBoardsResult = BoardsApiResult.Success(
listOf(
BoardSummary("board-1", "Juegos"),
BoardSummary("tpl-1", "GTD Simplificado"),
BoardSummary("tpl-2", "Kanban"),
BoardSummary("board-2", "Task Tension"),
),
)
listTemplatesResult = BoardsApiResult.Success(
listOf(
BoardTemplate("tpl-1", "GTD Simplificado"),
BoardTemplate("tpl-2", "Kanban"),
),
)
}
val repository = BoardsRepository(
sessionStore = InMemorySessionStore("https://kan.bn/"),
apiKeyStore = InMemoryApiKeyStore("api"),
apiClient = fakeApi,
)
val result = repository.listBoards()
assertTrue(result is BoardsApiResult.Success)
val boards = (result as BoardsApiResult.Success).value
assertEquals(listOf("board-1", "board-2"), boards.map { it.id })
}
@Test
fun listBoardsReturnsApiBoardsWhenTemplateListingFails() = runTest {
val fakeApi = FakeBoardsApiClient().apply {
workspacesResult = BoardsApiResult.Success(listOf(WorkspaceSummary("ws-1", "Main")))
listBoardsResult = BoardsApiResult.Success(
listOf(
BoardSummary("board-1", "Juegos"),
BoardSummary("tpl-1", "GTD Simplificado"),
),
)
listTemplatesResult = BoardsApiResult.Failure("Template endpoint unavailable")
}
val repository = BoardsRepository(
sessionStore = InMemorySessionStore("https://kan.bn/"),
apiKeyStore = InMemoryApiKeyStore("api"),
apiClient = fakeApi,
)
val result = repository.listBoards()
assertTrue(result is BoardsApiResult.Success)
val boards = (result as BoardsApiResult.Success).value
assertEquals(listOf("board-1", "tpl-1"), boards.map { it.id })
}
@Test @Test
fun createBoardTrimsNameAndPassesTemplateId() = runTest { fun createBoardTrimsNameAndPassesTemplateId() = runTest {
val fakeApi = FakeBoardsApiClient().apply { val fakeApi = FakeBoardsApiClient().apply {
@@ -248,7 +189,6 @@ class BoardsRepositoryTest {
private class FakeBoardsApiClient : KanbnApiClient { private class FakeBoardsApiClient : KanbnApiClient {
var listBoardsResult: BoardsApiResult<List<BoardSummary>> = BoardsApiResult.Success(emptyList()) var listBoardsResult: BoardsApiResult<List<BoardSummary>> = BoardsApiResult.Success(emptyList())
var listTemplatesResult: BoardsApiResult<List<BoardTemplate>> = BoardsApiResult.Success(emptyList())
var workspacesResult: BoardsApiResult<List<WorkspaceSummary>> = var workspacesResult: BoardsApiResult<List<WorkspaceSummary>> =
BoardsApiResult.Success(listOf(WorkspaceSummary("ws-1", "Main"))) BoardsApiResult.Success(listOf(WorkspaceSummary("ws-1", "Main")))
var createBoardResult: BoardsApiResult<BoardSummary> = BoardsApiResult.Success(BoardSummary("new", "New")) var createBoardResult: BoardsApiResult<BoardSummary> = BoardsApiResult.Success(BoardSummary("new", "New"))
@@ -285,8 +225,7 @@ class BoardsRepositoryTest {
apiKey: String, apiKey: String,
workspaceId: String, workspaceId: String,
): BoardsApiResult<List<BoardTemplate>> { ): BoardsApiResult<List<BoardTemplate>> {
lastWorkspaceId = workspaceId return BoardsApiResult.Success(emptyList())
return listTemplatesResult
} }
override suspend fun createBoard( override suspend fun createBoard(