fix: preserve activity snapshot when comment refresh fails

This commit is contained in:
2026-03-16 20:43:44 -04:00
parent f85586ddc7
commit 7132123ccf
2 changed files with 30 additions and 8 deletions

View File

@@ -190,6 +190,12 @@ class CardDetailRepository(
return Result.Failure.Generic("Comment is required")
}
val preAddSnapshot = when (val preAddActivitiesResult = listActivities(normalizedCardId)) {
is Result.Success -> preAddActivitiesResult.value
is Result.Failure.SessionExpired -> return preAddActivitiesResult
is Result.Failure.Generic -> emptyList()
}
val session = when (val sessionResult = session()) {
is Result.Success -> sessionResult.value
is Result.Failure -> return sessionResult
@@ -210,7 +216,7 @@ class CardDetailRepository(
return when (val refreshResult = listActivities(normalizedCardId)) {
is Result.Success -> refreshResult
is Result.Failure.SessionExpired -> refreshResult
is Result.Failure.Generic -> Result.Success(emptyList())
is Result.Failure.Generic -> Result.Success(preAddSnapshot)
}
}

View File

@@ -99,7 +99,8 @@ class CardDetailRepositoryTest {
fun addComment_success_refreshesActivities() = runTest {
val apiClient = FakeCardDetailApiClient().apply {
addCommentResult = BoardsApiResult.Success(Unit)
listActivitiesResult = BoardsApiResult.Success(
listActivitiesResults += BoardsApiResult.Success(emptyList())
listActivitiesResults += BoardsApiResult.Success(
listOf(
CardActivity(
id = "a-1",
@@ -116,15 +117,24 @@ class CardDetailRepositoryTest {
assertTrue(result is CardDetailRepository.Result.Success)
assertEquals(1, apiClient.addCommentCalls)
assertEquals(1, apiClient.listActivitiesCalls)
assertEquals(2, apiClient.listActivitiesCalls)
assertEquals("hello", apiClient.lastComment)
}
@Test
fun addComment_refreshGenericFailure_returnsSuccessWithEmptyActivities() = runTest {
fun addComment_refreshGenericFailure_returnsSuccessWithPreAddSnapshot() = runTest {
val preAddSnapshot = listOf(
CardActivity(
id = "a-existing",
type = "comment",
text = "existing",
createdAtEpochMillis = 10L,
),
)
val apiClient = FakeCardDetailApiClient().apply {
addCommentResult = BoardsApiResult.Success(Unit)
listActivitiesResult = BoardsApiResult.Failure("Server temporarily unavailable")
listActivitiesResults += BoardsApiResult.Success(preAddSnapshot)
listActivitiesResults += BoardsApiResult.Failure("Server temporarily unavailable")
}
val repository = createRepository(apiClient = apiClient)
@@ -132,22 +142,24 @@ class CardDetailRepositoryTest {
assertTrue(result is CardDetailRepository.Result.Success)
val activities = (result as CardDetailRepository.Result.Success<List<CardActivity>>).value
assertTrue(activities.isEmpty())
assertEquals(preAddSnapshot, activities)
assertEquals(1, apiClient.addCommentCalls)
assertEquals(1, apiClient.listActivitiesCalls)
assertEquals(2, apiClient.listActivitiesCalls)
}
@Test
fun addComment_refreshAuthFailure_mapsToSessionExpired() = runTest {
val apiClient = FakeCardDetailApiClient().apply {
addCommentResult = BoardsApiResult.Success(Unit)
listActivitiesResult = BoardsApiResult.Failure("Server error: 403")
listActivitiesResults += BoardsApiResult.Success(emptyList())
listActivitiesResults += BoardsApiResult.Failure("Server error: 403")
}
val repository = createRepository(apiClient = apiClient)
val result = repository.addComment(cardId = "card-1", comment = "hello")
assertTrue(result is CardDetailRepository.Result.Failure.SessionExpired)
assertEquals(2, apiClient.listActivitiesCalls)
}
@Test
@@ -263,6 +275,7 @@ class CardDetailRepositoryTest {
)
var updateCardResult: BoardsApiResult<Unit> = BoardsApiResult.Success(Unit)
var listActivitiesResult: BoardsApiResult<List<CardActivity>> = BoardsApiResult.Success(emptyList())
val listActivitiesResults: MutableList<BoardsApiResult<List<CardActivity>>> = mutableListOf()
var addCommentResult: BoardsApiResult<Unit> = BoardsApiResult.Success(Unit)
var lastUpdatedTitle: String? = null
@@ -300,6 +313,9 @@ class CardDetailRepositoryTest {
cardId: String,
): BoardsApiResult<List<CardActivity>> {
listActivitiesCalls += 1
if (listActivitiesResults.isNotEmpty()) {
return listActivitiesResults.removeAt(0)
}
return listActivitiesResult
}