Updated on 2026-08-14
This commit is contained in:
parent
41164b1baf
commit
54e612cf30
9 changed files with 200 additions and 18 deletions
|
|
@ -83,4 +83,14 @@ internal object NotificationsDomainModule {
|
||||||
): GetNetworksAvailableForNotificationsUseCase {
|
): GetNetworksAvailableForNotificationsUseCase {
|
||||||
return GetNetworksAvailableForNotificationsUseCase(pushNotificationsRepository = pushNotificationsRepository)
|
return GetNetworksAvailableForNotificationsUseCase(pushNotificationsRepository = pushNotificationsRepository)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideClearApplicationIdUseCase(
|
||||||
|
pushNotificationsRepository: PushNotificationsRepository,
|
||||||
|
): ClearApplicationIdUseCase {
|
||||||
|
return ClearApplicationIdUseCase(
|
||||||
|
pushNotificationsRepository = pushNotificationsRepository,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -21,9 +21,11 @@ import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||||
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
|
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
|
||||||
import com.tangem.domain.balancehiding.UpdateBalanceHidingSettingsUseCase
|
import com.tangem.domain.balancehiding.UpdateBalanceHidingSettingsUseCase
|
||||||
import com.tangem.domain.models.wallet.UserWallet
|
import com.tangem.domain.models.wallet.UserWallet
|
||||||
|
import com.tangem.domain.notifications.ClearApplicationIdUseCase
|
||||||
import com.tangem.domain.notifications.GetApplicationIdUseCase
|
import com.tangem.domain.notifications.GetApplicationIdUseCase
|
||||||
import com.tangem.domain.notifications.SendPushTokenUseCase
|
import com.tangem.domain.notifications.SendPushTokenUseCase
|
||||||
import com.tangem.domain.notifications.models.ApplicationId
|
import com.tangem.domain.notifications.models.ApplicationId
|
||||||
|
import com.tangem.domain.notifications.models.NotificationsError
|
||||||
import com.tangem.domain.onramp.FetchHotCryptoUseCase
|
import com.tangem.domain.onramp.FetchHotCryptoUseCase
|
||||||
import com.tangem.domain.promo.GetStoryContentUseCase
|
import com.tangem.domain.promo.GetStoryContentUseCase
|
||||||
import com.tangem.domain.promo.models.StoryContentIds
|
import com.tangem.domain.promo.models.StoryContentIds
|
||||||
|
|
@ -72,6 +74,7 @@ internal class MainViewModel @Inject constructor(
|
||||||
private val getApplicationIdUseCase: GetApplicationIdUseCase,
|
private val getApplicationIdUseCase: GetApplicationIdUseCase,
|
||||||
private val subscribeOnWalletsUseCase: GetSavedWalletsCountUseCase,
|
private val subscribeOnWalletsUseCase: GetSavedWalletsCountUseCase,
|
||||||
private val associateWalletsWithApplicationIdUseCase: AssociateWalletsWithApplicationIdUseCase,
|
private val associateWalletsWithApplicationIdUseCase: AssociateWalletsWithApplicationIdUseCase,
|
||||||
|
private val clearApplicationIdUseCase: ClearApplicationIdUseCase,
|
||||||
private val updateRemoteWalletsInfoUseCase: UpdateRemoteWalletsInfoUseCase,
|
private val updateRemoteWalletsInfoUseCase: UpdateRemoteWalletsInfoUseCase,
|
||||||
private val sendPushTokenUseCase: SendPushTokenUseCase,
|
private val sendPushTokenUseCase: SendPushTokenUseCase,
|
||||||
private val apiConfigsManager: ApiConfigsManager,
|
private val apiConfigsManager: ApiConfigsManager,
|
||||||
|
|
@ -104,7 +107,7 @@ internal class MainViewModel @Inject constructor(
|
||||||
|
|
||||||
launch { fetchStakingOptions() }
|
launch { fetchStakingOptions() }
|
||||||
|
|
||||||
launch { initPushNotifications() }
|
launch(dispatchers.default) { initPushNotifications() }
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModelScope.launch { incrementAppLaunchCounterUseCase() }
|
viewModelScope.launch { incrementAppLaunchCounterUseCase() }
|
||||||
|
|
@ -398,13 +401,27 @@ internal class MainViewModel @Inject constructor(
|
||||||
private suspend fun initPushNotifications() {
|
private suspend fun initPushNotifications() {
|
||||||
getApplicationIdUseCase()
|
getApplicationIdUseCase()
|
||||||
.onRight { applicationId ->
|
.onRight { applicationId ->
|
||||||
sendPushTokenUseCase(applicationId = applicationId)
|
sendPushTokenUseCase(applicationId = applicationId).onLeft { error ->
|
||||||
associateWalletsWithApplicationId(applicationId = applicationId)
|
if (error is NotificationsError.ApplicationIdNotFound) {
|
||||||
updateRemoteWalletsInfoUseCase(applicationId = applicationId)
|
clearApplicationIdUseCase()
|
||||||
|
getApplicationIdUseCase().onRight { newApplicationId ->
|
||||||
|
associateAndUpdateWallets(applicationId = newApplicationId)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
associateAndUpdateWallets(applicationId = applicationId)
|
||||||
|
}
|
||||||
|
}.onRight {
|
||||||
|
associateAndUpdateWallets(applicationId = applicationId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.onLeft(Timber::e)
|
.onLeft(Timber::e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun associateAndUpdateWallets(applicationId: ApplicationId) {
|
||||||
|
associateWalletsWithApplicationId(applicationId = applicationId)
|
||||||
|
updateRemoteWalletsInfoUseCase(applicationId = applicationId)
|
||||||
|
}
|
||||||
|
|
||||||
private fun associateWalletsWithApplicationId(applicationId: ApplicationId) {
|
private fun associateWalletsWithApplicationId(applicationId: ApplicationId) {
|
||||||
subscribeOnWalletsUseCase()
|
subscribeOnWalletsUseCase()
|
||||||
.onEach { wallets ->
|
.onEach { wallets ->
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
package com.tangem.data.notifications
|
package com.tangem.data.notifications
|
||||||
|
|
||||||
|
import androidx.datastore.preferences.core.edit
|
||||||
|
import arrow.core.Either
|
||||||
|
import arrow.core.left
|
||||||
|
import arrow.core.right
|
||||||
import com.tangem.data.notifications.converters.NotificationsEligibleNetworkConverter
|
import com.tangem.data.notifications.converters.NotificationsEligibleNetworkConverter
|
||||||
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
|
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||||
import com.tangem.datasource.api.common.response.getOrThrow
|
import com.tangem.datasource.api.common.response.getOrThrow
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.api.tangemTech.models.NotificationApplicationCreateBody
|
import com.tangem.datasource.api.tangemTech.models.NotificationApplicationCreateBody
|
||||||
|
|
@ -9,6 +15,7 @@ import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
import com.tangem.datasource.local.preferences.utils.*
|
import com.tangem.datasource.local.preferences.utils.*
|
||||||
import com.tangem.domain.notifications.models.ApplicationId
|
import com.tangem.domain.notifications.models.ApplicationId
|
||||||
|
import com.tangem.domain.notifications.models.NotificationsError
|
||||||
import com.tangem.domain.notifications.repository.PushNotificationsRepository
|
import com.tangem.domain.notifications.repository.PushNotificationsRepository
|
||||||
import com.tangem.domain.notifications.models.NotificationsEligibleNetwork
|
import com.tangem.domain.notifications.models.NotificationsEligibleNetwork
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
|
@ -47,9 +54,15 @@ internal class DefaultPushNotificationsRepository @Inject constructor(
|
||||||
?.let(::ApplicationId)
|
?.let(::ApplicationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun sendPushToken(appId: ApplicationId, pushToken: String) {
|
override suspend fun clearApplicationId() {
|
||||||
|
appPreferencesStore.edit { mutablePreferences ->
|
||||||
|
mutablePreferences.remove(PreferencesKeys.NOTIFICATIONS_APPLICATION_ID_KEY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun sendPushToken(appId: ApplicationId, pushToken: String): Either<NotificationsError, Unit> =
|
||||||
withContext(dispatchers.io) {
|
withContext(dispatchers.io) {
|
||||||
tangemTechApi.updatePushTokenForApplicationId(
|
val response = tangemTechApi.updatePushTokenForApplicationId(
|
||||||
appId.value,
|
appId.value,
|
||||||
NotificationApplicationCreateBody(
|
NotificationApplicationCreateBody(
|
||||||
pushToken = pushToken,
|
pushToken = pushToken,
|
||||||
|
|
@ -58,9 +71,21 @@ internal class DefaultPushNotificationsRepository @Inject constructor(
|
||||||
timezone = appInfoProvider.timezone,
|
timezone = appInfoProvider.timezone,
|
||||||
version = appInfoProvider.appVersion,
|
version = appInfoProvider.appVersion,
|
||||||
),
|
),
|
||||||
).getOrThrow()
|
)
|
||||||
|
when (response) {
|
||||||
|
is ApiResponse.Success -> Unit.right()
|
||||||
|
is ApiResponse.Error -> {
|
||||||
|
val cause = response.cause
|
||||||
|
if (cause is ApiResponseError.HttpException &&
|
||||||
|
cause.code == ApiResponseError.HttpException.Code.NOT_FOUND
|
||||||
|
) {
|
||||||
|
NotificationsError.ApplicationIdNotFound.left()
|
||||||
|
} else {
|
||||||
|
NotificationsError.DataError(cause.message ?: "Unknown error").left()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun getEligibleNetworks(): List<NotificationsEligibleNetwork> = withContext(dispatchers.io) {
|
override suspend fun getEligibleNetworks(): List<NotificationsEligibleNetwork> = withContext(dispatchers.io) {
|
||||||
tangemTechApi.getEligibleNetworksForPushNotifications().getOrThrow().mapNotNull {
|
tangemTechApi.getEligibleNetworksForPushNotifications().getOrThrow().mapNotNull {
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,12 @@ import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import com.tangem.data.notifications.converters.NotificationsEligibleNetworkConverter
|
import com.tangem.data.notifications.converters.NotificationsEligibleNetworkConverter
|
||||||
|
import arrow.core.Either
|
||||||
import com.tangem.datasource.api.common.response.ApiResponse
|
import com.tangem.datasource.api.common.response.ApiResponse
|
||||||
|
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||||
import com.tangem.datasource.api.tangemTech.models.*
|
import com.tangem.datasource.api.tangemTech.models.*
|
||||||
import com.tangem.domain.notifications.models.ApplicationId
|
import com.tangem.domain.notifications.models.ApplicationId
|
||||||
|
import com.tangem.domain.notifications.models.NotificationsError
|
||||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
import io.mockk.coVerify
|
import io.mockk.coVerify
|
||||||
|
|
@ -107,7 +110,20 @@ class DefaultPushNotificationsRepositoryTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN application id and push token WHEN sendPushToken THEN updates push token`() = runTest {
|
fun `GIVEN stored application id WHEN clearApplicationId THEN removes it from preferences`() = runTest {
|
||||||
|
// GIVEN
|
||||||
|
val preferences = mockk<Preferences>(relaxed = true)
|
||||||
|
coEvery { preferencesDataStore.updateData(any()) } returns preferences
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
repository.clearApplicationId()
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
coVerify { preferencesDataStore.updateData(any()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN application id and push token WHEN sendPushToken succeeds THEN returns Right Unit`() = runTest {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
val appId = ApplicationId("test-app-id")
|
val appId = ApplicationId("test-app-id")
|
||||||
val pushToken = "test-push-token"
|
val pushToken = "test-push-token"
|
||||||
|
|
@ -130,9 +146,10 @@ class DefaultPushNotificationsRepositoryTest {
|
||||||
} returns ApiResponse.Success(Unit)
|
} returns ApiResponse.Success(Unit)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
repository.sendPushToken(appId, pushToken)
|
val result = repository.sendPushToken(appId, pushToken)
|
||||||
|
|
||||||
// THEN
|
// THEN
|
||||||
|
assertThat(result).isEqualTo(Either.Right(Unit))
|
||||||
coVerify {
|
coVerify {
|
||||||
tangemTechApi.updatePushTokenForApplicationId(
|
tangemTechApi.updatePushTokenForApplicationId(
|
||||||
appId.value,
|
appId.value,
|
||||||
|
|
@ -147,6 +164,59 @@ class DefaultPushNotificationsRepositoryTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN application id not found WHEN sendPushToken THEN returns Left ApplicationIdNotFound`() = runTest {
|
||||||
|
// GIVEN
|
||||||
|
val appId = ApplicationId("test-app-id")
|
||||||
|
val pushToken = "test-push-token"
|
||||||
|
coEvery { appInfoProvider.osVersion } returns "11"
|
||||||
|
coEvery { appInfoProvider.language } returns "en"
|
||||||
|
coEvery { appInfoProvider.appVersion } returns "5.21.1"
|
||||||
|
coEvery { appInfoProvider.timezone } returns "UTC"
|
||||||
|
coEvery {
|
||||||
|
tangemTechApi.updatePushTokenForApplicationId(any(), any())
|
||||||
|
} returns (ApiResponse.Error(
|
||||||
|
ApiResponseError.HttpException(
|
||||||
|
code = ApiResponseError.HttpException.Code.NOT_FOUND,
|
||||||
|
message = "Not found",
|
||||||
|
errorBody = null,
|
||||||
|
),
|
||||||
|
) as ApiResponse<Unit>)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
val result = repository.sendPushToken(appId, pushToken)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
assertThat(result).isEqualTo(Either.Left(NotificationsError.ApplicationIdNotFound))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN api error WHEN sendPushToken THEN returns Left DataError`() = runTest {
|
||||||
|
// GIVEN
|
||||||
|
val appId = ApplicationId("test-app-id")
|
||||||
|
val pushToken = "test-push-token"
|
||||||
|
val errorMessage = "Server error"
|
||||||
|
coEvery { appInfoProvider.osVersion } returns "11"
|
||||||
|
coEvery { appInfoProvider.language } returns "en"
|
||||||
|
coEvery { appInfoProvider.appVersion } returns "5.21.1"
|
||||||
|
coEvery { appInfoProvider.timezone } returns "UTC"
|
||||||
|
coEvery {
|
||||||
|
tangemTechApi.updatePushTokenForApplicationId(any(), any())
|
||||||
|
} returns (ApiResponse.Error(
|
||||||
|
ApiResponseError.HttpException(
|
||||||
|
code = ApiResponseError.HttpException.Code.BAD_REQUEST,
|
||||||
|
message = errorMessage,
|
||||||
|
errorBody = null,
|
||||||
|
),
|
||||||
|
) as ApiResponse<Unit>)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
val result = repository.sendPushToken(appId, pushToken)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
assertThat(result).isEqualTo(Either.Left(NotificationsError.DataError(errorMessage)))
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN eligible networks WHEN getEligibleNetworks THEN returns converted networks`() = runTest {
|
fun `GIVEN eligible networks WHEN getEligibleNetworks THEN returns converted networks`() = runTest {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.tangem.domain.notifications.models
|
||||||
|
|
||||||
|
sealed class NotificationsError {
|
||||||
|
|
||||||
|
data class DataError(val message: String) : NotificationsError()
|
||||||
|
|
||||||
|
data object ApplicationIdNotFound : NotificationsError()
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.tangem.domain.notifications
|
||||||
|
|
||||||
|
import com.tangem.domain.notifications.repository.PushNotificationsRepository
|
||||||
|
|
||||||
|
class ClearApplicationIdUseCase(
|
||||||
|
private val pushNotificationsRepository: PushNotificationsRepository,
|
||||||
|
) {
|
||||||
|
|
||||||
|
suspend operator fun invoke() {
|
||||||
|
pushNotificationsRepository.clearApplicationId()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package com.tangem.domain.notifications
|
package com.tangem.domain.notifications
|
||||||
|
|
||||||
import arrow.core.Either
|
import arrow.core.Either
|
||||||
|
import arrow.core.raise.either
|
||||||
import com.tangem.domain.notifications.models.ApplicationId
|
import com.tangem.domain.notifications.models.ApplicationId
|
||||||
|
import com.tangem.domain.notifications.models.NotificationsError
|
||||||
import com.tangem.domain.notifications.repository.PushNotificationsRepository
|
import com.tangem.domain.notifications.repository.PushNotificationsRepository
|
||||||
import com.tangem.utils.notifications.PushNotificationsTokenProvider
|
import com.tangem.utils.notifications.PushNotificationsTokenProvider
|
||||||
|
|
||||||
|
|
@ -10,8 +12,8 @@ class SendPushTokenUseCase(
|
||||||
private val pushNotificationsTokenProvider: PushNotificationsTokenProvider,
|
private val pushNotificationsTokenProvider: PushNotificationsTokenProvider,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend operator fun invoke(applicationId: ApplicationId): Either<Throwable, Unit> = Either.catch {
|
suspend operator fun invoke(applicationId: ApplicationId): Either<NotificationsError, Unit> = either {
|
||||||
val token = pushNotificationsTokenProvider.getToken()
|
val token = pushNotificationsTokenProvider.getToken()
|
||||||
pushNotificationsRepository.sendPushToken(applicationId, token)
|
pushNotificationsRepository.sendPushToken(applicationId, token).bind()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package com.tangem.domain.notifications.repository
|
package com.tangem.domain.notifications.repository
|
||||||
|
|
||||||
|
import arrow.core.Either
|
||||||
import com.tangem.domain.notifications.models.ApplicationId
|
import com.tangem.domain.notifications.models.ApplicationId
|
||||||
import com.tangem.domain.notifications.models.NotificationsEligibleNetwork
|
import com.tangem.domain.notifications.models.NotificationsEligibleNetwork
|
||||||
|
import com.tangem.domain.notifications.models.NotificationsError
|
||||||
|
|
||||||
interface PushNotificationsRepository {
|
interface PushNotificationsRepository {
|
||||||
|
|
||||||
|
|
@ -12,8 +14,9 @@ interface PushNotificationsRepository {
|
||||||
|
|
||||||
suspend fun getApplicationId(): ApplicationId?
|
suspend fun getApplicationId(): ApplicationId?
|
||||||
|
|
||||||
@Throws
|
suspend fun clearApplicationId()
|
||||||
suspend fun sendPushToken(appId: ApplicationId, pushToken: String)
|
|
||||||
|
suspend fun sendPushToken(appId: ApplicationId, pushToken: String): Either<NotificationsError, Unit>
|
||||||
|
|
||||||
@Throws
|
@Throws
|
||||||
suspend fun getEligibleNetworks(): List<NotificationsEligibleNetwork>
|
suspend fun getEligibleNetworks(): List<NotificationsEligibleNetwork>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.tangem.domain.notifications
|
||||||
import arrow.core.Either
|
import arrow.core.Either
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import com.tangem.domain.notifications.models.ApplicationId
|
import com.tangem.domain.notifications.models.ApplicationId
|
||||||
|
import com.tangem.domain.notifications.models.NotificationsError
|
||||||
import com.tangem.domain.notifications.repository.PushNotificationsRepository
|
import com.tangem.domain.notifications.repository.PushNotificationsRepository
|
||||||
import com.tangem.utils.notifications.PushNotificationsTokenProvider
|
import com.tangem.utils.notifications.PushNotificationsTokenProvider
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
|
|
@ -34,7 +35,7 @@ class SendPushTokenUseCaseTest {
|
||||||
val applicationId = ApplicationId("test-app-id")
|
val applicationId = ApplicationId("test-app-id")
|
||||||
val token = "test-token"
|
val token = "test-token"
|
||||||
coEvery { pushNotificationsTokenProvider.getToken() } returns token
|
coEvery { pushNotificationsTokenProvider.getToken() } returns token
|
||||||
coEvery { pushNotificationsRepository.sendPushToken(applicationId, token) } returns Unit
|
coEvery { pushNotificationsRepository.sendPushToken(applicationId, token) } returns Either.Right(Unit)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
val result = sendPushTokenUseCase(applicationId)
|
val result = sendPushTokenUseCase(applicationId)
|
||||||
|
|
@ -45,13 +46,13 @@ class SendPushTokenUseCaseTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN repository throws error WHEN invoke THEN returns error`() = runTest {
|
fun `GIVEN repository returns DataError WHEN invoke THEN returns DataError`() = runTest {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
val applicationId = ApplicationId("test-app-id")
|
val applicationId = ApplicationId("test-app-id")
|
||||||
val token = "test-token"
|
val token = "test-token"
|
||||||
val expectedError = RuntimeException("Network error")
|
val expectedError = NotificationsError.DataError("Network error")
|
||||||
coEvery { pushNotificationsTokenProvider.getToken() } returns token
|
coEvery { pushNotificationsTokenProvider.getToken() } returns token
|
||||||
coEvery { pushNotificationsRepository.sendPushToken(applicationId, token) } throws expectedError
|
coEvery { pushNotificationsRepository.sendPushToken(applicationId, token) } returns Either.Left(expectedError)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
val result = sendPushTokenUseCase(applicationId)
|
val result = sendPushTokenUseCase(applicationId)
|
||||||
|
|
@ -60,4 +61,38 @@ class SendPushTokenUseCaseTest {
|
||||||
assertThat(result).isEqualTo(Either.Left(expectedError))
|
assertThat(result).isEqualTo(Either.Left(expectedError))
|
||||||
coVerify(exactly = 1) { pushNotificationsRepository.sendPushToken(applicationId, token) }
|
coVerify(exactly = 1) { pushNotificationsRepository.sendPushToken(applicationId, token) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN repository returns ApplicationIdNotFound WHEN invoke THEN returns ApplicationIdNotFound`() = runTest {
|
||||||
|
// GIVEN
|
||||||
|
val applicationId = ApplicationId("test-app-id")
|
||||||
|
val token = "test-token"
|
||||||
|
coEvery { pushNotificationsTokenProvider.getToken() } returns token
|
||||||
|
coEvery {
|
||||||
|
pushNotificationsRepository.sendPushToken(applicationId, token)
|
||||||
|
} returns Either.Left(NotificationsError.ApplicationIdNotFound)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
val result = sendPushTokenUseCase(applicationId)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
assertThat(result).isEqualTo(Either.Left(NotificationsError.ApplicationIdNotFound))
|
||||||
|
coVerify(exactly = 1) { pushNotificationsRepository.sendPushToken(applicationId, token) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `GIVEN empty token WHEN invoke THEN sends empty token to repository`() = runTest {
|
||||||
|
// GIVEN
|
||||||
|
val applicationId = ApplicationId("test-app-id")
|
||||||
|
val emptyToken = ""
|
||||||
|
coEvery { pushNotificationsTokenProvider.getToken() } returns emptyToken
|
||||||
|
coEvery { pushNotificationsRepository.sendPushToken(applicationId, emptyToken) } returns Either.Right(Unit)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
val result = sendPushTokenUseCase(applicationId)
|
||||||
|
|
||||||
|
// THEN
|
||||||
|
assertThat(result).isEqualTo(Either.Right(Unit))
|
||||||
|
coVerify(exactly = 1) { pushNotificationsRepository.sendPushToken(applicationId, emptyToken) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue