[PM-6702] 2# Region load in complete registration step (#3618)

This commit is contained in:
André Bispo 2024-08-13 15:22:34 +01:00 committed by GitHub
parent 4dbcec85bb
commit 4bd81782c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 172 additions and 5 deletions

View file

@ -17,4 +17,14 @@ interface EnvironmentDiskSource {
* if any.
*/
val preAuthEnvironmentUrlDataFlow: Flow<EnvironmentUrlDataJson?>
/**
* Gets the pre authentication urls for the given [userEmail].
*/
fun getPreAuthEnvironmentUrlDataForEmail(userEmail: String): EnvironmentUrlDataJson?
/**
* Stores the [urls] for the given [userEmail].
*/
fun storePreAuthEnvironmentUrlDataForEmail(userEmail: String, urls: EnvironmentUrlDataJson)
}

View file

@ -10,6 +10,7 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
private const val PRE_AUTH_URLS_KEY = "preAuthEnvironmentUrls"
private const val EMAIL_VERIFICATION_URLS = "emailVerificationUrls"
/**
* Primary implementation of [EnvironmentDiskSource].
@ -35,4 +36,22 @@ class EnvironmentDiskSourceImpl(
private val mutableEnvironmentUrlDataFlow =
bufferedMutableSharedFlow<EnvironmentUrlDataJson?>(replay = 1)
override fun getPreAuthEnvironmentUrlDataForEmail(
userEmail: String,
): EnvironmentUrlDataJson? =
getString(key = EMAIL_VERIFICATION_URLS.appendIdentifier(userEmail))
?.let {
json.decodeFromStringOrNull(it)
}
override fun storePreAuthEnvironmentUrlDataForEmail(
userEmail: String,
urls: EnvironmentUrlDataJson,
) {
putString(
key = EMAIL_VERIFICATION_URLS.appendIdentifier(userEmail),
value = json.encodeToString(urls),
)
}
}

View file

@ -16,4 +16,15 @@ interface EnvironmentRepository {
* Emits updates that track [environment].
*/
val environmentStateFlow: StateFlow<Environment>
/**
* Stores the current environment for the given [userEmail].
*/
fun saveCurrentEnvironmentForEmail(userEmail: String)
/**
* Loads the environment for the given [userEmail].
* returns boolean indicates if the load was successful
*/
fun loadEnvironmentForEmail(userEmail: String): Boolean
}

View file

@ -4,6 +4,7 @@ import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.platform.datasource.disk.EnvironmentDiskSource
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
import com.x8bit.bitwarden.data.platform.repository.model.Environment
import com.x8bit.bitwarden.data.platform.repository.util.toEnvironmentUrls
import com.x8bit.bitwarden.data.platform.repository.util.toEnvironmentUrlsOrDefault
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@ -55,4 +56,19 @@ class EnvironmentRepositoryImpl(
}
.launchIn(scope)
}
override fun loadEnvironmentForEmail(userEmail: String): Boolean {
val urls = environmentDiskSource
.getPreAuthEnvironmentUrlDataForEmail(userEmail)
?: return false
environment = urls.toEnvironmentUrls()
return true
}
override fun saveCurrentEnvironmentForEmail(userEmail: String) =
environmentDiskSource
.storePreAuthEnvironmentUrlDataForEmail(
userEmail = userEmail,
urls = environment.environmentUrlData,
)
}

View file

@ -4,8 +4,11 @@ import androidx.core.content.edit
import app.cash.turbine.test
import com.x8bit.bitwarden.data.auth.datasource.disk.model.EnvironmentUrlDataJson
import com.x8bit.bitwarden.data.platform.base.FakeSharedPreferences
import com.x8bit.bitwarden.data.platform.repository.model.Environment
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToJsonElement
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Test
@ -25,11 +28,9 @@ class EnvironmentDiskSourceTest {
@Test
fun `preAuthEnvironmentUrlData should pull from and update SharedPreferences`() {
val environmentKey = "bwPreferencesStorage:preAuthEnvironmentUrls"
// Shared preferences and the repository start with the same value.
assertNull(environmentDiskSource.preAuthEnvironmentUrlData)
assertNull(fakeSharedPreferences.getString(environmentKey, null))
assertNull(fakeSharedPreferences.getString(PRE_AUTH_URLS_KEY, null))
// Updating the repository updates shared preferences
environmentDiskSource.preAuthEnvironmentUrlData = ENVIRONMENT_URL_DATA
@ -38,12 +39,12 @@ class EnvironmentDiskSourceTest {
ENVIRONMENT_URL_DATA_JSON,
),
json.parseToJsonElement(
fakeSharedPreferences.getString(environmentKey, null)!!,
fakeSharedPreferences.getString(PRE_AUTH_URLS_KEY, null)!!,
),
)
// Update SharedPreferences updates the repository
fakeSharedPreferences.edit { putString(environmentKey, null) }
fakeSharedPreferences.edit { putString(PRE_AUTH_URLS_KEY, null) }
assertNull(environmentDiskSource.preAuthEnvironmentUrlData)
}
@ -60,8 +61,47 @@ class EnvironmentDiskSourceTest {
assertEquals(ENVIRONMENT_URL_DATA, awaitItem())
}
}
@Test
fun `getPreAuthEnvironmentUrlDataForEmail should pull from SharedPreferences`() {
val mockUrls = Environment.Us.environmentUrlData
fakeSharedPreferences
.edit {
putString(
"${EMAIL_VERIFICATION_URLS_KEY}_$EMAIL",
json.encodeToString(mockUrls),
)
}
val actual = environmentDiskSource
.getPreAuthEnvironmentUrlDataForEmail(userEmail = EMAIL)
assertEquals(
mockUrls,
actual,
)
}
@Test
fun `storePreAuthEnvironmentUrlDataForEmail should update SharedPreferences`() {
val mockUrls = Environment.Us.environmentUrlData
environmentDiskSource.storePreAuthEnvironmentUrlDataForEmail(
userEmail = EMAIL,
urls = mockUrls,
)
val actual = fakeSharedPreferences.getString(
"${EMAIL_VERIFICATION_URLS_KEY}_$EMAIL",
null,
)
assertEquals(
json.encodeToJsonElement(mockUrls),
json.parseToJsonElement(requireNotNull(actual)),
)
}
}
private const val EMAIL = "email@example.com"
private const val EMAIL_VERIFICATION_URLS_KEY = "bwPreferencesStorage:emailVerificationUrls"
private const val PRE_AUTH_URLS_KEY = "bwPreferencesStorage:preAuthEnvironmentUrls"
private const val ENVIRONMENT_URL_DATA_JSON = """
{
"base": "base",

View file

@ -20,6 +20,7 @@ import kotlinx.coroutines.flow.onSubscription
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@ -147,6 +148,58 @@ class EnvironmentRepositoryTest {
}
}
@Test
fun `loadEnvironmentForEmail should update the environment`() = runTest {
val environmentUrlDataJson = mockk<EnvironmentUrlDataJson>()
val environment = mockk<Environment> {
every { environmentUrlData } returns environmentUrlDataJson
}
every { environmentUrlDataJson.toEnvironmentUrls() } returns environment
fakeEnvironmentDiskSource.storePreAuthEnvironmentUrlDataForEmail(
userEmail = EMAIL,
environmentUrlDataJson,
)
repository.loadEnvironmentForEmail(userEmail = EMAIL)
assertEquals(
environment,
repository.environment,
)
}
@Test
fun `loadEnvironmentForEmail returns false on fail`() = runTest {
val result = repository.loadEnvironmentForEmail(userEmail = EMAIL)
assertFalse(result)
}
@Test
fun `saveCurrentEnvironmentForEmail should save the environment`() = runTest {
val environmentUrlDataJson = mockk<EnvironmentUrlDataJson>()
val environment = mockk<Environment> {
every { environmentUrlData } returns environmentUrlDataJson
}
every { environmentUrlDataJson.toEnvironmentUrls() } returns environment
repository.environment = Environment.Eu
fakeEnvironmentDiskSource.storePreAuthEnvironmentUrlDataForEmail(
userEmail = EMAIL,
environmentUrlDataJson,
)
repository.saveCurrentEnvironmentForEmail(userEmail = EMAIL)
assertEquals(
Environment.Eu.environmentUrlData,
fakeEnvironmentDiskSource
.getPreAuthEnvironmentUrlDataForEmail(
userEmail = EMAIL,
),
)
}
private fun getMockUserState(
environmentForActiveUser: EnvironmentUrlDataJson?,
): UserStateJson =
@ -164,7 +217,11 @@ class EnvironmentRepositoryTest {
)
}
private const val EMAIL = "email@example.com"
private class FakeEnvironmentDiskSource : EnvironmentDiskSource {
private val storedEmailVerificationUrls = mutableMapOf<String, EnvironmentUrlDataJson?>()
override var preAuthEnvironmentUrlData: EnvironmentUrlDataJson? = null
set(value) {
field = value
@ -175,6 +232,16 @@ private class FakeEnvironmentDiskSource : EnvironmentDiskSource {
get() = mutablePreAuthEnvironmentUrlDataFlow
.onSubscription { emit(preAuthEnvironmentUrlData) }
override fun getPreAuthEnvironmentUrlDataForEmail(userEmail: String): EnvironmentUrlDataJson? =
storedEmailVerificationUrls[userEmail]
override fun storePreAuthEnvironmentUrlDataForEmail(
userEmail: String,
urls: EnvironmentUrlDataJson,
) {
storedEmailVerificationUrls[userEmail] = urls
}
private val mutablePreAuthEnvironmentUrlDataFlow =
bufferedMutableSharedFlow<EnvironmentUrlDataJson?>(replay = 1)
}

View file

@ -18,5 +18,9 @@ class FakeEnvironmentRepository : EnvironmentRepository {
override val environmentStateFlow: StateFlow<Environment>
get() = mutableEnvironmentStateFlow.asStateFlow()
override fun saveCurrentEnvironmentForEmail(userEmail: String) = Unit
override fun loadEnvironmentForEmail(userEmail: String): Boolean = true
private val mutableEnvironmentStateFlow = MutableStateFlow<Environment>(Environment.Us)
}