feat(kanban): add rich create task dialog and quick card action menu

This commit is contained in:
M57 committed 2026-09-14 23:34:26 +03:00
1 parent 3cc5cc6574
commit 11512aeed4
6 files changed
+688 -62

No files matched your search

@@ -244,4 +244,101 @@ class KanbanMutationTest {
// Only 1 updateTask call initiated
coVerify(exactly = 1) { mockRepository.updateTask("t_1", "dev", any()) }
}
@Test
fun testCreateTaskWithFullOptionsAndStatusAlignment() =
runTest(testDispatcher) {
val board = KanbanBoard(id = "dev", name = "Dev")
val returnedTask = KanbanTask(id = "t_101", title = "Complex Task", status = "ready")
coEvery { mockRepository.getBoard("dev") } returns
NetworkResult.Success(KanbanBoardResponse(columns = listOf(KanbanColumn("todo", emptyList()))))
coEvery { mockRepository.createTask("dev", any()) } returns
NetworkResult.Success(CreateTaskResponse(task = returnedTask))
coEvery { mockRepository.updateTask("t_101", "dev", any()) } returns
NetworkResult.Success(UpdateTaskResponse(task = returnedTask.copy(status = "todo")))
val vm = createViewModel()
vm.selectBoard(board)
testDispatcher.scheduler.advanceUntilIdle()
val body =
CreateTaskBody(
title = "Complex Task",
body = "Rich spec",
assignee = "reviewer",
priority = 2,
goalMode = true,
modelOverride = "claude-3-5-sonnet",
providerOverride = "anthropic",
reasoningEffort = "high",
skills = listOf("kotlin", "compose"),
parents = listOf("t_parent"),
workspaceKind = "worktree",
)
vm.createTask(body = body, targetStatus = "todo")
testDispatcher.scheduler.advanceUntilIdle()
coVerify {
mockRepository.createTask(
"dev",
match {
it.title == "Complex Task" &&
it.body == "Rich spec" &&
it.assignee == "reviewer" &&
it.priority == 2 &&
it.goalMode &&
it.modelOverride == "claude-3-5-sonnet" &&
it.providerOverride == "anthropic" &&
it.reasoningEffort == "high" &&
it.skills == listOf("kotlin", "compose") &&
it.parents == listOf("t_parent") &&
it.workspaceKind == "worktree"
},
)
}
// Since backend returned "ready" but user wanted "todo", status alignment update is sent
coVerify {
mockRepository.updateTask(
"t_101",
"dev",
match { it.status == "todo" },
)
}
}
@Test
fun testLoadProfilesPopulatesState() =
runTest(testDispatcher) {
val profiles =
listOf(
com.m57.hermescontrol.data.model
.KanbanProfile(name = "researcher", model = "gpt-4o"),
com.m57.hermescontrol.data.model
.KanbanProfile(name = "reviewer", model = "claude-3-5-sonnet"),
)
coEvery { mockRepository.getProfiles() } returns
NetworkResult.Success(
com.m57.hermescontrol.data.model
.KanbanProfilesResponse(profiles),
)
val vm = createViewModel()
vm.loadProfiles()
testDispatcher.scheduler.advanceUntilIdle()
assertEquals(2, vm.uiState.value.profiles.size)
assertEquals(
"researcher",
vm.uiState.value.profiles[0]
.name,
)
assertEquals(
"reviewer",
vm.uiState.value.profiles[1]
.name,
)
}
}