Skip to content
Snippets Groups Projects
Unverified Commit d36678b8 authored by BMItter's avatar BMItter Committed by GitHub
Browse files

Improved preference handling / thread safety (DEV) (#3252)


* Change to HotDataFlow

* Created test data for value sets, Adjusted storage tests, Also save null values

* Adjusted repo test

* Only emit when content changed

* ktlint & sourcecheck

* Thread safety

* Return empty value set as default

* detekt and sourceclean

Co-authored-by: default avatarharambasicluka <64483219+harambasicluka@users.noreply.github.com>
parent 61fdae63
No related branches found
No related tags found
No related merge requests found
Showing with 262 additions and 215 deletions
package de.rki.coronawarnapp.vaccination.core.repository
import androidx.annotation.VisibleForTesting
import dagger.Reusable
import de.rki.coronawarnapp.util.coroutine.AppScope
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
import de.rki.coronawarnapp.util.flow.HotDataFlow
import de.rki.coronawarnapp.vaccination.core.repository.storage.ValueSetsStorage
import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationServer
import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationValueSet
import de.rki.coronawarnapp.vaccination.core.server.valueset.emptyVaccinationValueSet
import de.rki.coronawarnapp.vaccination.core.server.valueset.isEmpty
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.plus
import timber.log.Timber
import java.util.Locale
import javax.inject.Inject
......@@ -19,55 +26,65 @@ import javax.inject.Inject
class ValueSetsRepository @Inject constructor(
private val vaccinationServer: VaccinationServer,
private val valueSetsStorage: ValueSetsStorage,
@AppScope private val scope: CoroutineScope
@AppScope private val scope: CoroutineScope,
dispatcherProvider: DispatcherProvider
) {
val latestValueSet: Flow<VaccinationValueSet> = valueSetsStorage.valueSet.flow.distinctUntilChanged()
private fun Flow<VaccinationValueSet>.distinctUntilChangedByHash() = distinctUntilChangedBy { it.hashCode() }
fun triggerUpdateValueSet(languageCode: Locale) = scope.launch {
private val internalData: HotDataFlow<VaccinationValueSet> = HotDataFlow(
loggingTag = TAG,
scope = scope,
coroutineContext = dispatcherProvider.IO,
sharingBehavior = SharingStarted.Lazily,
startValueProvider = {
valueSetsStorage.vaccinationValueSet.also { Timber.v("Loaded initial value set %s", it) }
}
)
init {
internalData.data
.distinctUntilChangedByHash()
.onStart { Timber.d("Observing value set") }
.onEach { valueSetsStorage.vaccinationValueSet = it }
.catch { Timber.e(it, "Storing new value set failed.") }
.launchIn(scope + dispatcherProvider.IO)
}
val latestValueSet: Flow<VaccinationValueSet> = internalData.data.distinctUntilChangedByHash()
fun triggerUpdateValueSet(languageCode: Locale) {
Timber.d("triggerUpdateValueSet(languageCode=%s)", languageCode)
internalData.updateAsync(
onUpdate = { getValueSetFromServer(languageCode = languageCode) ?: this },
onError = { Timber.e(it, "Updating value set failed") }
)
}
private suspend fun getValueSetFromServer(languageCode: Locale): VaccinationValueSet? {
Timber.v("getValueSetFromServer(languageCode=%s)", languageCode)
var valueSet = vaccinationServer.getVaccinationValueSets(languageCode = languageCode)
if (valueSet == null && valueSetsStorage.valueSet.value.isEmpty()) {
if (valueSet.isEmpty()) {
Timber.d(
"Got no value set from server for %s and local value set is empty... " +
"Try fallback to value set for en",
"Got no value set from server for %s and local value set is empty... Try fallback to value set for en",
languageCode.language
)
valueSet = vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH)
}
valueSet
.also { Timber.d("Value set is %s", it) }
?.let { newValueSet -> valueSetsStorage.valueSet.update { newValueSet.toStoredVaccinationValueSet() } }
return valueSet
.also { Timber.v("New value set %s", it) }
}
fun clear() {
suspend fun clear() {
Timber.d("Clearing value sets")
vaccinationServer.clear()
valueSetsStorage.clear()
internalData.updateBlocking {
Timber.v("Resetting value set to an empty value set")
emptyVaccinationValueSet
}
}
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun VaccinationValueSet.toStoredVaccinationValueSet(): ValueSetsStorage.StoredVaccinationValueSet =
ValueSetsStorage.StoredVaccinationValueSet(
languageCode = languageCode,
vp = vp.toStoredValueSet(),
mp = mp.toStoredValueSet(),
ma = ma.toStoredValueSet()
)
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun VaccinationValueSet.ValueSet.toStoredValueSet(): ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet =
ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet(
items = items.map { it.toStoredItem() }
)
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun VaccinationValueSet.ValueSet.Item.toStoredItem():
ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet.StoredItem =
ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet.StoredItem(
key = key,
displayText = displayText
)
private const val TAG = "ValueSetsRepository"
......@@ -3,15 +3,15 @@ package de.rki.coronawarnapp.vaccination.core.repository.storage
import android.content.Context
import android.content.SharedPreferences
import androidx.annotation.Keep
import androidx.annotation.VisibleForTesting
import androidx.core.content.edit
import com.google.gson.Gson
import com.google.gson.annotations.SerializedName
import dagger.Reusable
import de.rki.coronawarnapp.util.di.AppContext
import de.rki.coronawarnapp.util.preferences.FlowPreference
import de.rki.coronawarnapp.util.preferences.clearAndNotify
import de.rki.coronawarnapp.util.preferences.createFlowPreference
import de.rki.coronawarnapp.util.serialization.BaseGson
import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationValueSet
import de.rki.coronawarnapp.vaccination.core.server.valueset.emptyVaccinationValueSet
import timber.log.Timber
import java.util.Locale
import javax.inject.Inject
......@@ -26,25 +26,52 @@ class ValueSetsStorage @Inject constructor(
context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
}
var valueSet: FlowPreference<StoredVaccinationValueSet> = prefs.createFlowPreference(
key = PKEY_VALUE_SETS_PREFIX,
reader = FlowPreference.gsonReader(gson = gson, createEmptyValueSet()),
writer = FlowPreference.gsonWriter(gson = gson)
)
var vaccinationValueSet: VaccinationValueSet
get() = getValueSet()
set(value) = setValueSet(value)
fun clear() {
Timber.d("Clearing local storage")
prefs.clearAndNotify()
private fun getValueSet(): VaccinationValueSet {
Timber.v("Loading value set")
val valueSetString = prefs.getString(PKEY_VALUE_SETS_PREFIX, null)
return when (valueSetString != null) {
true -> gson.fromJson(valueSetString, StoredVaccinationValueSet::class.java)
else -> emptyVaccinationValueSet
}.also { loaded -> Timber.v("Loaded value set %s", loaded) }
}
private fun createEmptyValueSet() = StoredVaccinationValueSet(
languageCode = Locale.ENGLISH,
vp = StoredVaccinationValueSet.StoredValueSet(items = emptyList()),
mp = StoredVaccinationValueSet.StoredValueSet(items = emptyList()),
ma = StoredVaccinationValueSet.StoredValueSet(items = emptyList())
)
private fun setValueSet(value: VaccinationValueSet) {
Timber.v("Saving value set %s", value)
prefs.edit {
val json = gson.toJson(value.toStoredVaccinationValueSet(), StoredVaccinationValueSet::class.java)
Timber.v("Writing %s to prefs", json)
putString(PKEY_VALUE_SETS_PREFIX, json)
}
}
@VisibleForTesting
fun VaccinationValueSet.toStoredVaccinationValueSet(): StoredVaccinationValueSet =
StoredVaccinationValueSet(
languageCode = languageCode,
vp = vp.toStoredValueSet(),
mp = mp.toStoredValueSet(),
ma = ma.toStoredValueSet()
)
@VisibleForTesting
fun VaccinationValueSet.ValueSet.toStoredValueSet(): StoredVaccinationValueSet.StoredValueSet =
StoredVaccinationValueSet.StoredValueSet(
items = items.map { it.toStoredItem() }
)
@VisibleForTesting
fun VaccinationValueSet.ValueSet.Item.toStoredItem():
StoredVaccinationValueSet.StoredValueSet.StoredItem =
StoredVaccinationValueSet.StoredValueSet.StoredItem(
key = key,
displayText = displayText
)
@Keep
@VisibleForTesting
data class StoredVaccinationValueSet(
@SerializedName("languageCode") override val languageCode: Locale,
@SerializedName("vp") override val vp: StoredValueSet,
......
......@@ -19,3 +19,12 @@ data class DefaultVaccinationValueSet(
) : VaccinationValueSet.ValueSet.Item
}
}
internal val emptyVaccinationValueSet: VaccinationValueSet by lazy {
DefaultVaccinationValueSet(
languageCode = Locale.ENGLISH,
vp = DefaultVaccinationValueSet.DefaultValueSet(items = emptyList()),
mp = DefaultVaccinationValueSet.DefaultValueSet(items = emptyList()),
ma = DefaultVaccinationValueSet.DefaultValueSet(items = emptyList())
)
}
......@@ -24,6 +24,6 @@ fun VaccinationValueSet.getDisplayText(key: String): String? =
fun VaccinationValueSet.ValueSet.getDisplayText(key: String): String? = items.find { key == it.key }?.displayText
fun VaccinationValueSet.isEmpty(): Boolean = vp.isEmpty() && mp.isEmpty() && ma.isEmpty()
fun VaccinationValueSet?.isEmpty(): Boolean = (this == null) || (vp.isEmpty() && mp.isEmpty() && ma.isEmpty())
fun VaccinationValueSet.ValueSet.isEmpty(): Boolean = items.isEmpty()
package de.rki.coronawarnapp.vaccination.core
import de.rki.coronawarnapp.vaccination.core.repository.storage.ValueSetsStorage
import de.rki.coronawarnapp.vaccination.core.server.valueset.DefaultVaccinationValueSet
import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationValueSet
import io.kotest.matchers.shouldBe
import java.util.Locale
object ValueSetTestData {
val vpItemDe = "1119305005" to "Impfstoff-Name"
val mpItemDe = "EU/1/21/1529" to "Arzneimittel-Name"
val maItemDe = "ORG-100001699" to "Hersteller-Name"
val vpItemEn = vpItemDe.copy(second = "Vaccine-Name")
val mpItemEn = mpItemDe.copy(second = "MedicalProduct-Name")
val maItemEn = maItemDe.copy(second = "Manufactorer-Name")
val storedValueSetDe = ValueSetsStorage.StoredVaccinationValueSet(
languageCode = Locale.GERMAN,
vp = createStoredValueSet(vpItemDe),
mp = createStoredValueSet(mpItemDe),
ma = createStoredValueSet(maItemDe)
)
val storedValueSetEn = ValueSetsStorage.StoredVaccinationValueSet(
languageCode = Locale.ENGLISH,
vp = createStoredValueSet(vpItemEn),
mp = createStoredValueSet(mpItemEn),
ma = createStoredValueSet(maItemEn)
)
val emptyStoredValueSet = ValueSetsStorage.StoredVaccinationValueSet(
languageCode = Locale.ENGLISH,
vp = ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet(items = emptyList()),
mp = ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet(items = emptyList()),
ma = ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet(items = emptyList())
)
val valueSetDe = DefaultVaccinationValueSet(
languageCode = Locale.GERMAN,
vp = createValueSet(vpItemDe),
mp = createValueSet(mpItemDe),
ma = createValueSet(maItemDe)
)
val valueSetEn = DefaultVaccinationValueSet(
languageCode = Locale.ENGLISH,
vp = createValueSet(vpItemEn),
mp = createValueSet(mpItemEn),
ma = createValueSet(maItemEn)
)
val emptyValueSetEn = emptyStoredValueSet
fun createStoredValueSet(keyText: Pair<String, String>): ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet {
val item = ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet.StoredItem(
key = keyText.first,
displayText = keyText.second
)
return ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet(items = listOf(item))
}
fun createValueSet(keyText: Pair<String, String>): DefaultVaccinationValueSet.DefaultValueSet {
val item = DefaultVaccinationValueSet.DefaultValueSet.DefaultItem(
key = keyText.first,
displayText = keyText.second
)
return DefaultVaccinationValueSet.DefaultValueSet(items = listOf(item))
}
}
fun VaccinationValueSet.validateValues(v2: VaccinationValueSet) {
languageCode shouldBe v2.languageCode
vp.validateValues(v2.vp)
mp.validateValues(v2.mp)
ma.validateValues(v2.ma)
}
fun VaccinationValueSet.ValueSet.validateValues(v2: VaccinationValueSet.ValueSet) {
items.forEachIndexed { index, item1 ->
val item2 = v2.items[index]
item1.key shouldBe item2.key
item1.displayText shouldBe item2.displayText
}
}
package de.rki.coronawarnapp.vaccination.core.repository
import de.rki.coronawarnapp.util.preferences.FlowPreference
import de.rki.coronawarnapp.vaccination.core.ValueSetTestData.emptyValueSetEn
import de.rki.coronawarnapp.vaccination.core.ValueSetTestData.valueSetDe
import de.rki.coronawarnapp.vaccination.core.ValueSetTestData.valueSetEn
import de.rki.coronawarnapp.vaccination.core.repository.storage.ValueSetsStorage
import de.rki.coronawarnapp.vaccination.core.server.valueset.DefaultVaccinationValueSet
import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationServer
import de.rki.coronawarnapp.vaccination.core.server.valueset.VaccinationValueSet
import io.kotest.matchers.shouldBe
import de.rki.coronawarnapp.vaccination.core.validateValues
import io.mockk.MockKAnnotations
import io.mockk.Ordering
import io.mockk.coEvery
......@@ -14,13 +14,13 @@ import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.just
import io.mockk.runs
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.TestCoroutineScope
import kotlinx.coroutines.test.runBlockingTest
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
import testhelpers.preferences.mockFlowPreference
import testhelpers.TestDispatcherProvider
import testhelpers.coroutines.runBlockingTest2
import java.util.Locale
class ValueSetsRepositoryTest : BaseTest() {
......@@ -28,124 +28,68 @@ class ValueSetsRepositoryTest : BaseTest() {
@MockK lateinit var vaccinationServer: VaccinationServer
@MockK lateinit var valueSetsStorage: ValueSetsStorage
private val testScope = TestCoroutineScope()
private val emptyValueSetEN = createValueSet(languageCode = Locale.ENGLISH)
private val valueSetPref: FlowPreference<ValueSetsStorage.StoredVaccinationValueSet> =
mockFlowPreference(emptyValueSetEN.toStoredVaccinationValueSet())
private val valueSetEN = createValueSet(
languageCode = Locale.ENGLISH,
vpItems = listOf(
DefaultVaccinationValueSet.DefaultValueSet.DefaultItem(
key = "1119305005",
displayText = "Vaccine-Name"
)
),
mpItems = listOf(
DefaultVaccinationValueSet.DefaultValueSet.DefaultItem(
key = "EU/1/21/1529",
displayText = "MedicalProduct-Name"
)
),
maItems = listOf(
DefaultVaccinationValueSet.DefaultValueSet.DefaultItem(
key = "ORG-100001699",
displayText = "Manufactorer-Name"
)
)
)
private val valueSetDE = createValueSet(
languageCode = Locale.GERMAN,
vpItems = listOf(
DefaultVaccinationValueSet.DefaultValueSet.DefaultItem(
key = "1119305005",
displayText = "Impfstoff-Name"
)
),
mpItems = listOf(
DefaultVaccinationValueSet.DefaultValueSet.DefaultItem(
key = "EU/1/21/1529",
displayText = "Arzneimittel-Name"
)
),
maItems = listOf(
DefaultVaccinationValueSet.DefaultValueSet.DefaultItem(
key = "ORG-100001699",
displayText = "Hersteller-Name"
)
)
)
private fun createValueSet(
languageCode: Locale,
vpItems: List<DefaultVaccinationValueSet.DefaultValueSet.DefaultItem> = emptyList(),
mpItems: List<DefaultVaccinationValueSet.DefaultValueSet.DefaultItem> = emptyList(),
maItems: List<DefaultVaccinationValueSet.DefaultValueSet.DefaultItem> = emptyList()
) = DefaultVaccinationValueSet(
languageCode = languageCode,
vp = DefaultVaccinationValueSet.DefaultValueSet(items = vpItems),
mp = DefaultVaccinationValueSet.DefaultValueSet(items = mpItems),
ma = DefaultVaccinationValueSet.DefaultValueSet(items = maItems)
)
private val testDispatcherProvider = TestDispatcherProvider()
private fun createInstance() = ValueSetsRepository(
private fun createInstance(scope: CoroutineScope) = ValueSetsRepository(
vaccinationServer = vaccinationServer,
valueSetsStorage = valueSetsStorage,
scope = testScope
scope = scope,
dispatcherProvider = testDispatcherProvider
)
@BeforeEach
fun setUp() {
MockKAnnotations.init(this)
coEvery { vaccinationServer.getVaccinationValueSets(any()) } returns null
coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH) } returns valueSetEN
coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.GERMAN) } returns valueSetDE
coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH) } returns valueSetEn
coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.GERMAN) } returns valueSetDe
every { vaccinationServer.clear() } just runs
every { valueSetsStorage.valueSet } returns valueSetPref
every { valueSetsStorage.clear() } just runs
every { valueSetsStorage.vaccinationValueSet = any() } just runs
every { valueSetsStorage.vaccinationValueSet } returns emptyValueSetEn
}
@Test
fun `successful update for de`() = runBlockingTest {
createInstance().run {
fun `successful update for de`() = runBlockingTest2(ignoreActive = true) {
createInstance(this).run {
triggerUpdateValueSet(languageCode = Locale.GERMAN)
latestValueSet.first()
}.also { it.validateValues(valueSetDE) }
}.also { it.validateValues(valueSetDe) }
coVerify(exactly = 1) {
coVerify {
vaccinationServer.getVaccinationValueSets(languageCode = Locale.GERMAN)
valueSetsStorage.vaccinationValueSet = valueSetDe
}
coVerify(exactly = 0) {
vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH)
valueSetsStorage.vaccinationValueSet = valueSetEn
}
}
@Test
fun `fallback to en`() = runBlockingTest {
createInstance().run {
fun `fallback to en`() = runBlockingTest2(ignoreActive = true) {
createInstance(this).run {
triggerUpdateValueSet(languageCode = Locale.FRENCH)
latestValueSet.first()
}.also { it.validateValues(valueSetEN) }
}.also { it.validateValues(valueSetEn) }
coVerify(ordering = Ordering.ORDERED) {
vaccinationServer.getVaccinationValueSets(languageCode = Locale.FRENCH)
vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH)
valueSetsStorage.vaccinationValueSet = valueSetEn
}
}
@Test
fun `server returns nothing`() = runBlockingTest {
fun `server returns nothing`() = runBlockingTest2(ignoreActive = true) {
coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.GERMAN) } returns null
coEvery { vaccinationServer.getVaccinationValueSets(languageCode = Locale.ENGLISH) } returns null
createInstance().run {
createInstance(this).run {
triggerUpdateValueSet(languageCode = Locale.GERMAN)
latestValueSet.first()
}.also { it.validateValues(emptyValueSetEN) }
}.also { it.validateValues(emptyValueSetEn) }
coVerify(ordering = Ordering.ORDERED) {
vaccinationServer.getVaccinationValueSets(languageCode = Locale.GERMAN)
......@@ -154,37 +98,16 @@ class ValueSetsRepositoryTest : BaseTest() {
}
@Test
fun `mapping is to stored version is correct`() {
valueSetDE.also { it.toStoredVaccinationValueSet().validateValues(it) }
valueSetEN.also { it.toStoredVaccinationValueSet().validateValues(it) }
emptyValueSetEN.also { it.toStoredVaccinationValueSet().validateValues(it) }
}
@Test
fun `clear data of server and local storage`() {
createInstance().run {
fun `clear data of server and local storage`() = runBlockingTest2(ignoreActive = true) {
createInstance(this).run {
clear()
coVerify(exactly = 1) {
latestValueSet.first().validateValues(emptyValueSetEn)
coVerify {
vaccinationServer.clear()
valueSetsStorage.clear()
valueSetsStorage.vaccinationValueSet = emptyValueSetEn
}
}
}
private fun VaccinationValueSet.validateValues(v2: VaccinationValueSet) {
languageCode shouldBe v2.languageCode
vp.validateValues(v2.vp)
mp.validateValues(v2.mp)
ma.validateValues(v2.ma)
}
private fun VaccinationValueSet.ValueSet.validateValues(v2: VaccinationValueSet.ValueSet) {
items.forEachIndexed { index, item1 ->
val item2 = v2.items[index]
item1.key shouldBe item2.key
item1.displayText shouldBe item2.displayText
}
}
}
......@@ -2,17 +2,21 @@ package de.rki.coronawarnapp.vaccination.core.repository.storage
import android.content.Context
import de.rki.coronawarnapp.util.serialization.SerializationModule
import de.rki.coronawarnapp.vaccination.core.ValueSetTestData.emptyStoredValueSet
import de.rki.coronawarnapp.vaccination.core.ValueSetTestData.emptyValueSetEn
import de.rki.coronawarnapp.vaccination.core.ValueSetTestData.storedValueSetDe
import de.rki.coronawarnapp.vaccination.core.ValueSetTestData.storedValueSetEn
import de.rki.coronawarnapp.vaccination.core.ValueSetTestData.valueSetDe
import de.rki.coronawarnapp.vaccination.core.ValueSetTestData.valueSetEn
import de.rki.coronawarnapp.vaccination.core.validateValues
import io.kotest.matchers.shouldBe
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runBlockingTest
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
import testhelpers.preferences.MockSharedPreferences
import java.util.Locale
class ValueSetsStorageTest : BaseTest() {
......@@ -21,28 +25,6 @@ class ValueSetsStorageTest : BaseTest() {
private val gson = SerializationModule().baseGson()
private val storedValueSetDE = ValueSetsStorage.StoredVaccinationValueSet(
languageCode = Locale.GERMAN,
vp = createValueSet(key = "1119305005", displayText = "Impfstoff-Name"),
mp = createValueSet(key = "EU/1/21/1529", displayText = "Arzneimittel-Name"),
ma = createValueSet(key = "ORG-100001699", displayText = "Hersteller-Name")
)
private val storedValueSetEN = ValueSetsStorage.StoredVaccinationValueSet(
languageCode = Locale.ENGLISH,
vp = createValueSet(key = "1119305005", displayText = "Vaccine-Name"),
mp = createValueSet(key = "EU/1/21/1529", displayText = "MedicalProduct-Name"),
ma = createValueSet(key = "ORG-100001699", displayText = "Manufactorer-Name")
)
private fun createValueSet(key: String, displayText: String): ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet {
val item = ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet.StoredItem(
key = key,
displayText = displayText
)
return ValueSetsStorage.StoredVaccinationValueSet.StoredValueSet(items = listOf(item))
}
@BeforeEach
fun setup() {
MockKAnnotations.init(this)
......@@ -56,40 +38,42 @@ class ValueSetsStorageTest : BaseTest() {
)
@Test
fun `Default value is empty value set`() {
createInstance().valueSet.value.run {
languageCode shouldBe Locale.ENGLISH
vp.items shouldBe emptyList()
mp.items shouldBe emptyList()
ma.items shouldBe emptyList()
}
fun `Default value is an empty value set`() {
createInstance().vaccinationValueSet.validateValues(emptyValueSetEn)
}
@Test
fun `Clear resets value set`() {
fun `Updates values`() {
createInstance().run {
valueSet.update { storedValueSetDE }
clear()
vaccinationValueSet = storedValueSetDe
vaccinationValueSet shouldBe storedValueSetDe
valueSet.value.also {
it.languageCode shouldBe Locale.ENGLISH
it.vp.items shouldBe emptyList()
it.mp.items shouldBe emptyList()
it.ma.items shouldBe emptyList()
}
vaccinationValueSet = storedValueSetEn
vaccinationValueSet shouldBe storedValueSetEn
}
}
@Test
fun `Updates values`() = runBlockingTest {
createInstance().valueSet.run {
update { storedValueSetDE }
value shouldBe storedValueSetDE
flow.first() shouldBe storedValueSetDE
fun `Check mapping is correct`() {
createInstance().run {
storedValueSetDe.also { it.toStoredVaccinationValueSet() shouldBe it }
storedValueSetEn.also { it.toStoredVaccinationValueSet() shouldBe it }
valueSetDe.also {
it.toStoredVaccinationValueSet() shouldBe storedValueSetDe
it.toStoredVaccinationValueSet().validateValues(it)
}
update { storedValueSetEN }
value shouldBe storedValueSetEN
flow.first() shouldBe storedValueSetEN
valueSetEn.also {
it.toStoredVaccinationValueSet() shouldBe storedValueSetEn
it.toStoredVaccinationValueSet().validateValues(it)
}
emptyValueSetEn.also {
it.toStoredVaccinationValueSet() shouldBe emptyStoredValueSet
it.toStoredVaccinationValueSet().validateValues(it)
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment