Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-06 17:08:05 +04:00
parent 017eece8b7
commit d96dd19f01
23 changed files with 456 additions and 8 deletions

View file

@ -39,6 +39,18 @@ internal class DefaultETagsStore(
appPreferencesStore.editData { it.remove(storeKey) }
}
override suspend fun clear(userWalletIds: List<UserWalletId>) {
if (userWalletIds.isEmpty()) return
appPreferencesStore.editData { preferences ->
userWalletIds.forEach { userWalletId ->
ETagsStore.Key.entries.forEach { key ->
preferences.remove(getAccountsETagKey(userWalletId = userWalletId, key = key))
}
}
}
}
private fun getAccountsETagKey(userWalletId: UserWalletId, key: ETagsStore.Key): Preferences.Key<String> {
return stringPreferencesKey(name = "etag_${key}_${userWalletId.stringValue}")
}

View file

@ -33,6 +33,13 @@ interface ETagsStore {
*/
suspend fun clear(userWalletId: UserWalletId, key: Key)
/**
* Clears all stored ETag values (every [Key]) for the specified wallets in a single operation
*
* @param userWalletIds identifiers of the user wallets
*/
suspend fun clear(userWalletIds: List<UserWalletId>)
/** Enumeration of possible keys for storing ETag values */
enum class Key {
WalletAccounts,

View file

@ -0,0 +1,68 @@
package com.tangem.data.common.cache.etag
import androidx.datastore.preferences.core.MutablePreferences
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.mutablePreferencesOf
import androidx.datastore.preferences.core.stringPreferencesKey
import com.google.common.truth.Truth.assertThat
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.models.wallet.UserWalletId
import io.mockk.clearMocks
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
import io.mockk.slot
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
internal class DefaultETagsStoreTest {
private val appPreferencesStore: AppPreferencesStore = mockk()
private val store = DefaultETagsStore(appPreferencesStore = appPreferencesStore)
@BeforeEach
fun resetMocks() {
clearMocks(appPreferencesStore)
}
@Test
fun `GIVEN wallets WHEN clear list THEN all keys of all wallets removed in a single edit`() = runTest {
// Arrange
val transform = slot<suspend AppPreferencesStore.(MutablePreferences) -> Unit>()
coEvery { appPreferencesStore.editData(capture(transform)) } returns mutablePreferencesOf()
val preferences = mutablePreferencesOf().apply {
ETagsStore.Key.entries.forEach { key ->
set(stringPreferencesKey("etag_${key}_${WALLET_A.stringValue}"), "a")
set(stringPreferencesKey("etag_${key}_${WALLET_B.stringValue}"), "b")
}
set(stringPreferencesKey("unrelated"), "keep")
}
// Act
store.clear(userWalletIds = listOf(WALLET_A, WALLET_B))
transform.captured.invoke(appPreferencesStore, preferences)
// Assert
coVerify(exactly = 1) { appPreferencesStore.editData(any()) }
assertThat(preferences.asMap().keys.map(Preferences.Key<*>::name)).containsExactly("unrelated")
}
@Test
fun `GIVEN empty list WHEN clear list THEN nothing is edited`() = runTest {
// Act
store.clear(userWalletIds = emptyList())
// Assert
coVerify(exactly = 0) { appPreferencesStore.editData(any()) }
}
private companion object {
val WALLET_A = UserWalletId("011")
val WALLET_B = UserWalletId("022")
}
}