mirror of
https://github.com/bitwarden/android.git
synced 2026-05-20 19:11:33 -05:00
Bug: Support translations for Cookie Acquisition error (#6917)
This commit is contained in:
@@ -89,6 +89,7 @@ import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
||||
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
|
||||
import com.x8bit.bitwarden.data.vault.manager.VaultLockManager
|
||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||
import com.x8bit.bitwarden.ui.platform.manager.resource.ResourceManager
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
@@ -439,10 +440,12 @@ object PlatformManagerModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideNetworkCookieManager(
|
||||
resourceManager: ResourceManager,
|
||||
configDiskSource: ConfigDiskSource,
|
||||
cookieDiskSource: CookieDiskSource,
|
||||
cookieAcquisitionRequestManager: CookieAcquisitionRequestManager,
|
||||
): NetworkCookieManager = NetworkCookieManagerImpl(
|
||||
resourceManager = resourceManager,
|
||||
configDiskSource = configDiskSource,
|
||||
cookieDiskSource = cookieDiskSource,
|
||||
cookieAcquisitionRequestManager = cookieAcquisitionRequestManager,
|
||||
|
||||
@@ -2,11 +2,13 @@ package com.x8bit.bitwarden.data.platform.manager.network
|
||||
|
||||
import com.bitwarden.data.datasource.disk.ConfigDiskSource
|
||||
import com.bitwarden.network.model.NetworkCookie
|
||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.CookieDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.model.CookieConfigurationData
|
||||
import com.x8bit.bitwarden.data.platform.manager.CookieAcquisitionRequestManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.CookieAcquisitionRequest
|
||||
import com.x8bit.bitwarden.data.platform.manager.util.toNetworkCookieList
|
||||
import com.x8bit.bitwarden.ui.platform.manager.resource.ResourceManager
|
||||
import timber.log.Timber
|
||||
|
||||
private const val BOOTSTRAP_TYPE_SSO_COOKIE_VENDOR = "ssoCookieVendor"
|
||||
@@ -15,6 +17,7 @@ private const val BOOTSTRAP_TYPE_SSO_COOKIE_VENDOR = "ssoCookieVendor"
|
||||
* Default implementation of [NetworkCookieManager].
|
||||
*/
|
||||
class NetworkCookieManagerImpl(
|
||||
private val resourceManager: ResourceManager,
|
||||
private val configDiskSource: ConfigDiskSource,
|
||||
private val cookieDiskSource: CookieDiskSource,
|
||||
private val cookieAcquisitionRequestManager: CookieAcquisitionRequestManager,
|
||||
@@ -32,6 +35,12 @@ class NetworkCookieManagerImpl(
|
||||
?.takeIf { it.type == BOOTSTRAP_TYPE_SSO_COOKIE_VENDOR }
|
||||
?.cookieDomain
|
||||
|
||||
override val errorMessageString: String
|
||||
get() = resourceManager.getString(
|
||||
resId = BitwardenString
|
||||
.your_request_was_interrupted_because_the_app_needed_to_reauthenticate,
|
||||
)
|
||||
|
||||
override fun needsBootstrap(hostname: String): Boolean {
|
||||
val result = configDiskSource
|
||||
.serverConfig
|
||||
|
||||
@@ -43,6 +43,7 @@ class GlideCookieInterceptor(
|
||||
response.close()
|
||||
throw CookieRedirectException(
|
||||
hostname = response.request.url.host,
|
||||
message = cookieProvider.errorMessageString,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ import com.bitwarden.data.datasource.disk.model.ServerConfig
|
||||
import com.bitwarden.data.datasource.disk.util.FakeConfigDiskSource
|
||||
import com.bitwarden.network.model.ConfigResponseJson
|
||||
import com.bitwarden.network.model.NetworkCookie
|
||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.CookieDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.model.CookieConfigurationData
|
||||
import com.x8bit.bitwarden.data.platform.manager.CookieAcquisitionRequestManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.CookieAcquisitionRequest
|
||||
import com.x8bit.bitwarden.ui.platform.manager.resource.ResourceManager
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
@@ -20,6 +22,9 @@ import org.junit.jupiter.api.Test
|
||||
|
||||
class NetworkCookieManagerTest {
|
||||
|
||||
private val resourceManager: ResourceManager = mockk {
|
||||
every { getString(resId = any()) } returns ERROR_MESSAGE
|
||||
}
|
||||
private val fakeConfigDiskSource = FakeConfigDiskSource()
|
||||
private val mockCookieDiskSource: CookieDiskSource = mockk()
|
||||
private val mockCookieAcquisitionRequestManager: CookieAcquisitionRequestManager =
|
||||
@@ -28,11 +33,25 @@ class NetworkCookieManagerTest {
|
||||
}
|
||||
|
||||
private val manager = NetworkCookieManagerImpl(
|
||||
resourceManager = resourceManager,
|
||||
configDiskSource = fakeConfigDiskSource,
|
||||
cookieDiskSource = mockCookieDiskSource,
|
||||
cookieAcquisitionRequestManager = mockCookieAcquisitionRequestManager,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `errorMessageString should return appropriate message`() {
|
||||
val result = manager.errorMessageString
|
||||
|
||||
assertEquals(ERROR_MESSAGE, result)
|
||||
verify(exactly = 1) {
|
||||
resourceManager.getString(
|
||||
resId = BitwardenString
|
||||
.your_request_was_interrupted_because_the_app_needed_to_reauthenticate,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `needsBootstrap should return false when serverConfig is null`() {
|
||||
fakeConfigDiskSource.serverConfig = null
|
||||
@@ -284,3 +303,5 @@ private fun createCookieConfig(
|
||||
hostname = hostname,
|
||||
cookies = cookies,
|
||||
)
|
||||
|
||||
private const val ERROR_MESSAGE: String = "Error Message"
|
||||
|
||||
@@ -10,10 +10,14 @@ class ThrowableExtensionsTest {
|
||||
|
||||
@Test
|
||||
fun `userFriendlyMessage should return message for CookieRedirectException`() {
|
||||
val exception = CookieRedirectException(hostname = "example.com")
|
||||
val message = "Your request was interrupted because the app needed to " +
|
||||
"re-authenticate. Please try again."
|
||||
val exception = CookieRedirectException(
|
||||
hostname = "example.com",
|
||||
message = message,
|
||||
)
|
||||
assertEquals(
|
||||
"Your request was interrupted because the app needed to " +
|
||||
"re-authenticate. Please try again.",
|
||||
message,
|
||||
exception.userFriendlyMessage,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2941,7 +2941,9 @@ class CipherManagerTest {
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val cipherId = "mockId-1"
|
||||
val error = CookieRedirectException("test.host")
|
||||
val message = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again."
|
||||
val error = CookieRedirectException(hostname = "test.host", message = message)
|
||||
coEvery {
|
||||
ciphersService.hardDeleteCipher(cipherId = cipherId)
|
||||
} returns error.asFailure()
|
||||
@@ -2950,8 +2952,7 @@ class CipherManagerTest {
|
||||
|
||||
assertEquals(
|
||||
DeleteCipherResult.Error(
|
||||
errorMessage = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again.",
|
||||
errorMessage = message,
|
||||
error = error,
|
||||
),
|
||||
result,
|
||||
@@ -2967,7 +2968,9 @@ class CipherManagerTest {
|
||||
val cipherId = "mockId-1"
|
||||
val cipherView = createMockCipherView(number = 1)
|
||||
val encryptionContext = createMockEncryptionContext(number = 1)
|
||||
val error = CookieRedirectException("test.host")
|
||||
val message = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again."
|
||||
val error = CookieRedirectException(hostname = "test.host", message = message)
|
||||
coEvery {
|
||||
vaultSdkSource.encryptCipher(userId = userId, cipherView = cipherView)
|
||||
} returns encryptionContext.asSuccess()
|
||||
@@ -2982,8 +2985,7 @@ class CipherManagerTest {
|
||||
|
||||
assertEquals(
|
||||
DeleteCipherResult.Error(
|
||||
errorMessage = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again.",
|
||||
errorMessage = message,
|
||||
error = error,
|
||||
),
|
||||
result,
|
||||
@@ -2997,7 +2999,9 @@ class CipherManagerTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val cipherId = "mockId-1"
|
||||
val cipherView = createMockCipherView(number = 1)
|
||||
val error = CookieRedirectException("test.host")
|
||||
val message = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again."
|
||||
val error = CookieRedirectException(hostname = "test.host", message = message)
|
||||
coEvery {
|
||||
ciphersService.restoreCipher(cipherId = cipherId)
|
||||
} returns error.asFailure()
|
||||
@@ -3009,8 +3013,7 @@ class CipherManagerTest {
|
||||
|
||||
assertEquals(
|
||||
RestoreCipherResult.Error(
|
||||
errorMessage = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again.",
|
||||
errorMessage = message,
|
||||
error = error,
|
||||
),
|
||||
result,
|
||||
@@ -3023,7 +3026,9 @@ class CipherManagerTest {
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val cipherId = "mockId-1"
|
||||
val error = CookieRedirectException("test.host")
|
||||
val message = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again."
|
||||
val error = CookieRedirectException(hostname = "test.host", message = message)
|
||||
coEvery {
|
||||
ciphersService.archiveCipher(cipherId = cipherId)
|
||||
} returns error.asFailure()
|
||||
@@ -3035,8 +3040,7 @@ class CipherManagerTest {
|
||||
|
||||
assertEquals(
|
||||
ArchiveCipherResult.Error(
|
||||
errorMessage = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again.",
|
||||
errorMessage = message,
|
||||
error = error,
|
||||
),
|
||||
result,
|
||||
|
||||
@@ -686,7 +686,9 @@ class SendManagerTest {
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val sendId = "mockId-1"
|
||||
val error = CookieRedirectException(hostname = "example.com")
|
||||
val message = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again."
|
||||
val error = CookieRedirectException(hostname = "test.host", message = message)
|
||||
coEvery {
|
||||
sendsService.deleteSend(sendId = sendId)
|
||||
} returns error.asFailure()
|
||||
@@ -695,7 +697,7 @@ class SendManagerTest {
|
||||
|
||||
assertEquals(
|
||||
DeleteSendResult.Error(
|
||||
errorMessage = error.message,
|
||||
errorMessage = message,
|
||||
error = error,
|
||||
),
|
||||
result,
|
||||
|
||||
@@ -102,6 +102,7 @@ class GlideCookieInterceptorTest {
|
||||
every {
|
||||
mockCookieProvider.getCookies("vault.bitwarden.com")
|
||||
} returns emptyList()
|
||||
every { mockCookieProvider.errorMessageString } returns "Error"
|
||||
|
||||
val exception = assertThrows<CookieRedirectException> {
|
||||
interceptor.intercept(chain)
|
||||
@@ -134,6 +135,7 @@ class GlideCookieInterceptorTest {
|
||||
} returns listOf(
|
||||
NetworkCookie(name = "awselb", value = "session123"),
|
||||
)
|
||||
every { mockCookieProvider.errorMessageString } returns "Error"
|
||||
|
||||
val exception = assertThrows<CookieRedirectException> {
|
||||
interceptor.intercept(chain)
|
||||
|
||||
@@ -1760,9 +1760,11 @@ class VaultViewModelTest : BaseViewModelTest() {
|
||||
@Test
|
||||
fun `vaultDataStateFlow Error with CookieRedirectException should show user-friendly message`() =
|
||||
runTest {
|
||||
val message = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again."
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.Error(
|
||||
error = CookieRedirectException(hostname = "example.com"),
|
||||
error = CookieRedirectException(hostname = "example.com", message = message),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1771,10 +1773,7 @@ class VaultViewModelTest : BaseViewModelTest() {
|
||||
assertEquals(
|
||||
createMockVaultState(
|
||||
viewState = VaultState.ViewState.Error(
|
||||
message = (
|
||||
"Your request was interrupted because the app needed to " +
|
||||
"re-authenticate. Please try again."
|
||||
).asText(),
|
||||
message = message.asText(),
|
||||
),
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
@@ -1856,9 +1855,11 @@ class VaultViewModelTest : BaseViewModelTest() {
|
||||
@Test
|
||||
fun `vaultDataStateFlow Error with CookieRedirectException with items should show user-friendly error dialog`() =
|
||||
runTest {
|
||||
val message = "Your request was interrupted because " +
|
||||
"the app needed to re-authenticate. Please try again."
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.Error(
|
||||
error = CookieRedirectException(hostname = "example.com"),
|
||||
error = CookieRedirectException(hostname = "example.com", message = message),
|
||||
data = VaultData(
|
||||
decryptCipherListResult = createMockDecryptCipherListResult(
|
||||
number = 1,
|
||||
|
||||
Reference in New Issue
Block a user