Updated on 2026-08-14
This commit is contained in:
parent
41164b1baf
commit
54e612cf30
9 changed files with 200 additions and 18 deletions
|
|
@ -1,6 +1,12 @@
|
|||
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.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.tangemTech.TangemTechApi
|
||||
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.utils.*
|
||||
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.models.NotificationsEligibleNetwork
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -47,9 +54,15 @@ internal class DefaultPushNotificationsRepository @Inject constructor(
|
|||
?.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) {
|
||||
tangemTechApi.updatePushTokenForApplicationId(
|
||||
val response = tangemTechApi.updatePushTokenForApplicationId(
|
||||
appId.value,
|
||||
NotificationApplicationCreateBody(
|
||||
pushToken = pushToken,
|
||||
|
|
@ -58,9 +71,21 @@ internal class DefaultPushNotificationsRepository @Inject constructor(
|
|||
timezone = appInfoProvider.timezone,
|
||||
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) {
|
||||
tangemTechApi.getEligibleNetworksForPushNotifications().getOrThrow().mapNotNull {
|
||||
|
|
|
|||
|
|
@ -10,9 +10,12 @@ import com.tangem.datasource.local.preferences.PreferencesKeys
|
|||
import com.google.common.truth.Truth.assertThat
|
||||
import com.squareup.moshi.Moshi
|
||||
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.ApiResponseError
|
||||
import com.tangem.datasource.api.tangemTech.models.*
|
||||
import com.tangem.domain.notifications.models.ApplicationId
|
||||
import com.tangem.domain.notifications.models.NotificationsError
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
|
|
@ -107,7 +110,20 @@ class DefaultPushNotificationsRepositoryTest {
|
|||
}
|
||||
|
||||
@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
|
||||
val appId = ApplicationId("test-app-id")
|
||||
val pushToken = "test-push-token"
|
||||
|
|
@ -130,9 +146,10 @@ class DefaultPushNotificationsRepositoryTest {
|
|||
} returns ApiResponse.Success(Unit)
|
||||
|
||||
// WHEN
|
||||
repository.sendPushToken(appId, pushToken)
|
||||
val result = repository.sendPushToken(appId, pushToken)
|
||||
|
||||
// THEN
|
||||
assertThat(result).isEqualTo(Either.Right(Unit))
|
||||
coVerify {
|
||||
tangemTechApi.updatePushTokenForApplicationId(
|
||||
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
|
||||
fun `GIVEN eligible networks WHEN getEligibleNetworks THEN returns converted networks`() = runTest {
|
||||
// GIVEN
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue