Skip to content

Commit

Permalink
Merge branch '1.2.4-prep'
Browse files Browse the repository at this point in the history
  • Loading branch information
shorthouse committed Mar 11, 2024
2 parents 13da5d5 + 19f9e93 commit 1d16643
Show file tree
Hide file tree
Showing 65 changed files with 435 additions and 251 deletions.
2 changes: 1 addition & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
-keep class * extends com.google.gson.reflect.TypeToken

# Keep user preferences enums
-keep public enum dev.shorthouse.coinwatch.data.userPreferences.**{
-keep public enum dev.shorthouse.coinwatch.data.preferences.global.**{
*;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package dev.shorthouse.coinwatch.data

import android.content.Context
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.dataStoreFile
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import dev.shorthouse.coinwatch.data.preferences.favourites.FavouritesPreferencesRepository
import dev.shorthouse.coinwatch.data.preferences.favourites.FavouritesPreferencesSerializer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.resetMain
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.junit.After
import org.junit.Before
import org.junit.Test

@OptIn(ExperimentalCoroutinesApi::class)
class FavouritesPreferencesRepositoryTest {

private val testContext: Context = ApplicationProvider.getApplicationContext()
private val testCoroutineDispatcher = StandardTestDispatcher()
private val testCoroutineScope = TestScope(testCoroutineDispatcher + Job())

private val testDataStore = DataStoreFactory.create(
serializer = FavouritesPreferencesSerializer,
scope = testCoroutineScope,
produceFile = { testContext.dataStoreFile("test_datastore") }
)

// Class under test
private val favouritesPreferencesRepository = FavouritesPreferencesRepository(testDataStore)

@Before
fun setup() {
Dispatchers.setMain(testCoroutineDispatcher)
}

@After
fun cleanup() {
Dispatchers.resetMain()
testCoroutineScope.cancel()
}

@Test
fun when_isFavouritesCondensedTrue_should_updateFavouritesPreferences() =
testCoroutineScope.runTest {
val isCondensed = true

favouritesPreferencesRepository.updateIsFavouritesCondensed(
isCondensed = isCondensed
)

val favouritesPreferences = favouritesPreferencesRepository
.favouritesPreferencesFlow
.first()

assertThat(favouritesPreferences.isFavouritesCondensed).isTrue()
}

@Test
fun when_isFavouritesCondensedFalse_should_updateFavouritesPreferences() =
testCoroutineScope.runTest {
val isCondensed = false

favouritesPreferencesRepository.updateIsFavouritesCondensed(
isCondensed = isCondensed
)

val favouritesPreferences = favouritesPreferencesRepository
.favouritesPreferencesFlow
.first()

assertThat(favouritesPreferences.isFavouritesCondensed).isFalse()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import androidx.datastore.core.DataStoreFactory
import androidx.datastore.dataStoreFile
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import dev.shorthouse.coinwatch.data.userPreferences.CoinSort
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.userPreferences.StartScreen
import dev.shorthouse.coinwatch.data.userPreferences.UserPreferencesRepository
import dev.shorthouse.coinwatch.data.userPreferences.UserPreferencesSerializer
import dev.shorthouse.coinwatch.data.preferences.global.CoinSort
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.data.preferences.global.StartScreen
import dev.shorthouse.coinwatch.data.preferences.global.UserPreferencesRepository
import dev.shorthouse.coinwatch.data.preferences.global.UserPreferencesSerializer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import androidx.compose.ui.test.swipeDown
import com.google.common.truth.Truth.assertThat
import dev.shorthouse.coinwatch.R
import dev.shorthouse.coinwatch.data.source.local.model.Coin
import dev.shorthouse.coinwatch.data.userPreferences.CoinSort
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.CoinSort
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.model.Percentage
import dev.shorthouse.coinwatch.model.Price
import dev.shorthouse.coinwatch.ui.model.TimeOfDay
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import com.google.common.truth.Truth.assertThat
import dev.shorthouse.coinwatch.BuildConfig
import dev.shorthouse.coinwatch.data.userPreferences.StartScreen
import dev.shorthouse.coinwatch.data.preferences.global.StartScreen
import dev.shorthouse.coinwatch.ui.screen.settings.SettingsScreen
import dev.shorthouse.coinwatch.ui.screen.settings.SettingsUiState
import dev.shorthouse.coinwatch.ui.theme.AppTheme
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package dev.shorthouse.coinwatch
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.shorthouse.coinwatch.data.userPreferences.StartScreen
import dev.shorthouse.coinwatch.data.preferences.global.StartScreen
import dev.shorthouse.coinwatch.domain.GetUserPreferencesUseCase
import dev.shorthouse.coinwatch.navigation.NavigationBarScreen
import javax.inject.Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package dev.shorthouse.coinwatch.data.mapper

import dev.shorthouse.coinwatch.common.toSanitisedBigDecimalOrNull
import dev.shorthouse.coinwatch.data.source.remote.model.CoinChartApiModel
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.model.CoinChart
import dev.shorthouse.coinwatch.model.Percentage
import dev.shorthouse.coinwatch.model.Price
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.shorthouse.coinwatch.data.mapper

import dev.shorthouse.coinwatch.data.source.remote.model.CoinDetailsApiModel
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.model.CoinDetails
import dev.shorthouse.coinwatch.model.Price
import java.text.NumberFormat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package dev.shorthouse.coinwatch.data.mapper

import dev.shorthouse.coinwatch.data.source.local.model.Coin
import dev.shorthouse.coinwatch.data.source.remote.model.CoinsApiModel
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.model.Percentage
import dev.shorthouse.coinwatch.model.Price
import javax.inject.Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package dev.shorthouse.coinwatch.data.mapper

import dev.shorthouse.coinwatch.data.source.local.model.FavouriteCoin
import dev.shorthouse.coinwatch.data.source.remote.model.FavouriteCoinsApiModel
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.model.Percentage
import dev.shorthouse.coinwatch.model.Price
import java.math.BigDecimal
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package dev.shorthouse.coinwatch.data.preferences

import androidx.datastore.core.Serializer
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json
import timber.log.Timber
import java.io.InputStream
import java.io.OutputStream

abstract class BasePreferencesSerializer<T>(
private val defaultInstance: () -> T,
private val serializer: KSerializer<T>,
) : Serializer<T> {

override val defaultValue: T
get() = defaultInstance()

override suspend fun readFrom(input: InputStream): T {
return try {
Json.decodeFromString(
deserializer = serializer,
string = input.readBytes().decodeToString()
)
} catch (exception: SerializationException) {
Timber.e("Error serializing preferences with ${serializer.descriptor}", exception)
defaultValue
}
}

override suspend fun writeTo(t: T, output: OutputStream) {
output.write(
Json.encodeToString(
serializer = serializer,
value = t
).encodeToByteArray()
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.shorthouse.coinwatch.data.preferences.favourites

import kotlinx.serialization.Serializable

@Serializable
data class FavouritesPreferences(
val isFavouritesCondensed: Boolean = false
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package dev.shorthouse.coinwatch.data.preferences.favourites

import androidx.datastore.core.DataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first
import timber.log.Timber
import java.io.IOException
import javax.inject.Inject

class FavouritesPreferencesRepository @Inject constructor(
private val favouritesPreferencesDataStore: DataStore<FavouritesPreferences>
) {
val favouritesPreferencesFlow: Flow<FavouritesPreferences> = favouritesPreferencesDataStore.data
.catch { exception ->
if (exception is IOException) {
Timber.e("Error reading favourites preferences", exception)
emit(FavouritesPreferences())
} else {
throw exception
}
}

suspend fun updateIsFavouritesCondensed(isCondensed: Boolean) {
if (isCondensed != favouritesPreferencesFlow.first().isFavouritesCondensed) {
favouritesPreferencesDataStore.updateData { currentPreferences ->
currentPreferences.copy(isFavouritesCondensed = isCondensed)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.shorthouse.coinwatch.data.preferences.favourites

import dev.shorthouse.coinwatch.data.preferences.BasePreferencesSerializer

object FavouritesPreferencesSerializer : BasePreferencesSerializer<FavouritesPreferences>(
defaultInstance = { FavouritesPreferences() },
serializer = FavouritesPreferences.serializer(),
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.shorthouse.coinwatch.data.userPreferences
package dev.shorthouse.coinwatch.data.preferences.global

import androidx.annotation.StringRes
import dev.shorthouse.coinwatch.R
Expand All @@ -9,7 +9,6 @@ data class UserPreferences(
val coinSort: CoinSort = CoinSort.MarketCap,
val currency: Currency = Currency.USD,
val startScreen: StartScreen = StartScreen.Market,
val isFavouritesCondensed: Boolean = false
)

enum class Currency(val symbol: String, @StringRes val nameId: Int) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dev.shorthouse.coinwatch.data.userPreferences
package dev.shorthouse.coinwatch.data.preferences.global

import androidx.datastore.core.DataStore
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -44,10 +44,4 @@ class UserPreferencesRepository @Inject constructor(
}
}
}

suspend fun updateIsFavouritesCondensed(isCondensed: Boolean) {
userPreferencesDataStore.updateData { currentPreferences ->
currentPreferences.copy(isFavouritesCondensed = isCondensed)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package dev.shorthouse.coinwatch.data.preferences.global

import dev.shorthouse.coinwatch.data.preferences.BasePreferencesSerializer

object UserPreferencesSerializer : BasePreferencesSerializer<UserPreferences>(
defaultInstance = { UserPreferences() },
serializer = UserPreferences.serializer(),
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.shorthouse.coinwatch.data.repository.chart

import dev.shorthouse.coinwatch.common.Result
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.model.CoinChart
import kotlinx.coroutines.flow.Flow

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.shorthouse.coinwatch.data.repository.chart

import dev.shorthouse.coinwatch.common.Result
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.data.mapper.CoinChartMapper
import dev.shorthouse.coinwatch.data.source.remote.CoinNetworkDataSource
import dev.shorthouse.coinwatch.di.IoDispatcher
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package dev.shorthouse.coinwatch.data.repository.coin

import dev.shorthouse.coinwatch.common.Result
import dev.shorthouse.coinwatch.data.source.local.model.Coin
import dev.shorthouse.coinwatch.data.userPreferences.CoinSort
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.CoinSort
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import kotlinx.coroutines.flow.Flow

interface CoinRepository {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import dev.shorthouse.coinwatch.data.mapper.CoinMapper
import dev.shorthouse.coinwatch.data.source.local.CoinLocalDataSource
import dev.shorthouse.coinwatch.data.source.local.model.Coin
import dev.shorthouse.coinwatch.data.source.remote.CoinNetworkDataSource
import dev.shorthouse.coinwatch.data.userPreferences.CoinSort
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.CoinSort
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.di.IoDispatcher
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.shorthouse.coinwatch.data.repository.details

import dev.shorthouse.coinwatch.common.Result
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.model.CoinDetails
import kotlinx.coroutines.flow.Flow

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.shorthouse.coinwatch.data.repository.details

import dev.shorthouse.coinwatch.common.Result
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.data.mapper.CoinDetailsMapper
import dev.shorthouse.coinwatch.data.source.remote.CoinNetworkDataSource
import dev.shorthouse.coinwatch.di.IoDispatcher
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package dev.shorthouse.coinwatch.data.repository.favouriteCoin

import dev.shorthouse.coinwatch.common.Result
import dev.shorthouse.coinwatch.data.source.local.model.FavouriteCoin
import dev.shorthouse.coinwatch.data.userPreferences.CoinSort
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.CoinSort
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import kotlinx.coroutines.flow.Flow

interface FavouriteCoinRepository {
Expand All @@ -12,6 +12,7 @@ interface FavouriteCoinRepository {
coinSort: CoinSort,
currency: Currency
): Result<List<FavouriteCoin>>

fun getCachedFavouriteCoins(): Flow<Result<List<FavouriteCoin>>>
suspend fun updateCachedFavouriteCoins(favouriteCoins: List<FavouriteCoin>)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import dev.shorthouse.coinwatch.data.source.local.CoinLocalDataSource
import dev.shorthouse.coinwatch.data.source.local.model.Coin
import dev.shorthouse.coinwatch.data.source.local.model.FavouriteCoin
import dev.shorthouse.coinwatch.data.source.remote.CoinNetworkDataSource
import dev.shorthouse.coinwatch.data.userPreferences.CoinSort
import dev.shorthouse.coinwatch.data.userPreferences.Currency
import dev.shorthouse.coinwatch.data.preferences.global.CoinSort
import dev.shorthouse.coinwatch.data.preferences.global.Currency
import dev.shorthouse.coinwatch.di.IoDispatcher
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
Expand Down
Loading

0 comments on commit 1d16643

Please sign in to comment.