Updated on 2026-08-14
This commit is contained in:
parent
9491a9cae6
commit
9abc118480
7 changed files with 91 additions and 66 deletions
|
|
@ -10,9 +10,9 @@ import com.tangem.data.account.store.ArchivedAccountsStoreFactory
|
|||
import com.tangem.data.account.tokens.DefaultMainAccountTokensMigration
|
||||
import com.tangem.data.common.account.WalletAccountsFetcher
|
||||
import com.tangem.data.common.account.WalletAccountsSaver
|
||||
import com.tangem.data.common.cache.etag.ETagsStore
|
||||
import com.tangem.data.common.currency.UserTokensSaver
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.local.datastore.RuntimeStateStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.repository.AccountsCRUDRepository
|
||||
|
|
@ -42,7 +42,6 @@ internal object AccountDataModule {
|
|||
accountsResponseStoreFactory: AccountsResponseStoreFactory,
|
||||
userWalletsStore: UserWalletsStore,
|
||||
userTokensSaver: UserTokensSaver,
|
||||
eTagsStore: ETagsStore,
|
||||
accountConverterFactoryContainer: AccountConverterFactoryContainer,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): AccountsCRUDRepository {
|
||||
|
|
@ -53,7 +52,7 @@ internal object AccountDataModule {
|
|||
archivedAccountsStoreFactory = ArchivedAccountsStoreFactory,
|
||||
userWalletsStore = userWalletsStore,
|
||||
userTokensSaver = userTokensSaver,
|
||||
eTagsStore = eTagsStore,
|
||||
archivedAccountsETagStore = RuntimeStateStore(emptyMap()),
|
||||
convertersContainer = accountConverterFactoryContainer,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,12 +10,15 @@ import com.tangem.data.account.store.AccountsResponseStoreFactory
|
|||
import com.tangem.data.account.store.ArchivedAccountsStore
|
||||
import com.tangem.data.account.store.ArchivedAccountsStoreFactory
|
||||
import com.tangem.data.common.account.WalletAccountsSaver
|
||||
import com.tangem.data.common.cache.etag.ETagsStore
|
||||
import com.tangem.data.common.api.safeApiCall
|
||||
import com.tangem.data.common.currency.UserTokensSaver
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError.HttpException
|
||||
import com.tangem.datasource.api.common.response.ETAG_HEADER
|
||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
|
||||
import com.tangem.datasource.local.datastore.RuntimeStateStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.datasource.utils.getSyncOrNull
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
|
|
@ -43,7 +46,7 @@ internal class DefaultAccountsCRUDRepository(
|
|||
private val archivedAccountsStoreFactory: ArchivedAccountsStoreFactory,
|
||||
private val userWalletsStore: UserWalletsStore,
|
||||
private val userTokensSaver: UserTokensSaver,
|
||||
private val eTagsStore: ETagsStore,
|
||||
private val archivedAccountsETagStore: RuntimeStateStore<Map<String, String?>>,
|
||||
private val convertersContainer: AccountConverterFactoryContainer,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : AccountsCRUDRepository {
|
||||
|
|
@ -90,19 +93,38 @@ internal class DefaultAccountsCRUDRepository(
|
|||
}
|
||||
|
||||
override suspend fun fetchArchivedAccounts(userWalletId: UserWalletId) {
|
||||
val response = withContext(dispatchers.io) {
|
||||
tangemTechApi.getWalletArchivedAccounts(
|
||||
walletId = userWalletId.stringValue,
|
||||
eTag = getETag(userWalletId),
|
||||
).getOrThrow()
|
||||
}
|
||||
|
||||
val eTag = archivedAccountsETagStore.getSyncOrNull()?.get(key = userWalletId.stringValue)
|
||||
val store = getArchivedAccountsStore(userWalletId = userWalletId)
|
||||
val converter = ArchivedAccountConverter(userWalletId = userWalletId)
|
||||
|
||||
val archivedAccounts = converter.convertList(input = response.accounts)
|
||||
val response = safeApiCall(
|
||||
call = {
|
||||
val apiResponse = withContext(dispatchers.io) {
|
||||
tangemTechApi.getWalletArchivedAccounts(
|
||||
walletId = userWalletId.stringValue,
|
||||
eTag = eTag,
|
||||
)
|
||||
}
|
||||
|
||||
store.store(value = archivedAccounts)
|
||||
saveETag(userWalletId, apiResponse)
|
||||
|
||||
apiResponse.bind()
|
||||
},
|
||||
onError = {
|
||||
if (it is HttpException && it.code == HttpException.Code.NOT_MODIFIED) {
|
||||
null
|
||||
} else {
|
||||
throw it
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
if (response != null) {
|
||||
val converter = ArchivedAccountConverter(userWalletId = userWalletId)
|
||||
|
||||
val archivedAccounts = converter.convertList(input = response.accounts)
|
||||
|
||||
store.store(value = archivedAccounts)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun saveAccounts(accountList: AccountList) {
|
||||
|
|
@ -167,8 +189,12 @@ internal class DefaultAccountsCRUDRepository(
|
|||
|
||||
override fun getUserWalletsSync(): List<UserWallet> = userWalletsStore.userWalletsSync
|
||||
|
||||
private suspend fun getETag(userWalletId: UserWalletId): String? {
|
||||
return eTagsStore.getSyncOrNull(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts)
|
||||
private suspend fun saveETag(userWalletId: UserWalletId, apiResponse: ApiResponse<*>) {
|
||||
val eTag = apiResponse.headers[ETAG_HEADER]?.firstOrNull()
|
||||
|
||||
archivedAccountsETagStore.update {
|
||||
it + (userWalletId.stringValue to eTag)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getAccountsResponseSync(userWalletId: UserWalletId): GetWalletAccountsResponse? {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import com.tangem.data.account.store.AccountsResponseStoreFactory
|
|||
import com.tangem.data.account.store.ArchivedAccountsStore
|
||||
import com.tangem.data.account.store.ArchivedAccountsStoreFactory
|
||||
import com.tangem.data.common.account.WalletAccountsSaver
|
||||
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.tangemTech.TangemTechApi
|
||||
|
|
@ -54,7 +53,7 @@ class DefaultAccountsCRUDRepositoryTest {
|
|||
|
||||
private val userWalletsStore: UserWalletsStore = mockk()
|
||||
private val userTokensSaver: UserTokensSaver = mockk()
|
||||
private val eTagsStore: ETagsStore = mockk()
|
||||
private val archivedAccountsETagStore: RuntimeStateStore<Map<String, String?>> = mockk(relaxUnitFun = true)
|
||||
|
||||
private val convertersContainer: AccountConverterFactoryContainer = mockk()
|
||||
private val accountListConverter: AccountListConverter = mockk()
|
||||
|
|
@ -67,7 +66,7 @@ class DefaultAccountsCRUDRepositoryTest {
|
|||
archivedAccountsStoreFactory = archivedAccountsStoreFactory,
|
||||
userWalletsStore = userWalletsStore,
|
||||
userTokensSaver = userTokensSaver,
|
||||
eTagsStore = eTagsStore,
|
||||
archivedAccountsETagStore = archivedAccountsETagStore,
|
||||
convertersContainer = convertersContainer,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
)
|
||||
|
|
@ -532,7 +531,7 @@ class DefaultAccountsCRUDRepositoryTest {
|
|||
|
||||
val archivedAccount = ArchivedAccountConverter(userWalletId).convert(accountDTO)
|
||||
|
||||
coEvery { eTagsStore.getSyncOrNull(userWalletId, ETagsStore.Key.WalletAccounts) } returns eTag
|
||||
coEvery { archivedAccountsETagStore.getSyncOrNull() } returns mapOf(userWalletId.stringValue to eTag)
|
||||
|
||||
coEvery {
|
||||
tangemTechApi.getWalletArchivedAccounts(userWalletId.stringValue, eTag)
|
||||
|
|
@ -546,9 +545,10 @@ class DefaultAccountsCRUDRepositoryTest {
|
|||
Truth.assertThat(actual).containsExactly(archivedAccount)
|
||||
|
||||
coVerifyOrder {
|
||||
eTagsStore.getSyncOrNull(userWalletId, ETagsStore.Key.WalletAccounts)
|
||||
tangemTechApi.getWalletArchivedAccounts(userWalletId.stringValue, eTag)
|
||||
archivedAccountsETagStore.getSyncOrNull()
|
||||
archivedAccountsStoreFactory.create(userWalletId)
|
||||
tangemTechApi.getWalletArchivedAccounts(userWalletId.stringValue, eTag)
|
||||
archivedAccountsETagStore.update(any())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -558,7 +558,7 @@ class DefaultAccountsCRUDRepositoryTest {
|
|||
val eTag = "etag123"
|
||||
val exception = Exception("API error")
|
||||
|
||||
coEvery { eTagsStore.getSyncOrNull(userWalletId, ETagsStore.Key.WalletAccounts) } returns eTag
|
||||
coEvery { archivedAccountsETagStore.getSyncOrNull() } returns mapOf(userWalletId.stringValue to eTag)
|
||||
coEvery { tangemTechApi.getWalletArchivedAccounts(userWalletId.stringValue, eTag) } throws exception
|
||||
|
||||
// Act
|
||||
|
|
@ -570,7 +570,7 @@ class DefaultAccountsCRUDRepositoryTest {
|
|||
Truth.assertThat(archivedAccountsStore.getSyncOrNull()).isNull()
|
||||
|
||||
coVerifyOrder {
|
||||
eTagsStore.getSyncOrNull(userWalletId, ETagsStore.Key.WalletAccounts)
|
||||
archivedAccountsETagStore.getSyncOrNull()
|
||||
tangemTechApi.getWalletArchivedAccounts(userWalletId.stringValue, eTag)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue