refactor(kanban): unify KanbanApiService with HermesApiService and update E2E integration test
This commit is contained in:
1 parent
dd5ce10796
commit
3cc5cc6574
5 files changed
+23
-23
No files matched your search
@@ -22,9 +22,6 @@ object ApiClient {
|
|||||||
@Volatile
|
@Volatile
|
||||||
private var service: HermesApiService? = null
|
private var service: HermesApiService? = null
|
||||||
|
|
||||||
@Volatile
|
|
||||||
private var kanbanService: KanbanApiService? = null
|
|
||||||
|
|
||||||
/** The current [HermesApiService] instance. Lazily created on first access. */
|
/** The current [HermesApiService] instance. Lazily created on first access. */
|
||||||
val hermesApi: HermesApiService
|
val hermesApi: HermesApiService
|
||||||
get() {
|
get() {
|
||||||
@@ -33,20 +30,15 @@ object ApiClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The current [KanbanApiService] instance. Lazily created on first access. */
|
/** The current [KanbanApiService] instance. Reuses [hermesApi]. */
|
||||||
val kanbanApi: KanbanApiService
|
val kanbanApi: KanbanApiService
|
||||||
get() {
|
get() = hermesApi
|
||||||
return kanbanService ?: synchronized(this) {
|
|
||||||
kanbanService ?: buildRetrofit().create(KanbanApiService::class.java).also { kanbanService = it }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Force-rebuild the Retrofit client (e.g. after settings change). */
|
/** Force-rebuild the Retrofit client (e.g. after settings change). */
|
||||||
fun rebuild() {
|
fun rebuild() {
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
retrofit = null
|
retrofit = null
|
||||||
service = null
|
service = null
|
||||||
kanbanService = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ import retrofit2.http.Path
|
|||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
import retrofit2.http.Streaming
|
import retrofit2.http.Streaming
|
||||||
|
|
||||||
interface HermesApiService {
|
interface HermesApiService : KanbanApiService {
|
||||||
@GET("api/skills/content")
|
@GET("api/skills/content")
|
||||||
suspend fun getSkillContent(
|
suspend fun getSkillContent(
|
||||||
@Query("name") name: String,
|
@Query("name") name: String,
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ interface KanbanApiService {
|
|||||||
): Response<ResponseBody>
|
): Response<ResponseBody>
|
||||||
|
|
||||||
@GET("api/plugins/kanban/profiles")
|
@GET("api/plugins/kanban/profiles")
|
||||||
suspend fun getProfiles(): Response<KanbanProfilesResponse>
|
suspend fun getKanbanProfiles(): Response<KanbanProfilesResponse>
|
||||||
|
|
||||||
@PATCH("api/plugins/kanban/profiles/{name}")
|
@PATCH("api/plugins/kanban/profiles/{name}")
|
||||||
suspend fun updateProfileDescription(
|
suspend fun updateProfileDescription(
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ class KanbanRepositoryImpl(
|
|||||||
|
|
||||||
override suspend fun getProfiles(): NetworkResult<KanbanProfilesResponse> =
|
override suspend fun getProfiles(): NetworkResult<KanbanProfilesResponse> =
|
||||||
withContext(ioDispatcher) {
|
withContext(ioDispatcher) {
|
||||||
safeApiCall { apiProvider().getProfiles() }
|
safeApiCall { apiProvider().getKanbanProfiles() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun updateProfileDescription(
|
override suspend fun updateProfileDescription(
|
||||||
|
|||||||
@@ -1205,10 +1205,9 @@ class E2eIntegrationTest {
|
|||||||
runTest {
|
runTest {
|
||||||
val board = KanbanBoard("board-1", "Backlog", null)
|
val board = KanbanBoard("board-1", "Backlog", null)
|
||||||
val task = KanbanTask("task-1", "Do laundry", null, "todo", null)
|
val task = KanbanTask("task-1", "Do laundry", null, "todo", null)
|
||||||
coEvery { mockApiService.getKanbanBoards() } returns
|
coEvery { mockApiService.getBoards(any()) } returns
|
||||||
Response.success(KanbanBoardsResponse(listOf(board), "board-1"))
|
Response.success(KanbanBoardsResponse(listOf(board), "board-1"))
|
||||||
coEvery { mockApiService.switchKanbanBoard("board-1") } returns Response.success(Unit)
|
coEvery { mockApiService.getBoard("board-1", any(), any()) } returns
|
||||||
coEvery { mockApiService.getKanbanBoard() } returns
|
|
||||||
Response.success(KanbanBoardResponse(listOf(KanbanColumn("todo", listOf(task))), null, null))
|
Response.success(KanbanBoardResponse(listOf(KanbanColumn("todo", listOf(task))), null, null))
|
||||||
|
|
||||||
val viewModel = KanbanViewModel(eventsClientProvider = { mockk<KanbanEventsClient>(relaxed = true) })
|
val viewModel = KanbanViewModel(eventsClientProvider = { mockk<KanbanEventsClient>(relaxed = true) })
|
||||||
@@ -1230,11 +1229,16 @@ class E2eIntegrationTest {
|
|||||||
// Desktop-style transition: todo -> ready is a direct write the
|
// Desktop-style transition: todo -> ready is a direct write the
|
||||||
// backend accepts; the VM PATCHes the target status.
|
// backend accepts; the VM PATCHes the target status.
|
||||||
coEvery {
|
coEvery {
|
||||||
mockApiService.updateKanbanTask(
|
mockApiService.updateTask(
|
||||||
"task-1",
|
eq("task-1"),
|
||||||
mapOf("status" to "ready"),
|
eq("board-1"),
|
||||||
|
any(),
|
||||||
|
)
|
||||||
|
} returns
|
||||||
|
Response.success(
|
||||||
|
com.m57.hermescontrol.data.model
|
||||||
|
.UpdateTaskResponse(task = task.copy(status = "ready")),
|
||||||
)
|
)
|
||||||
} returns Response.success(Unit)
|
|
||||||
viewModel.moveTask(viewModel.uiState.value.tasks[0], KanbanTaskAction.READY)
|
viewModel.moveTask(viewModel.uiState.value.tasks[0], KanbanTaskAction.READY)
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
assertEquals(
|
assertEquals(
|
||||||
@@ -1243,9 +1247,13 @@ class E2eIntegrationTest {
|
|||||||
.status,
|
.status,
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create path: the wrapped {"task": ...} response must not
|
// Create path: returns CreateTaskResponse
|
||||||
// break deserialization — the API layer reads it as Unit.
|
coEvery { mockApiService.createTask(any(), any()) } returns
|
||||||
coEvery { mockApiService.createKanbanTask(any(), any()) } returns Response.success(Unit)
|
Response.success(
|
||||||
|
com.m57.hermescontrol.data.model.CreateTaskResponse(
|
||||||
|
task = KanbanTask("task-2", "Fresh task", status = "todo"),
|
||||||
|
),
|
||||||
|
)
|
||||||
viewModel.createTask("Fresh task", null, "todo")
|
viewModel.createTask("Fresh task", null, "todo")
|
||||||
advanceUntilIdle()
|
advanceUntilIdle()
|
||||||
assertEquals("Task created successfully", viewModel.uiState.value.toastMessage)
|
assertEquals("Task created successfully", viewModel.uiState.value.toastMessage)
|
||||||
|
|||||||
Reference in new issue
Block a user