diff --git a/data/account/src/main/kotlin/com/tangem/data/account/fetcher/DefaultWalletAccountsFetcher.kt b/data/account/src/main/kotlin/com/tangem/data/account/fetcher/DefaultWalletAccountsFetcher.kt index 3bc99dc784..8c475f3b58 100644 --- a/data/account/src/main/kotlin/com/tangem/data/account/fetcher/DefaultWalletAccountsFetcher.kt +++ b/data/account/src/main/kotlin/com/tangem/data/account/fetcher/DefaultWalletAccountsFetcher.kt @@ -94,21 +94,23 @@ internal class DefaultWalletAccountsFetcher @Inject constructor( override suspend fun push( userWalletId: UserWalletId, body: SaveWalletAccountsResponse, + ): GetWalletAccountsResponse? { + return pushInternal(userWalletId = userWalletId, body = body) + } + + private suspend fun pushInternal( + userWalletId: UserWalletId, + body: SaveWalletAccountsResponse, + eTag: String? = null, ): GetWalletAccountsResponse? { return safeApiCall( call = { - var eTag = getETag(userWalletId) - - if (eTag == null) { - fetch(userWalletId) - - eTag = getETag(userWalletId) ?: error("ETag is null after fetch") - } + val resolvedETag = eTag ?: getETagForPush(userWalletId) val apiResponse = withContext(dispatchers.io) { tangemTechApi.saveWalletAccounts( walletId = userWalletId.stringValue, - eTag = eTag, + eTag = resolvedETag, body = body, ) } @@ -127,6 +129,19 @@ internal class DefaultWalletAccountsFetcher @Inject constructor( ) } + private suspend fun getETagForPush(userWalletId: UserWalletId): String { + var savedETag = getETag(userWalletId) + + if (savedETag == null) { + fetch(userWalletId) + + savedETag = getETag(userWalletId) + ?: error("Failed to retrieve ETag after fetching wallet accounts for wallet $userWalletId") + } + + return savedETag + } + private suspend fun fetchWalletAccounts( userWalletId: UserWalletId, savedAccountsResponse: GetWalletAccountsResponse?, @@ -154,7 +169,13 @@ internal class DefaultWalletAccountsFetcher @Inject constructor( error = throwable, userWalletId = userWalletId, savedAccountsResponse = savedAccountsResponse, - pushWalletAccounts = ::push, + pushWalletAccounts = { accounts, eTag -> + pushInternal( + userWalletId = userWalletId, + body = SaveWalletAccountsResponse(accounts), + eTag = eTag, + ) + }, storeWalletAccounts = ::store, ) }, diff --git a/data/account/src/main/kotlin/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandler.kt b/data/account/src/main/kotlin/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandler.kt index 9e86b4848b..772a1dce68 100644 --- a/data/account/src/main/kotlin/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandler.kt +++ b/data/account/src/main/kotlin/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandler.kt @@ -2,7 +2,6 @@ package com.tangem.data.account.fetcher import com.tangem.data.account.fetcher.DefaultWalletAccountsFetcher.FetchResult import com.tangem.data.account.utils.DefaultWalletAccountsResponseFactory -import com.tangem.data.common.cache.etag.ETagsStore import com.tangem.data.common.currency.UserTokensResponseAccountIdEnricher import com.tangem.data.common.currency.UserTokensSaver import com.tangem.datasource.api.common.response.ApiResponse @@ -29,10 +28,10 @@ import javax.inject.Singleton * Handles errors that occur during the fetching of wallet accounts * * @property tangemTechApi API for network requests + * @property userWalletsStore provides access to user wallets storage * @property userTokensSaver saves user tokens to the storage * @property userTokensResponseStore provides access to user token responses. * @property defaultWalletAccountsResponseFactory creates [GetWalletAccountsResponse] from [UserTokensResponse] - * @property eTagsStore store for ETags to manage caching * @property dispatchers dispatchers * * @see DefaultWalletAccountsFetcher @@ -47,7 +46,6 @@ internal class FetchWalletAccountsErrorHandler @Inject constructor( private val userTokensSaver: UserTokensSaver, private val userTokensResponseStore: UserTokensResponseStore, private val defaultWalletAccountsResponseFactory: DefaultWalletAccountsResponseFactory, - private val eTagsStore: ETagsStore, private val dispatchers: CoroutineDispatcherProvider, ) { @@ -66,7 +64,7 @@ internal class FetchWalletAccountsErrorHandler @Inject constructor( error: ApiResponseError, userWalletId: UserWalletId, savedAccountsResponse: GetWalletAccountsResponse?, - pushWalletAccounts: suspend (UserWalletId, List) -> GetWalletAccountsResponse?, + pushWalletAccounts: suspend (List, String) -> GetWalletAccountsResponse?, storeWalletAccounts: suspend (UserWalletId, GetWalletAccountsResponse) -> Unit, ): FetchResult { val isResponseUpToDate = error.isNetworkError(code = Code.NOT_MODIFIED) @@ -87,9 +85,7 @@ internal class FetchWalletAccountsErrorHandler @Inject constructor( val eTag = createWallet(userWalletId) if (eTag != null) { - eTagsStore.store(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts, value = eTag) - - pushWalletAccounts(userWalletId, accountDTOs) + pushWalletAccounts(accountDTOs, eTag) userTokensSaver.pushWithRetryer(userWalletId, userTokensResponse) } } diff --git a/data/account/src/test/java/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandlerTest.kt b/data/account/src/test/java/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandlerTest.kt index 88e44f4db4..51d9c2ad3f 100644 --- a/data/account/src/test/java/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandlerTest.kt +++ b/data/account/src/test/java/com/tangem/data/account/fetcher/FetchWalletAccountsErrorHandlerTest.kt @@ -3,7 +3,6 @@ package com.tangem.data.account.fetcher import com.tangem.data.account.converter.createGetWalletAccountsResponse import com.tangem.data.account.converter.createWalletAccountDTO import com.tangem.data.account.utils.DefaultWalletAccountsResponseFactory -import com.tangem.data.common.cache.etag.ETagsStore import com.tangem.data.common.currency.UserTokensSaver import com.tangem.datasource.api.common.response.ApiResponse import com.tangem.datasource.api.common.response.ApiResponseError @@ -38,7 +37,6 @@ class FetchWalletAccountsErrorHandlerTest { private val userTokensSaver: UserTokensSaver = mockk(relaxUnitFun = true) private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxUnitFun = true) private val defaultWalletAccountsResponseFactory: DefaultWalletAccountsResponseFactory = mockk() - private val eTagsStore: ETagsStore = mockk(relaxUnitFun = true) private val handler = FetchWalletAccountsErrorHandler( tangemTechApi = tangemTechApi, @@ -46,17 +44,18 @@ class FetchWalletAccountsErrorHandlerTest { userTokensSaver = userTokensSaver, userTokensResponseStore = userTokensResponseStore, defaultWalletAccountsResponseFactory = defaultWalletAccountsResponseFactory, - eTagsStore = eTagsStore, dispatchers = TestingCoroutineDispatcherProvider(), ) - private val pushWalletAccounts: suspend (UserWalletId, List) -> GetWalletAccountsResponse = + private val pushWalletAccounts: suspend (List, String) -> GetWalletAccountsResponse = mockk(relaxed = true) private val storeWalletAccounts: suspend (UserWalletId, GetWalletAccountsResponse) -> Unit = mockk(relaxed = true) @BeforeEach fun setupEach() { clearMocks( + tangemTechApi, + userWalletsStore, userTokensSaver, userTokensResponseStore, defaultWalletAccountsResponseFactory, @@ -129,7 +128,7 @@ class FetchWalletAccountsErrorHandlerTest { ), ) } returns apiResponse - coEvery { pushWalletAccounts(userWalletId, listOf(accountDTO)) } returns savedAccountsResponse + coEvery { pushWalletAccounts(listOf(accountDTO), eTagValue) } returns savedAccountsResponse // Act handler.handle( @@ -150,8 +149,7 @@ class FetchWalletAccountsErrorHandlerTest { walletType = WalletType.COLD, ), ) - eTagsStore.store(userWalletId, ETagsStore.Key.WalletAccounts, eTagValue) - pushWalletAccounts(userWalletId, listOf(accountDTO)) + pushWalletAccounts(listOf(accountDTO), eTagValue) storeWalletAccounts(userWalletId, savedAccountsResponse) }