parent
015cf5ad29
commit
4f0c2e7b92
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore
|
||||
|
||||
enum class DarkThemeConfigProto {
|
||||
DARK_THEME_CONFIG_UNSPECIFIED,
|
||||
DARK_THEME_CONFIG_FOLLOW_SYSTEM,
|
||||
DARK_THEME_CONFIG_LIGHT,
|
||||
DARK_THEME_CONFIG_DARK,
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore
|
||||
|
||||
enum class ThemeBrandProto {
|
||||
THEME_BRAND_UNSPECIFIED,
|
||||
THEME_BRAND_DEFAULT,
|
||||
THEME_BRAND_ANDROID,
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore
|
||||
|
||||
import com.google.samples.apps.nowinandroid.core.datastore.DarkThemeConfigProto.DARK_THEME_CONFIG_FOLLOW_SYSTEM
|
||||
import com.google.samples.apps.nowinandroid.core.datastore.ThemeBrandProto.THEME_BRAND_UNSPECIFIED
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
// A lot of workaround brought by Proto
|
||||
@Serializable
|
||||
data class UserPreferences(
|
||||
val topicChangeListVersion: Int,
|
||||
val authorChangeListVersion: Int,
|
||||
val newsResourceChangeListVersion: Int,
|
||||
val hasDoneIntToStringIdMigration: Boolean,
|
||||
val hasDoneListToMapMigration: Boolean,
|
||||
val followedTopicIds: Set<String> = emptySet(),
|
||||
val followedAuthorIds: Set<String> = emptySet(),
|
||||
val bookmarkedNewsResourceIds: Set<String> = emptySet(),
|
||||
val viewedNewsResourceIds: Set<String> = emptySet(),
|
||||
val themeBrand: ThemeBrandProto,
|
||||
val darkThemeConfig: DarkThemeConfigProto,
|
||||
val shouldHideOnboarding: Boolean,
|
||||
val useDynamicColor: Boolean,
|
||||
) {
|
||||
companion object {
|
||||
val DEFAULT = UserPreferences(
|
||||
topicChangeListVersion = 0,
|
||||
authorChangeListVersion = 0,
|
||||
newsResourceChangeListVersion = 0,
|
||||
hasDoneIntToStringIdMigration = false,
|
||||
hasDoneListToMapMigration = false,
|
||||
themeBrand = THEME_BRAND_UNSPECIFIED,
|
||||
darkThemeConfig = DARK_THEME_CONFIG_FOLLOW_SYSTEM,
|
||||
shouldHideOnboarding = false,
|
||||
useDynamicColor = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore.di
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.core.DataStoreFactory
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import com.google.samples.apps.nowinandroid.core.datastore.UserPreferencesSerializer
|
||||
import me.tatarka.inject.annotations.Component
|
||||
import me.tatarka.inject.annotations.Provides
|
||||
|
||||
@Component
|
||||
abstract class DataStoreComponent {
|
||||
|
||||
private val Context.dataStore by preferencesDataStore("user_preferences")
|
||||
|
||||
@Provides
|
||||
fun providesDataStore(context: Context): DataStore<Preferences> {
|
||||
return context.dataStore
|
||||
}
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore.di
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import com.russhwolf.settings.ExperimentalSettingsApi
|
||||
import com.russhwolf.settings.coroutines.FlowSettings
|
||||
import com.russhwolf.settings.datastore.DataStoreSettings
|
||||
import me.tatarka.inject.annotations.Component
|
||||
import me.tatarka.inject.annotations.Provides
|
||||
|
||||
@Component
|
||||
actual abstract class SettingsComponent {
|
||||
@OptIn(ExperimentalSettingsApi::class)
|
||||
@Provides
|
||||
actual fun providesFlowSettings(
|
||||
dataStore: DataStore<Preferences>
|
||||
): FlowSettings {
|
||||
return DataStoreSettings()
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2022 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<manifest />
|
||||
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore
|
||||
|
||||
import androidx.datastore.core.DataMigration
|
||||
|
||||
/**
|
||||
* Migrates saved ids from [Int] to [String] types
|
||||
*/
|
||||
internal object IntToStringIdsMigration : DataMigration<UserPreferences> {
|
||||
|
||||
override suspend fun cleanUp() = Unit
|
||||
|
||||
override suspend fun migrate(currentData: UserPreferences): UserPreferences =
|
||||
currentData.copy {
|
||||
// Migrate topic ids
|
||||
deprecatedFollowedTopicIds.clear()
|
||||
deprecatedFollowedTopicIds.addAll(
|
||||
currentData.deprecatedIntFollowedTopicIdsList.map(Int::toString),
|
||||
)
|
||||
deprecatedIntFollowedTopicIds.clear()
|
||||
|
||||
// Migrate author ids
|
||||
deprecatedFollowedAuthorIds.clear()
|
||||
deprecatedFollowedAuthorIds.addAll(
|
||||
currentData.deprecatedIntFollowedAuthorIdsList.map(Int::toString),
|
||||
)
|
||||
deprecatedIntFollowedAuthorIds.clear()
|
||||
|
||||
// Mark migration as complete
|
||||
hasDoneIntToStringIdMigration = true
|
||||
}
|
||||
|
||||
override suspend fun shouldMigrate(currentData: UserPreferences): Boolean =
|
||||
!currentData.hasDoneIntToStringIdMigration
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore
|
||||
|
||||
import androidx.datastore.core.DataMigration
|
||||
|
||||
/**
|
||||
* Migrates from using lists to maps for user data.
|
||||
*/
|
||||
internal object ListToMapMigration : DataMigration<UserPreferences> {
|
||||
|
||||
override suspend fun cleanUp() = Unit
|
||||
|
||||
override suspend fun migrate(currentData: UserPreferences): UserPreferences =
|
||||
currentData.copy {
|
||||
// Migrate topic id lists
|
||||
followedTopicIds.clear()
|
||||
followedTopicIds.putAll(
|
||||
currentData.deprecatedFollowedTopicIdsList.associateWith { true },
|
||||
)
|
||||
deprecatedFollowedTopicIds.clear()
|
||||
|
||||
// Migrate author ids
|
||||
followedAuthorIds.clear()
|
||||
followedAuthorIds.putAll(
|
||||
currentData.deprecatedFollowedAuthorIdsList.associateWith { true },
|
||||
)
|
||||
deprecatedFollowedAuthorIds.clear()
|
||||
|
||||
// Migrate bookmarks
|
||||
bookmarkedNewsResourceIds.clear()
|
||||
bookmarkedNewsResourceIds.putAll(
|
||||
currentData.deprecatedBookmarkedNewsResourceIdsList.associateWith { true },
|
||||
)
|
||||
deprecatedBookmarkedNewsResourceIds.clear()
|
||||
|
||||
// Mark migration as complete
|
||||
hasDoneListToMapMigration = true
|
||||
}
|
||||
|
||||
override suspend fun shouldMigrate(currentData: UserPreferences): Boolean =
|
||||
!currentData.hasDoneListToMapMigration
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore
|
||||
|
||||
import androidx.datastore.core.CorruptionException
|
||||
import androidx.datastore.core.Serializer
|
||||
import com.google.protobuf.InvalidProtocolBufferException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* An [androidx.datastore.core.Serializer] for the [UserPreferences] proto.
|
||||
*/
|
||||
class UserPreferencesSerializer @Inject constructor() : Serializer<UserPreferences> {
|
||||
override val defaultValue: UserPreferences = UserPreferences.getDefaultInstance()
|
||||
|
||||
override suspend fun readFrom(input: InputStream): UserPreferences =
|
||||
try {
|
||||
// readFrom is already called on the data store background thread
|
||||
UserPreferences.parseFrom(input)
|
||||
} catch (exception: InvalidProtocolBufferException) {
|
||||
throw CorruptionException("Cannot read proto.", exception)
|
||||
}
|
||||
|
||||
override suspend fun writeTo(t: UserPreferences, output: OutputStream) {
|
||||
// writeTo is already called on the data store background thread
|
||||
t.writeTo(output)
|
||||
}
|
||||
}
|
||||
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore
|
||||
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Unit test for [IntToStringIdsMigration]
|
||||
*/
|
||||
class IntToStringIdsMigrationTest {
|
||||
|
||||
@Test
|
||||
fun IntToStringIdsMigration_should_migrate_topic_ids() = runTest {
|
||||
// Set up existing preferences with topic int ids
|
||||
val preMigrationUserPreferences = userPreferences {
|
||||
deprecatedIntFollowedTopicIds.addAll(listOf(1, 2, 3))
|
||||
}
|
||||
// Assert that there are no string topic ids yet
|
||||
assertEquals(
|
||||
emptyList<String>(),
|
||||
preMigrationUserPreferences.deprecatedFollowedTopicIdsList,
|
||||
)
|
||||
|
||||
// Run the migration
|
||||
val postMigrationUserPreferences =
|
||||
IntToStringIdsMigration.migrate(preMigrationUserPreferences)
|
||||
|
||||
// Assert the deprecated int topic ids have been migrated to the string topic ids
|
||||
assertEquals(
|
||||
userPreferences {
|
||||
deprecatedFollowedTopicIds.addAll(listOf("1", "2", "3"))
|
||||
hasDoneIntToStringIdMigration = true
|
||||
},
|
||||
postMigrationUserPreferences,
|
||||
)
|
||||
|
||||
// Assert that the migration has been marked complete
|
||||
assertTrue(postMigrationUserPreferences.hasDoneIntToStringIdMigration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun IntToStringIdsMigration_should_migrate_author_ids() = runTest {
|
||||
// Set up existing preferences with author int ids
|
||||
val preMigrationUserPreferences = userPreferences {
|
||||
deprecatedIntFollowedAuthorIds.addAll(listOf(4, 5, 6))
|
||||
}
|
||||
// Assert that there are no string author ids yet
|
||||
assertEquals(
|
||||
emptyList<String>(),
|
||||
preMigrationUserPreferences.deprecatedFollowedAuthorIdsList,
|
||||
)
|
||||
|
||||
// Run the migration
|
||||
val postMigrationUserPreferences =
|
||||
IntToStringIdsMigration.migrate(preMigrationUserPreferences)
|
||||
|
||||
// Assert the deprecated int author ids have been migrated to the string author ids
|
||||
assertEquals(
|
||||
userPreferences {
|
||||
deprecatedFollowedAuthorIds.addAll(listOf("4", "5", "6"))
|
||||
hasDoneIntToStringIdMigration = true
|
||||
},
|
||||
postMigrationUserPreferences,
|
||||
)
|
||||
|
||||
// Assert that the migration has been marked complete
|
||||
assertTrue(postMigrationUserPreferences.hasDoneIntToStringIdMigration)
|
||||
}
|
||||
}
|
||||
@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore
|
||||
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ListToMapMigrationTest {
|
||||
|
||||
@Test
|
||||
fun ListToMapMigration_should_migrate_topic_ids() = runTest {
|
||||
// Set up existing preferences with topic ids
|
||||
val preMigrationUserPreferences = userPreferences {
|
||||
deprecatedFollowedTopicIds.addAll(listOf("1", "2", "3"))
|
||||
}
|
||||
// Assert that there are no topic ids in the map yet
|
||||
assertEquals(
|
||||
emptyMap<String, Boolean>(),
|
||||
preMigrationUserPreferences.followedTopicIdsMap,
|
||||
)
|
||||
|
||||
// Run the migration
|
||||
val postMigrationUserPreferences =
|
||||
ListToMapMigration.migrate(preMigrationUserPreferences)
|
||||
|
||||
// Assert the deprecated topic ids have been migrated to the topic ids map
|
||||
assertEquals(
|
||||
mapOf("1" to true, "2" to true, "3" to true),
|
||||
postMigrationUserPreferences.followedTopicIdsMap,
|
||||
)
|
||||
|
||||
// Assert that the migration has been marked complete
|
||||
assertTrue(postMigrationUserPreferences.hasDoneListToMapMigration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ListToMapMigration_should_migrate_author_ids() = runTest {
|
||||
// Set up existing preferences with author ids
|
||||
val preMigrationUserPreferences = userPreferences {
|
||||
deprecatedFollowedAuthorIds.addAll(listOf("4", "5", "6"))
|
||||
}
|
||||
// Assert that there are no author ids in the map yet
|
||||
assertEquals(
|
||||
emptyMap<String, Boolean>(),
|
||||
preMigrationUserPreferences.followedAuthorIdsMap,
|
||||
)
|
||||
|
||||
// Run the migration
|
||||
val postMigrationUserPreferences =
|
||||
ListToMapMigration.migrate(preMigrationUserPreferences)
|
||||
|
||||
// Assert the deprecated author ids have been migrated to the author ids map
|
||||
assertEquals(
|
||||
mapOf("4" to true, "5" to true, "6" to true),
|
||||
postMigrationUserPreferences.followedAuthorIdsMap,
|
||||
)
|
||||
|
||||
// Assert that the migration has been marked complete
|
||||
assertTrue(postMigrationUserPreferences.hasDoneListToMapMigration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun ListToMapMigration_should_migrate_bookmarks() = runTest {
|
||||
// Set up existing preferences with bookmarks
|
||||
val preMigrationUserPreferences = userPreferences {
|
||||
deprecatedBookmarkedNewsResourceIds.addAll(listOf("7", "8", "9"))
|
||||
}
|
||||
// Assert that there are no bookmarks in the map yet
|
||||
assertEquals(
|
||||
emptyMap<String, Boolean>(),
|
||||
preMigrationUserPreferences.bookmarkedNewsResourceIdsMap,
|
||||
)
|
||||
|
||||
// Run the migration
|
||||
val postMigrationUserPreferences =
|
||||
ListToMapMigration.migrate(preMigrationUserPreferences)
|
||||
|
||||
// Assert the deprecated bookmarks have been migrated to the bookmarks map
|
||||
assertEquals(
|
||||
mapOf("7" to true, "8" to true, "9" to true),
|
||||
postMigrationUserPreferences.bookmarkedNewsResourceIdsMap,
|
||||
)
|
||||
|
||||
// Assert that the migration has been marked complete
|
||||
assertTrue(postMigrationUserPreferences.hasDoneListToMapMigration)
|
||||
}
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.core.datastore
|
||||
|
||||
import androidx.datastore.core.CorruptionException
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class UserPreferencesSerializerTest {
|
||||
private val userPreferencesSerializer = UserPreferencesSerializer()
|
||||
|
||||
@Test
|
||||
fun defaultUserPreferences_isEmpty() {
|
||||
assertEquals(
|
||||
userPreferences {
|
||||
// Default value
|
||||
},
|
||||
userPreferencesSerializer.defaultValue,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun writingAndReadingUserPreferences_outputsCorrectValue() = runTest {
|
||||
val expectedUserPreferences = userPreferences {
|
||||
followedTopicIds.put("0", true)
|
||||
followedTopicIds.put("1", true)
|
||||
}
|
||||
|
||||
val outputStream = ByteArrayOutputStream()
|
||||
|
||||
expectedUserPreferences.writeTo(outputStream)
|
||||
|
||||
val inputStream = ByteArrayInputStream(outputStream.toByteArray())
|
||||
|
||||
val actualUserPreferences = userPreferencesSerializer.readFrom(inputStream)
|
||||
|
||||
assertEquals(
|
||||
expectedUserPreferences,
|
||||
actualUserPreferences,
|
||||
)
|
||||
}
|
||||
|
||||
@Test(expected = CorruptionException::class)
|
||||
fun readingInvalidUserPreferences_throwsCorruptionException() = runTest {
|
||||
userPreferencesSerializer.readFrom(ByteArrayInputStream(byteArrayOf(0)))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue