Updated on 2026-08-14

This commit is contained in:
Tangem 2026-07-21 11:38:46 +03:00
parent e6faa0a588
commit beeb77543b
2 changed files with 41 additions and 1 deletions

View file

@ -14,6 +14,8 @@ import com.tangem.domain.pushnotificationpreferences.models.PushNotificationCate
import com.tangem.domain.pushnotificationpreferences.models.WalletPushNotificationPreferences import com.tangem.domain.pushnotificationpreferences.models.WalletPushNotificationPreferences
import com.tangem.domain.pushnotificationpreferences.repository.WalletPushNotificationPreferencesRepository import com.tangem.domain.pushnotificationpreferences.repository.WalletPushNotificationPreferencesRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.runSuspendCatching
import com.tangem.utils.logging.TangemLogger
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@ -49,6 +51,16 @@ internal class DefaultWalletPushNotificationPreferencesRepository(
} }
override suspend fun preload(userWalletId: UserWalletId) { override suspend fun preload(userWalletId: UserWalletId) {
runSuspendCatching { preloadOrThrow(userWalletId) }
.onFailure { error ->
TangemLogger.e(
"Failed to preload push notification preferences for wallet ${userWalletId.stringValue}",
error,
)
}
}
private suspend fun preloadOrThrow(userWalletId: UserWalletId) {
if (isCached(userWalletId)) return if (isCached(userWalletId)) return
mutexFor(userWalletId).withLock { mutexFor(userWalletId).withLock {
if (isCached(userWalletId)) return if (isCached(userWalletId)) return
@ -64,7 +76,7 @@ internal class DefaultWalletPushNotificationPreferencesRepository(
} }
override fun observePreferences(userWalletId: UserWalletId): Flow<WalletPushNotificationPreferences> = cache.get() override fun observePreferences(userWalletId: UserWalletId): Flow<WalletPushNotificationPreferences> = cache.get()
.onStart { preload(userWalletId) } .onStart { preloadOrThrow(userWalletId) }
.map { it[userWalletId.stringValue] } .map { it[userWalletId.stringValue] }
.filterNotNull() .filterNotNull()
.distinctUntilChanged() .distinctUntilChanged()

View file

@ -76,6 +76,34 @@ class DefaultWalletPushNotificationPreferencesRepositoryTest {
coVerify(exactly = 1) { tangemTechApi.getPushNotificationPreferences(userWalletId.stringValue) } coVerify(exactly = 1) { tangemTechApi.getPushNotificationPreferences(userWalletId.stringValue) }
} }
@Test
fun `GIVEN server fails WHEN preload THEN does not throw AND does not cache`() = runTest {
// Arrange
coEvery { tangemTechApi.getPushNotificationPreferences(userWalletId.stringValue) } throws
IllegalStateException("boom")
// Act
val thrown = runCatching { repository.preload(userWalletId) }.exceptionOrNull()
// Assert
assertThat(thrown).isNull()
stubGet(userWalletId, transaction = true, offers = true, price = false)
repository.preload(userWalletId)
coVerify(exactly = 2) { tangemTechApi.getPushNotificationPreferences(userWalletId.stringValue) }
}
@Test
fun `GIVEN server fails WHEN observePreferences THEN flow errors for collectors`() = runTest {
// Arrange
coEvery { tangemTechApi.getPushNotificationPreferences(userWalletId.stringValue) } throws
IllegalStateException("boom")
// Act & Assert
repository.observePreferences(userWalletId).test {
assertThat(awaitError()).isInstanceOf(IllegalStateException::class.java)
}
}
@Test @Test
fun `GIVEN cache miss WHEN updatePreference THEN fetches baseline AND sends full-replace PUT AND caches echo`() = fun `GIVEN cache miss WHEN updatePreference THEN fetches baseline AND sends full-replace PUT AND caches echo`() =
runTest { runTest {