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") 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()) { val session = when (val sessionResult = session()) {
is Result.Success -> sessionResult.value is Result.Success -> sessionResult.value
is Result.Failure -> return sessionResult is Result.Failure -> return sessionResult
@@ -210,7 +216,7 @@ class CardDetailRepository(
return when (val refreshResult = listActivities(normalizedCardId)) { return when (val refreshResult = listActivities(normalizedCardId)) {
is Result.Success -> refreshResult is Result.Success -> refreshResult
is Result.Failure.SessionExpired -> 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 { fun addComment_success_refreshesActivities() = runTest {
val apiClient = FakeCardDetailApiClient().apply { val apiClient = FakeCardDetailApiClient().apply {
addCommentResult = BoardsApiResult.Success(Unit) addCommentResult = BoardsApiResult.Success(Unit)
listActivitiesResult = BoardsApiResult.Success( listActivitiesResults += BoardsApiResult.Success(emptyList())
listActivitiesResults += BoardsApiResult.Success(
listOf( listOf(
CardActivity( CardActivity(
id = "a-1", id = "a-1",
@@ -116,15 +117,24 @@ class CardDetailRepositoryTest {
assertTrue(result is CardDetailRepository.Result.Success) assertTrue(result is CardDetailRepository.Result.Success)
assertEquals(1, apiClient.addCommentCalls) assertEquals(1, apiClient.addCommentCalls)
assertEquals(1, apiClient.listActivitiesCalls) assertEquals(2, apiClient.listActivitiesCalls)
assertEquals("hello", apiClient.lastComment) assertEquals("hello", apiClient.lastComment)
} }
@Test @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 { val apiClient = FakeCardDetailApiClient().apply {
addCommentResult = BoardsApiResult.Success(Unit) 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) val repository = createRepository(apiClient = apiClient)
@@ -132,22 +142,24 @@ class CardDetailRepositoryTest {
assertTrue(result is CardDetailRepository.Result.Success) assertTrue(result is CardDetailRepository.Result.Success)
val activities = (result as CardDetailRepository.Result.Success<List<CardActivity>>).value val activities = (result as CardDetailRepository.Result.Success<List<CardActivity>>).value
assertTrue(activities.isEmpty()) assertEquals(preAddSnapshot, activities)
assertEquals(1, apiClient.addCommentCalls) assertEquals(1, apiClient.addCommentCalls)
assertEquals(1, apiClient.listActivitiesCalls) assertEquals(2, apiClient.listActivitiesCalls)
} }
@Test @Test
fun addComment_refreshAuthFailure_mapsToSessionExpired() = runTest { fun addComment_refreshAuthFailure_mapsToSessionExpired() = runTest {
val apiClient = FakeCardDetailApiClient().apply { val apiClient = FakeCardDetailApiClient().apply {
addCommentResult = BoardsApiResult.Success(Unit) 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 repository = createRepository(apiClient = apiClient)
val result = repository.addComment(cardId = "card-1", comment = "hello") val result = repository.addComment(cardId = "card-1", comment = "hello")
assertTrue(result is CardDetailRepository.Result.Failure.SessionExpired) assertTrue(result is CardDetailRepository.Result.Failure.SessionExpired)
assertEquals(2, apiClient.listActivitiesCalls)
} }
@Test @Test
@@ -263,6 +275,7 @@ class CardDetailRepositoryTest {
) )
var updateCardResult: BoardsApiResult<Unit> = BoardsApiResult.Success(Unit) var updateCardResult: BoardsApiResult<Unit> = BoardsApiResult.Success(Unit)
var listActivitiesResult: BoardsApiResult<List<CardActivity>> = BoardsApiResult.Success(emptyList()) var listActivitiesResult: BoardsApiResult<List<CardActivity>> = BoardsApiResult.Success(emptyList())
val listActivitiesResults: MutableList<BoardsApiResult<List<CardActivity>>> = mutableListOf()
var addCommentResult: BoardsApiResult<Unit> = BoardsApiResult.Success(Unit) var addCommentResult: BoardsApiResult<Unit> = BoardsApiResult.Success(Unit)
var lastUpdatedTitle: String? = null var lastUpdatedTitle: String? = null
@@ -300,6 +313,9 @@ class CardDetailRepositoryTest {
cardId: String, cardId: String,
): BoardsApiResult<List<CardActivity>> { ): BoardsApiResult<List<CardActivity>> {
listActivitiesCalls += 1 listActivitiesCalls += 1
if (listActivitiesResults.isNotEmpty()) {
return listActivitiesResults.removeAt(0)
}
return listActivitiesResult return listActivitiesResult
} }