mirror of
https://github.com/bitwarden/android.git
synced 2026-06-02 11:12:00 -05:00
BIT-752: Add Environment/EnvironmentRepository/EnvironmentDiskSource (#151)
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package com.x8bit.bitwarden.data.platform.datasource.disk
|
||||
|
||||
import app.cash.turbine.test
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.EnvironmentUrlDataJson
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeSharedPreferences
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class EnvironmentDiskSourceTest {
|
||||
private val fakeSharedPreferences = FakeSharedPreferences()
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
explicitNulls = false
|
||||
}
|
||||
|
||||
private val environmentDiskSource = EnvironmentDiskSourceImpl(
|
||||
sharedPreferences = fakeSharedPreferences,
|
||||
json = json,
|
||||
)
|
||||
|
||||
@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))
|
||||
|
||||
// Updating the repository updates shared preferences
|
||||
environmentDiskSource.preAuthEnvironmentUrlData = ENVIRONMENT_URL_DATA
|
||||
assertEquals(
|
||||
json.parseToJsonElement(
|
||||
ENVIRONMENT_URL_DATA_JSON,
|
||||
),
|
||||
json.parseToJsonElement(
|
||||
fakeSharedPreferences.getString(environmentKey, null)!!,
|
||||
),
|
||||
)
|
||||
|
||||
// Update SharedPreferences updates the repository
|
||||
fakeSharedPreferences.edit().putString(environmentKey, null).apply()
|
||||
assertNull(environmentDiskSource.preAuthEnvironmentUrlData)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `preAuthEnvironmentUrlDataFlow should react to changes in preAuthEnvironmentUrlData`() =
|
||||
runTest {
|
||||
environmentDiskSource.preAuthEnvironmentUrlDataFlow.test {
|
||||
// The initial values of the Flow and the property are in sync
|
||||
assertNull(environmentDiskSource.preAuthEnvironmentUrlData)
|
||||
assertNull(awaitItem())
|
||||
|
||||
// Updating the repository updates shared preferences
|
||||
environmentDiskSource.preAuthEnvironmentUrlData = ENVIRONMENT_URL_DATA
|
||||
assertEquals(ENVIRONMENT_URL_DATA, awaitItem())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val ENVIRONMENT_URL_DATA_JSON = """
|
||||
{
|
||||
"base": "base",
|
||||
"api": "api",
|
||||
"identity": "identity",
|
||||
"icon": "icon",
|
||||
"notifications": "notifications",
|
||||
"webVault": "webVault",
|
||||
"events": "events"
|
||||
}
|
||||
"""
|
||||
|
||||
private val ENVIRONMENT_URL_DATA = EnvironmentUrlDataJson(
|
||||
base = "base",
|
||||
api = "api",
|
||||
identity = "identity",
|
||||
icon = "icon",
|
||||
notifications = "notifications",
|
||||
webVault = "webVault",
|
||||
events = "events",
|
||||
)
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.x8bit.bitwarden.data.platform.repository
|
||||
|
||||
import app.cash.turbine.test
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.EnvironmentUrlDataJson
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.EnvironmentDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.Environment
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.toEnvironmentUrls
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.onSubscription
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class EnvironmentRepositoryTest {
|
||||
private val fakeEnvironmentDiskSource = FakeEnvironmentDiskSource()
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private val repository = EnvironmentRepositoryImpl(
|
||||
environmentDiskSource = fakeEnvironmentDiskSource,
|
||||
dispatcher = UnconfinedTestDispatcher(),
|
||||
)
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
mockkStatic(ENVIRONMENT_EXTENSIONS_PATH)
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
unmockkStatic(ENVIRONMENT_EXTENSIONS_PATH)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `environment should pull from and update EnvironmentDiskSource`() {
|
||||
val environmentUrlDataJson = mockk<EnvironmentUrlDataJson>()
|
||||
val environment = mockk<Environment>() {
|
||||
every { environmentUrlData } returns environmentUrlDataJson
|
||||
}
|
||||
every { environmentUrlDataJson.toEnvironmentUrls() } returns environment
|
||||
|
||||
// The repository exposes a non-null default value when the disk source is empty
|
||||
assertNull(fakeEnvironmentDiskSource.preAuthEnvironmentUrlData)
|
||||
assertEquals(
|
||||
Environment.Us,
|
||||
repository.environment,
|
||||
)
|
||||
|
||||
// Updating the repository updates the disk source
|
||||
repository.environment = environment
|
||||
assertEquals(
|
||||
environmentUrlDataJson,
|
||||
fakeEnvironmentDiskSource.preAuthEnvironmentUrlData,
|
||||
)
|
||||
|
||||
// Updating the disk source updates the repository
|
||||
fakeEnvironmentDiskSource.preAuthEnvironmentUrlData = null
|
||||
assertEquals(
|
||||
Environment.Us,
|
||||
repository.environment,
|
||||
)
|
||||
fakeEnvironmentDiskSource.preAuthEnvironmentUrlData = environmentUrlDataJson
|
||||
assertEquals(
|
||||
environment,
|
||||
repository.environment,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `environmentStateFow should react to changes in environment`() = runTest {
|
||||
val environmentUrlDataJson = mockk<EnvironmentUrlDataJson>()
|
||||
val environment = mockk<Environment>() {
|
||||
every { environmentUrlData } returns environmentUrlDataJson
|
||||
}
|
||||
every { environmentUrlDataJson.toEnvironmentUrls() } returns environment
|
||||
|
||||
repository.environmentStateFlow.test {
|
||||
// The initial values of the Flow and the property are in sync
|
||||
assertEquals(
|
||||
Environment.Us,
|
||||
repository.environment,
|
||||
)
|
||||
assertEquals(
|
||||
Environment.Us,
|
||||
awaitItem(),
|
||||
)
|
||||
|
||||
// Updating the property causes a flow emissions
|
||||
repository.environment = environment
|
||||
assertEquals(environment, awaitItem())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val ENVIRONMENT_EXTENSIONS_PATH =
|
||||
"com.x8bit.bitwarden.data.platform.repository.util.EnvironmentExtensionsKt"
|
||||
|
||||
private class FakeEnvironmentDiskSource : EnvironmentDiskSource {
|
||||
override var preAuthEnvironmentUrlData: EnvironmentUrlDataJson? = null
|
||||
set(value) {
|
||||
field = value
|
||||
mutablePreAuthEnvironmentUrlDataFlow.tryEmit(value)
|
||||
}
|
||||
|
||||
override val preAuthEnvironmentUrlDataFlow: Flow<EnvironmentUrlDataJson?>
|
||||
get() = mutablePreAuthEnvironmentUrlDataFlow
|
||||
.onSubscription { emit(preAuthEnvironmentUrlData) }
|
||||
|
||||
private val mutablePreAuthEnvironmentUrlDataFlow =
|
||||
MutableSharedFlow<EnvironmentUrlDataJson?>(
|
||||
replay = 1,
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.platform.repository
|
||||
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.AuthState
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.interceptor.AuthTokenInterceptor
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.Environment
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -16,11 +17,16 @@ import org.junit.jupiter.api.Test
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class NetworkConfigRepositoryTest {
|
||||
private val mutableAuthStateFlow = MutableStateFlow<AuthState>(AuthState.Uninitialized)
|
||||
private val mutableEnvironmentStateFlow = MutableStateFlow<Environment>(Environment.Us)
|
||||
|
||||
private val authRepository: AuthRepository = mockk() {
|
||||
every { authStateFlow } returns mutableAuthStateFlow
|
||||
}
|
||||
|
||||
private val environmentRepository: EnvironmentRepository = mockk {
|
||||
every { environmentStateFlow } returns mutableEnvironmentStateFlow
|
||||
}
|
||||
|
||||
private val authTokenInterceptor = AuthTokenInterceptor()
|
||||
|
||||
private lateinit var networkConfigRepository: NetworkConfigRepository
|
||||
@@ -30,6 +36,7 @@ class NetworkConfigRepositoryTest {
|
||||
networkConfigRepository = NetworkConfigRepositoryImpl(
|
||||
authRepository = authRepository,
|
||||
authTokenInterceptor = authTokenInterceptor,
|
||||
environmentRepository = environmentRepository,
|
||||
dispatcher = UnconfinedTestDispatcher(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.x8bit.bitwarden.data.platform.repository.util
|
||||
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.model.EnvironmentUrlDataJson
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.Environment
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class EnvironmentExtensionsTest {
|
||||
@Test
|
||||
fun `toEnvironmentUrls should correctly convert US urls to the expected type`() {
|
||||
assertEquals(
|
||||
Environment.Us,
|
||||
EnvironmentUrlDataJson.DEFAULT_US.toEnvironmentUrls(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toEnvironmentUrls should correctly convert EU urls to the expected type`() {
|
||||
assertEquals(
|
||||
Environment.Eu,
|
||||
EnvironmentUrlDataJson.DEFAULT_EU.toEnvironmentUrls(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toEnvironmentUrls should correctly convert custom urls to the expected type`() {
|
||||
val environmentUrlData = EnvironmentUrlDataJson(
|
||||
base = "base",
|
||||
api = "api",
|
||||
identity = "identity",
|
||||
icon = "icon",
|
||||
notifications = "notifications",
|
||||
webVault = "webVault",
|
||||
events = "events",
|
||||
)
|
||||
assertEquals(
|
||||
Environment.SelfHosted(
|
||||
environmentUrlData = environmentUrlData,
|
||||
),
|
||||
environmentUrlData.toEnvironmentUrls(),
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user