Skip to content

Commit

Permalink
feat: mark user as deleted when server response with 404 (#2259)
Browse files Browse the repository at this point in the history
  • Loading branch information
MohamadJaara authored and augustocdias committed Dec 5, 2023
1 parent 194c870 commit 34c4fc7
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import com.wire.kalium.logic.functional.foldToEitherWhileRight
import com.wire.kalium.logic.functional.getOrNull
import com.wire.kalium.logic.functional.map
import com.wire.kalium.logic.functional.mapRight
import com.wire.kalium.logic.functional.onFailure
import com.wire.kalium.logic.kaliumLogger
import com.wire.kalium.logic.wrapApiRequest
import com.wire.kalium.logic.wrapStorageRequest
Expand All @@ -61,6 +62,8 @@ import com.wire.kalium.network.api.base.authenticated.userDetails.qualifiedIds
import com.wire.kalium.network.api.base.model.SelfUserDTO
import com.wire.kalium.network.api.base.model.UserProfileDTO
import com.wire.kalium.network.api.base.model.isTeamMember
import com.wire.kalium.network.exceptions.KaliumException
import com.wire.kalium.network.exceptions.isNotFound
import com.wire.kalium.persistence.dao.ConnectionEntity
import com.wire.kalium.persistence.dao.MetadataDAO
import com.wire.kalium.persistence.dao.QualifiedIDEntity
Expand Down Expand Up @@ -226,8 +229,20 @@ internal class UserDataSource internal constructor(
return fetchUsersByIds(ids)
}

/**
* Fetches user information for all of users id stored in the DB
* and updates the DB with the new information.
* If the user is not found on the server, it will be marked as deleted.
*/
override suspend fun fetchUserInfo(userId: UserId) =
wrapApiRequest { userDetailsApi.getUserInfo(userId.toApi()) }
.onFailure {
if (it is NetworkFailure.ServerMiscommunication &&
it.kaliumException is KaliumException.InvalidRequestError &&
it.kaliumException.isNotFound()) {
wrapStorageRequest { userDAO.markUserAsDeleted(userId.toDao()) }
}
}
.flatMap { userProfileDTO ->
fetchTeamMembersByIds(listOf(userProfileDTO))
.flatMap { persistUsers(listOf(userProfileDTO), it) }
Expand Down Expand Up @@ -317,8 +332,8 @@ internal class UserDataSource internal constructor(
userProfile = userProfileDTO,
connectionState = ConnectionEntity.State.ACCEPTED,
userTypeEntity =
if (userProfileDTO.service != null) UserTypeEntity.SERVICE
else userTypeEntityMapper.teamRoleCodeToUserType(mapTeamMemberDTO[userProfileDTO.id.value]?.permissions?.own)
if (userProfileDTO.service != null) UserTypeEntity.SERVICE
else userTypeEntityMapper.teamRoleCodeToUserType(mapTeamMemberDTO[userProfileDTO.id.value]?.permissions?.own)
)
}
val otherUsers = listUserProfileDTO
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ import com.wire.kalium.network.api.base.authenticated.userDetails.ListUsersDTO
import com.wire.kalium.network.api.base.authenticated.userDetails.QualifiedUserIdListRequest
import com.wire.kalium.network.api.base.authenticated.userDetails.UserDetailsApi
import com.wire.kalium.network.api.base.authenticated.userDetails.qualifiedIds
import com.wire.kalium.network.api.base.model.ErrorResponse
import com.wire.kalium.network.api.base.model.UserProfileDTO
import com.wire.kalium.network.exceptions.KaliumException
import com.wire.kalium.network.utils.NetworkResponse
import com.wire.kalium.persistence.dao.MetadataDAO
import com.wire.kalium.persistence.dao.QualifiedIDEntity
Expand Down Expand Up @@ -692,6 +694,33 @@ class UserRepositoryTest {
.wasNotInvoked()
}

@Test
fun givenNotFoundError_whenFetchingAUserInfo_thenMarkAsDeleted() = runTest {
val (arrangement, userRepository) = Arrangement()
.withUserDaoReturning(TestUser.DETAILS_ENTITY.copy(team = TestTeam.TEAM_ID.value))
.withErrorGetUsersInfo(
NetworkResponse.Error(
KaliumException.InvalidRequestError(
ErrorResponse(404, "Not found", "not-found")
)
)
)
.arrange()

val result = userRepository.fetchUserInfo(TestUser.USER_ID)
result.shouldFail()

verify(arrangement.userDetailsApi)
.suspendFunction(arrangement.userDetailsApi::getUserInfo)
.with(any())
.wasInvoked(exactly = once)

verify(arrangement.userDAO)
.suspendFunction(arrangement.userDAO::markUserAsDeleted)
.with(any())
.wasInvoked(exactly = once)
}

private class Arrangement {
@Mock
val userDAO = configure(mock(classOf<UserDAO>())) { stubsUnitByDefault = true }
Expand Down Expand Up @@ -783,6 +812,13 @@ class UserRepositoryTest {
.thenReturn(NetworkResponse.Success(result, mapOf(), 200))
}

fun withErrorGetUsersInfo(error: NetworkResponse.Error) = apply {
given(userDetailsApi)
.suspendFunction(userDetailsApi::getUserInfo)
.whenInvokedWith(any())
.thenReturn(error)
}

fun withSuccessfulFetchTeamMembersByIds(result: List<TeamsApi.TeamMemberDTO>) = apply {
given(teamsApi)
.suspendFunction(teamsApi::getTeamMembersByIds)
Expand Down

0 comments on commit 34c4fc7

Please sign in to comment.