Implement shopping lists screen (#129)
* Initialize shopping lists feature * Start shopping lists screen with Compose * Add icon to shopping list name * Add shopping lists to menu * Set max size for the list * Replace compose-adapter with accompanist * Remove unused fields from shopping lists response * Show list of shopping lists from BE * Hide shopping lists if Mealie is 0.5.6 * Add shopping list item click listener * Create material app theme for Compose * Use shorter names * Load shopping lists by pages and save to db * Make page handling logic match recipes * Add swipe to refresh to shopping lists * Extract SwipeToRefresh Composable * Make LazyPagingColumn generic * Show refresh only when mediator is refreshing * Do not refresh automatically * Allow controlling Activity state from modules * Implement navigating to shopping list screen * Move Compose libraries setup to a plugin * Implement loading full shopping list info * Move Storage classes to database module * Save shopping list items to DB * Use separate names for separate ids * Do only one DB version update * Use unique names for all columns * Display shopping list items * Move OperationUiState to ui module * Subscribe to shopping lists updates * Indicate progress with progress bar * Use strings from resources * Format shopping list item quantities * Hide unit/food/note/quantity if they are not set * Implement updating shopping list item checked state * Remove unnecessary null checks * Disable checkbox when it is being updated * Split shopping list screen into composables * Show items immediately if they are saved * Fix showing "list is empty" before the items * Show Snackbar when error happens * Reduce shopping list items paddings * Remove shopping lists when URL is changed * Add error/empty state handling to shopping lists * Fix empty error state * Fix tests compilation * Add margin between text and button * Add divider between checked and unchecked items * Move divider to the item * Refresh the shopping lists on authentication * Use retry when necessary * Remove excessive logging * Fix pages bounds check * Move FlowExtensionsTest * Update Compose version * Fix showing loading indicator for shopping lists * Add Russian translation * Fix SDK version lint check * Rename parameter to match interface * Add DB migration TODO * Get rid of DB migrations * Do not use pagination with shopping lists * Cleanup after the pagination removal * Load shopping list items * Remove shopping lists storage * Rethrow CancellationException in LoadingHelper * Add pull-to-refresh on shopping list screen * Extract LazyColumnWithLoadingState * Split refresh errors and loading state * Reuse LazyColumnWithLoadingState for shopping list items * Remove paging-compose dependency * Refresh shopping list items on authentication * Disable missing translation lint check * Update Compose and Kotlin versions * Fix order of checked items * Hide useless information from a shopping list item
This commit is contained in:
@@ -3,10 +3,12 @@ package gq.kirmanak.mealient.data.add.impl
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeDataSource
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeRepo
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_ADD_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.datastore.recipe.AddRecipeStorage
|
||||
import gq.kirmanak.mealient.datastore_test.PORRIDGE_RECIPE_DRAFT
|
||||
import gq.kirmanak.mealient.model_mapper.ModelMapper
|
||||
import gq.kirmanak.mealient.model_mapper.ModelMapperImpl
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_DRAFT
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -24,12 +26,14 @@ class AddRecipeRepoTest : BaseUnitTest() {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var storage: AddRecipeStorage
|
||||
|
||||
private val modelMapper: ModelMapper = ModelMapperImpl()
|
||||
|
||||
private lateinit var subject: AddRecipeRepo
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
subject = AddRecipeRepoImpl(dataSource, storage, logger)
|
||||
subject = AddRecipeRepoImpl(dataSource, storage, logger, modelMapper)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package gq.kirmanak.mealient.data.baseurl
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.datasource.models.VersionInfo
|
||||
import gq.kirmanak.mealient.datasource_test.VERSION_INFO_V0
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_VERSION
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_INFO_V0
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.impl.annotations.MockK
|
||||
|
||||
@@ -5,6 +5,18 @@ import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
||||
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_ADD_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_ADD_RECIPE_REQUEST_V0
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_CREATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_RECIPE_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_UPDATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.datasource_test.RECIPE_SUMMARY_PORRIDGE_V0
|
||||
import gq.kirmanak.mealient.datasource_test.RECIPE_SUMMARY_PORRIDGE_V1
|
||||
import gq.kirmanak.mealient.model_mapper.ModelMapper
|
||||
import gq.kirmanak.mealient.model_mapper.ModelMapperImpl
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.FAVORITE_RECIPES_LIST
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION_V0
|
||||
@@ -12,16 +24,6 @@ import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION_V1
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.USER_INFO_V0
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.USER_INFO_V1
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_REQUEST_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_CREATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_UPDATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V1
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -45,12 +47,14 @@ class MealieDataSourceWrapperTest : BaseUnitTest() {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var v1Source: MealieDataSourceV1
|
||||
|
||||
private val modelMapper: ModelMapper = ModelMapperImpl()
|
||||
|
||||
lateinit var subject: MealieDataSourceWrapper
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
subject = MealieDataSourceWrapper(serverInfoRepo, v0Source, v1Source)
|
||||
subject = MealieDataSourceWrapper(serverInfoRepo, v0Source, v1Source, modelMapper)
|
||||
coEvery { v0Source.requestUserInfo() } returns USER_INFO_V0
|
||||
coEvery { v1Source.requestUserInfo() } returns USER_INFO_V1
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
package gq.kirmanak.mealient.data.recipes.db
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import gq.kirmanak.mealient.database.AppDb
|
||||
import gq.kirmanak.mealient.test.HiltRobolectricTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.BREAD_INGREDIENT
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_BREAD_RECIPE_INGREDIENT_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.FULL_CAKE_INFO_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.FULL_PORRIDGE_INFO_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_CAKE_RECIPE_INSTRUCTION_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_INSTRUCTION
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARY_ENTITIES
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltAndroidTest
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
|
||||
@Inject
|
||||
lateinit var subject: RecipeStorageImpl
|
||||
|
||||
@Inject
|
||||
lateinit var appDb: AppDb
|
||||
|
||||
@Test
|
||||
fun `when saveRecipes then saves recipes`() = runTest {
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
val actualTags = appDb.recipeDao().queryAllRecipes()
|
||||
assertThat(actualTags).containsExactly(
|
||||
CAKE_RECIPE_SUMMARY_ENTITY,
|
||||
PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when refreshAll then old recipes aren't preserved`() = runTest {
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.refreshAll(listOf(CAKE_RECIPE_SUMMARY_ENTITY))
|
||||
val actual = appDb.recipeDao().queryAllRecipes()
|
||||
assertThat(actual).containsExactly(CAKE_RECIPE_SUMMARY_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when clearAllLocalData then recipes aren't preserved`() = runTest {
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.clearAllLocalData()
|
||||
val actual = appDb.recipeDao().queryAllRecipes()
|
||||
assertThat(actual).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when saveRecipeInfo then saves recipe info`() = runTest {
|
||||
subject.saveRecipes(listOf(CAKE_RECIPE_SUMMARY_ENTITY))
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")
|
||||
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when saveRecipeInfo with two then saves second`() = runTest {
|
||||
subject.saveRecipes(TEST_RECIPE_SUMMARY_ENTITIES)
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
subject.saveRecipeInfo(PORRIDGE_FULL_RECIPE_INFO)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("2")
|
||||
assertThat(actual).isEqualTo(FULL_PORRIDGE_INFO_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when saveRecipeInfo secondly then overwrites ingredients`() = runTest {
|
||||
subject.saveRecipes(listOf(CAKE_RECIPE_SUMMARY_ENTITY))
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
val newRecipe = CAKE_FULL_RECIPE_INFO.copy(recipeIngredients = listOf(BREAD_INGREDIENT))
|
||||
subject.saveRecipeInfo(newRecipe)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")?.recipeIngredients
|
||||
val expected = listOf(CAKE_BREAD_RECIPE_INGREDIENT_ENTITY.copy(localId = 3))
|
||||
assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when saveRecipeInfo secondly then overwrites instructions`() = runTest {
|
||||
subject.saveRecipes(listOf(CAKE_RECIPE_SUMMARY_ENTITY))
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
val newRecipe = CAKE_FULL_RECIPE_INFO.copy(recipeInstructions = listOf(MIX_INSTRUCTION))
|
||||
subject.saveRecipeInfo(newRecipe)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")?.recipeInstructions
|
||||
val expected = listOf(MIX_CAKE_RECIPE_INSTRUCTION_ENTITY.copy(localId = 3))
|
||||
assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,12 @@ package gq.kirmanak.mealient.data.recipes.impl
|
||||
import androidx.paging.PagingSource
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import gq.kirmanak.mealient.data.recipes.db.RecipeStorage
|
||||
import gq.kirmanak.mealient.database.CAKE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.database.PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.database.TEST_RECIPE_SUMMARY_ENTITIES
|
||||
import gq.kirmanak.mealient.database.recipe.RecipeStorage
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||
import gq.kirmanak.mealient.test.HiltRobolectricTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARY_ENTITIES
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
@@ -3,13 +3,20 @@ package gq.kirmanak.mealient.data.recipes.impl
|
||||
import androidx.paging.LoadType
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.recipes.RecipeRepo
|
||||
import gq.kirmanak.mealient.data.recipes.db.RecipeStorage
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource
|
||||
import gq.kirmanak.mealient.database.BAKE_CAKE_RECIPE_INSTRUCTION_ENTITY
|
||||
import gq.kirmanak.mealient.database.CAKE_BREAD_RECIPE_INGREDIENT_ENTITY
|
||||
import gq.kirmanak.mealient.database.CAKE_RECIPE_ENTITY
|
||||
import gq.kirmanak.mealient.database.CAKE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.database.CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY
|
||||
import gq.kirmanak.mealient.database.FULL_CAKE_INFO_ENTITY
|
||||
import gq.kirmanak.mealient.database.MIX_CAKE_RECIPE_INSTRUCTION_ENTITY
|
||||
import gq.kirmanak.mealient.database.recipe.RecipeStorage
|
||||
import gq.kirmanak.mealient.datasource.NetworkError.Unauthorized
|
||||
import gq.kirmanak.mealient.datasource_test.CAKE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.model_mapper.ModelMapper
|
||||
import gq.kirmanak.mealient.model_mapper.ModelMapperImpl
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.FULL_CAKE_INFO_ENTITY
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.coVerifyOrder
|
||||
@@ -36,12 +43,21 @@ class RecipeRepoTest : BaseUnitTest() {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var pagingSourceFactory: RecipePagingSourceFactory
|
||||
|
||||
private val modelMapper: ModelMapper = ModelMapperImpl()
|
||||
|
||||
lateinit var subject: RecipeRepo
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
subject = RecipeRepoImpl(remoteMediator, storage, pagingSourceFactory, dataSource, logger)
|
||||
subject = RecipeRepoImpl(
|
||||
remoteMediator,
|
||||
storage,
|
||||
pagingSourceFactory,
|
||||
dataSource,
|
||||
logger,
|
||||
modelMapper,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -55,7 +71,18 @@ class RecipeRepoTest : BaseUnitTest() {
|
||||
fun `when refreshRecipeInfo expect call to storage`() = runTest {
|
||||
coEvery { dataSource.requestRecipeInfo(eq("cake")) } returns CAKE_FULL_RECIPE_INFO
|
||||
subject.refreshRecipeInfo("cake")
|
||||
coVerify { storage.saveRecipeInfo(eq(CAKE_FULL_RECIPE_INFO)) }
|
||||
coVerify {
|
||||
storage.saveRecipeInfo(
|
||||
eq(CAKE_RECIPE_ENTITY),
|
||||
eq(
|
||||
listOf(
|
||||
CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY,
|
||||
CAKE_BREAD_RECIPE_INGREDIENT_ENTITY
|
||||
)
|
||||
),
|
||||
eq(listOf(MIX_CAKE_RECIPE_INSTRUCTION_ENTITY, BAKE_CAKE_RECIPE_INSTRUCTION_ENTITY))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -3,13 +3,15 @@ package gq.kirmanak.mealient.data.recipes.impl
|
||||
import androidx.paging.*
|
||||
import androidx.paging.LoadType.*
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.recipes.db.RecipeStorage
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource
|
||||
import gq.kirmanak.mealient.database.TEST_RECIPE_SUMMARY_ENTITIES
|
||||
import gq.kirmanak.mealient.database.recipe.RecipeStorage
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||
import gq.kirmanak.mealient.datasource.NetworkError.Unauthorized
|
||||
import gq.kirmanak.mealient.datasource_test.TEST_RECIPE_SUMMARIES
|
||||
import gq.kirmanak.mealient.model_mapper.ModelMapper
|
||||
import gq.kirmanak.mealient.model_mapper.ModelMapperImpl
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARIES
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARY_ENTITIES
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.impl.annotations.MockK
|
||||
@@ -41,6 +43,8 @@ class RecipesRemoteMediatorTest : BaseUnitTest() {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var pagingSourceFactory: RecipePagingSourceFactory
|
||||
|
||||
private val modelMapper: ModelMapper = ModelMapperImpl()
|
||||
|
||||
@Before
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
@@ -50,6 +54,7 @@ class RecipesRemoteMediatorTest : BaseUnitTest() {
|
||||
pagingSourceFactory = pagingSourceFactory,
|
||||
logger = logger,
|
||||
dispatchers = dispatchers,
|
||||
modelMapper = modelMapper,
|
||||
)
|
||||
coEvery { dataSource.getFavoriteRecipes() } returns emptyList()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package gq.kirmanak.mealient.data.share
|
||||
|
||||
import gq.kirmanak.mealient.datasource.models.ParseRecipeURLInfo
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
package gq.kirmanak.mealient.extensions
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.toList
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class FlowExtensionsKtTest : BaseUnitTest() {
|
||||
|
||||
@Test
|
||||
fun `when flow has an update then valueUpdatesOnly sends updated value`() = runTest {
|
||||
val flow = flowOf(1, 2)
|
||||
assertThat(flow.valueUpdatesOnly().toList()).isEqualTo(listOf(2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when flow has repeated values then valueUpdatesOnly sends updated value`() = runTest {
|
||||
val flow = flowOf(1, 1, 1, 2)
|
||||
assertThat(flow.valueUpdatesOnly().toList()).isEqualTo(listOf(2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when flow has one value then valueUpdatesOnly is empty`() = runTest {
|
||||
val flow = flowOf(1)
|
||||
assertThat(flow.valueUpdatesOnly().toList()).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when flow has two updates then valueUpdatesOnly sends both`() = runTest {
|
||||
val flow = flowOf(1, 2, 1)
|
||||
assertThat(flow.valueUpdatesOnly().toList()).isEqualTo(listOf(2, 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when flow has three updates then valueUpdatesOnly sends all`() = runTest {
|
||||
val flow = flowOf(1, 2, 1, 3)
|
||||
assertThat(flow.valueUpdatesOnly().toList()).isEqualTo(listOf(2, 1, 3))
|
||||
}
|
||||
}
|
||||
@@ -1,146 +0,0 @@
|
||||
package gq.kirmanak.mealient.extensions
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_RECIPE_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MILK_RECIPE_INGREDIENT_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MILK_RECIPE_INGREDIENT_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MILK_RECIPE_INGREDIENT_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_CAKE_RECIPE_INSTRUCTION_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_INSTRUCTION
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_RECIPE_INSTRUCTION_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_RECIPE_INSTRUCTION_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_RECIPE_INSTRUCTION_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_REQUEST_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_CREATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_DRAFT
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_UPDATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.SUGAR_INGREDIENT
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_INFO_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_INFO_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_RESPONSE_V1
|
||||
import org.junit.Test
|
||||
|
||||
class ModelMappingsTest : BaseUnitTest() {
|
||||
|
||||
@Test
|
||||
fun `when toAddRecipeRequest then fills fields correctly`() {
|
||||
assertThat(PORRIDGE_RECIPE_DRAFT.toAddRecipeInfo()).isEqualTo(PORRIDGE_ADD_RECIPE_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when toDraft then fills fields correctly`() {
|
||||
assertThat(PORRIDGE_ADD_RECIPE_INFO.toDraft()).isEqualTo(PORRIDGE_RECIPE_DRAFT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when full recipe info to entity expect correct entity`() {
|
||||
assertThat(CAKE_FULL_RECIPE_INFO.toRecipeEntity()).isEqualTo(CAKE_RECIPE_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when ingredient info to entity expect correct entity`() {
|
||||
val actual = SUGAR_INGREDIENT.toRecipeIngredientEntity("1")
|
||||
assertThat(actual).isEqualTo(CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when instruction info to entity expect correct entity`() {
|
||||
val actual = MIX_INSTRUCTION.toRecipeInstructionEntity("1")
|
||||
assertThat(actual).isEqualTo(MIX_CAKE_RECIPE_INSTRUCTION_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when summary v0 to info expect correct info`() {
|
||||
val actual = PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0.toRecipeSummaryInfo()
|
||||
assertThat(actual).isEqualTo(RECIPE_SUMMARY_PORRIDGE_V0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when summary v1 to info expect correct info`() {
|
||||
val actual = PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1.toRecipeSummaryInfo()
|
||||
assertThat(actual).isEqualTo(RECIPE_SUMMARY_PORRIDGE_V1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when summary info to entity expect correct entity`() {
|
||||
val actual = RECIPE_SUMMARY_PORRIDGE_V0.toRecipeSummaryEntity(isFavorite = false)
|
||||
assertThat(actual).isEqualTo(PORRIDGE_RECIPE_SUMMARY_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when version response v0 to info expect correct info`() {
|
||||
assertThat(VERSION_RESPONSE_V0.toVersionInfo()).isEqualTo(VERSION_INFO_V0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when version response v1 to info expect correct info`() {
|
||||
assertThat(VERSION_RESPONSE_V1.toVersionInfo()).isEqualTo(VERSION_INFO_V1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe ingredient response v0 to info expect correct info`() {
|
||||
val actual = MILK_RECIPE_INGREDIENT_RESPONSE_V0.toRecipeIngredientInfo()
|
||||
assertThat(actual).isEqualTo(MILK_RECIPE_INGREDIENT_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe ingredient response v1 to info expect correct info`() {
|
||||
val actual = MILK_RECIPE_INGREDIENT_RESPONSE_V1.toRecipeIngredientInfo()
|
||||
assertThat(actual).isEqualTo(MILK_RECIPE_INGREDIENT_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe instruction response v0 to info expect correct info`() {
|
||||
val actual = MIX_RECIPE_INSTRUCTION_RESPONSE_V0.toRecipeInstructionInfo()
|
||||
assertThat(actual).isEqualTo(MIX_RECIPE_INSTRUCTION_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe instruction response v1 to info expect correct info`() {
|
||||
val actual = MIX_RECIPE_INSTRUCTION_RESPONSE_V1.toRecipeInstructionInfo()
|
||||
assertThat(actual).isEqualTo(MIX_RECIPE_INSTRUCTION_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe response v0 to info expect correct info`() {
|
||||
val actual = PORRIDGE_RECIPE_RESPONSE_V0.toFullRecipeInfo()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_FULL_RECIPE_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe response v1 to info expect correct info`() {
|
||||
val actual = PORRIDGE_RECIPE_RESPONSE_V1.toFullRecipeInfo()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_FULL_RECIPE_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when add recipe info to request v0 expect correct request`() {
|
||||
val actual = PORRIDGE_ADD_RECIPE_INFO.toV0Request()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_ADD_RECIPE_REQUEST_V0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when add recipe info to create request v1 expect correct request`() {
|
||||
val actual = PORRIDGE_ADD_RECIPE_INFO.toV1CreateRequest()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_CREATE_RECIPE_REQUEST_V1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when add recipe info to update request v1 expect correct request`() {
|
||||
val actual = PORRIDGE_ADD_RECIPE_INFO.toV1UpdateRequest()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_UPDATE_RECIPE_REQUEST_V1)
|
||||
}
|
||||
}
|
||||
@@ -1,440 +0,0 @@
|
||||
package gq.kirmanak.mealient.test
|
||||
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeInfo
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeIngredientInfo
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeInstructionInfo
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeSettingsInfo
|
||||
import gq.kirmanak.mealient.data.baseurl.VersionInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.FullRecipeInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeIngredientInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeInstructionInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeSettingsInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeSummaryInfo
|
||||
import gq.kirmanak.mealient.database.recipe.entity.FullRecipeEntity
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeEntity
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeIngredientEntity
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeInstructionEntity
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||
import gq.kirmanak.mealient.datasource.v0.models.AddRecipeIngredientV0
|
||||
import gq.kirmanak.mealient.datasource.v0.models.AddRecipeInstructionV0
|
||||
import gq.kirmanak.mealient.datasource.v0.models.AddRecipeRequestV0
|
||||
import gq.kirmanak.mealient.datasource.v0.models.AddRecipeSettingsV0
|
||||
import gq.kirmanak.mealient.datasource.v0.models.GetRecipeIngredientResponseV0
|
||||
import gq.kirmanak.mealient.datasource.v0.models.GetRecipeInstructionResponseV0
|
||||
import gq.kirmanak.mealient.datasource.v0.models.GetRecipeResponseV0
|
||||
import gq.kirmanak.mealient.datasource.v0.models.GetRecipeSummaryResponseV0
|
||||
import gq.kirmanak.mealient.datasource.v0.models.VersionResponseV0
|
||||
import gq.kirmanak.mealient.datasource.v1.models.AddRecipeIngredientV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.AddRecipeInstructionV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.AddRecipeSettingsV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.CreateRecipeRequestV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.GetRecipeIngredientResponseV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.GetRecipeInstructionResponseV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.GetRecipeResponseV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.GetRecipeSettingsResponseV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.GetRecipeSummaryResponseV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.UpdateRecipeRequestV1
|
||||
import gq.kirmanak.mealient.datasource.v1.models.VersionResponseV1
|
||||
import gq.kirmanak.mealient.datastore.recipe.AddRecipeDraft
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
|
||||
object RecipeImplTestData {
|
||||
val RECIPE_SUMMARY_CAKE = RecipeSummaryInfo(
|
||||
remoteId = "1",
|
||||
name = "Cake",
|
||||
slug = "cake",
|
||||
description = "A tasty cake",
|
||||
dateAdded = LocalDate.parse("2021-11-13"),
|
||||
dateUpdated = LocalDateTime.parse("2021-11-13T15:30:13"),
|
||||
imageId = "cake",
|
||||
)
|
||||
|
||||
val RECIPE_SUMMARY_PORRIDGE_V0 = RecipeSummaryInfo(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
slug = "porridge",
|
||||
description = "A tasty porridge",
|
||||
dateAdded = LocalDate.parse("2021-11-12"),
|
||||
dateUpdated = LocalDateTime.parse("2021-10-13T17:35:23"),
|
||||
imageId = "porridge",
|
||||
)
|
||||
|
||||
val RECIPE_SUMMARY_PORRIDGE_V1 = RecipeSummaryInfo(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
slug = "porridge",
|
||||
description = "A tasty porridge",
|
||||
dateAdded = LocalDate.parse("2021-11-12"),
|
||||
dateUpdated = LocalDateTime.parse("2021-10-13T17:35:23"),
|
||||
imageId = "2",
|
||||
)
|
||||
|
||||
val TEST_RECIPE_SUMMARIES = listOf(RECIPE_SUMMARY_CAKE, RECIPE_SUMMARY_PORRIDGE_V0)
|
||||
|
||||
val CAKE_RECIPE_SUMMARY_ENTITY = RecipeSummaryEntity(
|
||||
remoteId = "1",
|
||||
name = "Cake",
|
||||
slug = "cake",
|
||||
description = "A tasty cake",
|
||||
dateAdded = LocalDate.parse("2021-11-13"),
|
||||
dateUpdated = LocalDateTime.parse("2021-11-13T15:30:13"),
|
||||
imageId = "cake",
|
||||
isFavorite = false,
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_SUMMARY_ENTITY = RecipeSummaryEntity(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
slug = "porridge",
|
||||
description = "A tasty porridge",
|
||||
dateAdded = LocalDate.parse("2021-11-12"),
|
||||
dateUpdated = LocalDateTime.parse("2021-10-13T17:35:23"),
|
||||
imageId = "porridge",
|
||||
isFavorite = false,
|
||||
)
|
||||
|
||||
val TEST_RECIPE_SUMMARY_ENTITIES =
|
||||
listOf(CAKE_RECIPE_SUMMARY_ENTITY, PORRIDGE_RECIPE_SUMMARY_ENTITY)
|
||||
|
||||
val SUGAR_INGREDIENT = RecipeIngredientInfo(
|
||||
note = "2 oz of white sugar",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
val BREAD_INGREDIENT = RecipeIngredientInfo(
|
||||
note = "2 oz of white bread",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
private val MILK_INGREDIENT = RecipeIngredientInfo(
|
||||
note = "2 oz of white milk",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
val MIX_INSTRUCTION = RecipeInstructionInfo(
|
||||
text = "Mix the ingredients"
|
||||
)
|
||||
|
||||
private val BAKE_INSTRUCTION = RecipeInstructionInfo(
|
||||
text = "Bake the ingredients"
|
||||
)
|
||||
|
||||
private val BOIL_INSTRUCTION = RecipeInstructionInfo(
|
||||
text = "Boil the ingredients"
|
||||
)
|
||||
|
||||
val CAKE_FULL_RECIPE_INFO = FullRecipeInfo(
|
||||
remoteId = "1",
|
||||
name = "Cake",
|
||||
recipeYield = "4 servings",
|
||||
recipeIngredients = listOf(SUGAR_INGREDIENT, BREAD_INGREDIENT),
|
||||
recipeInstructions = listOf(MIX_INSTRUCTION, BAKE_INSTRUCTION),
|
||||
settings = RecipeSettingsInfo(disableAmounts = true)
|
||||
)
|
||||
|
||||
val PORRIDGE_FULL_RECIPE_INFO = FullRecipeInfo(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeIngredients = listOf(SUGAR_INGREDIENT, MILK_INGREDIENT),
|
||||
recipeInstructions = listOf(MIX_INSTRUCTION, BOIL_INSTRUCTION),
|
||||
settings = RecipeSettingsInfo(disableAmounts = true)
|
||||
)
|
||||
|
||||
val MIX_CAKE_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||
recipeId = "1",
|
||||
text = "Mix the ingredients",
|
||||
)
|
||||
|
||||
private val BAKE_CAKE_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||
recipeId = "1",
|
||||
text = "Bake the ingredients",
|
||||
)
|
||||
|
||||
val CAKE_RECIPE_ENTITY = RecipeEntity(
|
||||
remoteId = "1",
|
||||
recipeYield = "4 servings",
|
||||
disableAmounts = true,
|
||||
)
|
||||
|
||||
val CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||
recipeId = "1",
|
||||
note = "2 oz of white sugar",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
val CAKE_BREAD_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||
recipeId = "1",
|
||||
note = "2 oz of white bread",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
val FULL_CAKE_INFO_ENTITY = FullRecipeEntity(
|
||||
recipeEntity = CAKE_RECIPE_ENTITY,
|
||||
recipeSummaryEntity = CAKE_RECIPE_SUMMARY_ENTITY,
|
||||
recipeIngredients = listOf(
|
||||
CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY,
|
||||
CAKE_BREAD_RECIPE_INGREDIENT_ENTITY,
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
MIX_CAKE_RECIPE_INSTRUCTION_ENTITY,
|
||||
BAKE_CAKE_RECIPE_INSTRUCTION_ENTITY,
|
||||
),
|
||||
)
|
||||
|
||||
private val PORRIDGE_RECIPE_ENTITY_FULL = RecipeEntity(
|
||||
remoteId = "2",
|
||||
recipeYield = "3 servings",
|
||||
disableAmounts = true,
|
||||
)
|
||||
|
||||
private val PORRIDGE_MILK_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||
recipeId = "2",
|
||||
note = "2 oz of white milk",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
private val PORRIDGE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||
recipeId = "2",
|
||||
note = "2 oz of white sugar",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
private val PORRIDGE_MIX_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||
recipeId = "2",
|
||||
text = "Mix the ingredients"
|
||||
)
|
||||
|
||||
private val PORRIDGE_BOIL_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||
recipeId = "2",
|
||||
text = "Boil the ingredients"
|
||||
)
|
||||
|
||||
val FULL_PORRIDGE_INFO_ENTITY = FullRecipeEntity(
|
||||
recipeEntity = PORRIDGE_RECIPE_ENTITY_FULL,
|
||||
recipeSummaryEntity = PORRIDGE_RECIPE_SUMMARY_ENTITY,
|
||||
recipeIngredients = listOf(
|
||||
PORRIDGE_SUGAR_RECIPE_INGREDIENT_ENTITY,
|
||||
PORRIDGE_MILK_RECIPE_INGREDIENT_ENTITY,
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
PORRIDGE_MIX_RECIPE_INSTRUCTION_ENTITY,
|
||||
PORRIDGE_BOIL_RECIPE_INSTRUCTION_ENTITY,
|
||||
)
|
||||
)
|
||||
|
||||
val SUGAR_ADD_RECIPE_INGREDIENT_INFO = AddRecipeIngredientInfo("2 oz of white sugar")
|
||||
|
||||
val MILK_ADD_RECIPE_INGREDIENT_INFO = AddRecipeIngredientInfo("2 oz of white milk")
|
||||
|
||||
val BOIL_ADD_RECIPE_INSTRUCTION_INFO = AddRecipeInstructionInfo("Boil the ingredients")
|
||||
|
||||
val MIX_ADD_RECIPE_INSTRUCTION_INFO = AddRecipeInstructionInfo("Mix the ingredients")
|
||||
|
||||
val ADD_RECIPE_INFO_SETTINGS = AddRecipeSettingsInfo(disableComments = false, public = true)
|
||||
|
||||
val PORRIDGE_ADD_RECIPE_INFO = AddRecipeInfo(
|
||||
name = "Porridge",
|
||||
description = "A tasty porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeIngredient = listOf(
|
||||
MILK_ADD_RECIPE_INGREDIENT_INFO,
|
||||
SUGAR_ADD_RECIPE_INGREDIENT_INFO,
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
MIX_ADD_RECIPE_INSTRUCTION_INFO,
|
||||
BOIL_ADD_RECIPE_INSTRUCTION_INFO,
|
||||
),
|
||||
settings = ADD_RECIPE_INFO_SETTINGS,
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_DRAFT = AddRecipeDraft(
|
||||
recipeName = "Porridge",
|
||||
recipeDescription = "A tasty porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeInstructions = listOf("Mix the ingredients", "Boil the ingredients"),
|
||||
recipeIngredients = listOf("2 oz of white milk", "2 oz of white sugar"),
|
||||
isRecipePublic = true,
|
||||
areCommentsDisabled = false,
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0 = GetRecipeSummaryResponseV0(
|
||||
remoteId = 2,
|
||||
name = "Porridge",
|
||||
slug = "porridge",
|
||||
description = "A tasty porridge",
|
||||
dateAdded = LocalDate.parse("2021-11-12"),
|
||||
dateUpdated = LocalDateTime.parse("2021-10-13T17:35:23"),
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1 = GetRecipeSummaryResponseV1(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
slug = "porridge",
|
||||
description = "A tasty porridge",
|
||||
dateAdded = LocalDate.parse("2021-11-12"),
|
||||
dateUpdated = LocalDateTime.parse("2021-10-13T17:35:23"),
|
||||
)
|
||||
|
||||
val VERSION_RESPONSE_V0 = VersionResponseV0("v0.5.6")
|
||||
|
||||
val VERSION_INFO_V0 = VersionInfo("v0.5.6")
|
||||
|
||||
val VERSION_RESPONSE_V1 = VersionResponseV1("v1.0.0-beta05")
|
||||
|
||||
val VERSION_INFO_V1 = VersionInfo("v1.0.0-beta05")
|
||||
|
||||
val MILK_RECIPE_INGREDIENT_RESPONSE_V0 = GetRecipeIngredientResponseV0("2 oz of white milk")
|
||||
|
||||
val SUGAR_RECIPE_INGREDIENT_RESPONSE_V0 = GetRecipeIngredientResponseV0("2 oz of white sugar")
|
||||
|
||||
val MILK_RECIPE_INGREDIENT_RESPONSE_V1 = GetRecipeIngredientResponseV1(
|
||||
note = "2 oz of white milk",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
val SUGAR_RECIPE_INGREDIENT_RESPONSE_V1 = GetRecipeIngredientResponseV1(
|
||||
note = "2 oz of white sugar",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
val MILK_RECIPE_INGREDIENT_INFO = RecipeIngredientInfo(
|
||||
note = "2 oz of white milk",
|
||||
quantity = 1.0,
|
||||
unit = null,
|
||||
food = null,
|
||||
title = null,
|
||||
)
|
||||
|
||||
val MIX_RECIPE_INSTRUCTION_RESPONSE_V0 = GetRecipeInstructionResponseV0("Mix the ingredients")
|
||||
|
||||
val BOIL_RECIPE_INSTRUCTION_RESPONSE_V0 = GetRecipeInstructionResponseV0("Boil the ingredients")
|
||||
|
||||
val MIX_RECIPE_INSTRUCTION_RESPONSE_V1 = GetRecipeInstructionResponseV1("Mix the ingredients")
|
||||
|
||||
val BOIL_RECIPE_INSTRUCTION_RESPONSE_V1 = GetRecipeInstructionResponseV1("Boil the ingredients")
|
||||
|
||||
val MIX_RECIPE_INSTRUCTION_INFO = RecipeInstructionInfo("Mix the ingredients")
|
||||
|
||||
val PORRIDGE_RECIPE_RESPONSE_V0 = GetRecipeResponseV0(
|
||||
remoteId = 2,
|
||||
name = "Porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeIngredients = listOf(
|
||||
SUGAR_RECIPE_INGREDIENT_RESPONSE_V0,
|
||||
MILK_RECIPE_INGREDIENT_RESPONSE_V0,
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
MIX_RECIPE_INSTRUCTION_RESPONSE_V0,
|
||||
BOIL_RECIPE_INSTRUCTION_RESPONSE_V0
|
||||
),
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_RESPONSE_V1 = GetRecipeResponseV1(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeIngredients = listOf(
|
||||
SUGAR_RECIPE_INGREDIENT_RESPONSE_V1,
|
||||
MILK_RECIPE_INGREDIENT_RESPONSE_V1,
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
MIX_RECIPE_INSTRUCTION_RESPONSE_V1,
|
||||
BOIL_RECIPE_INSTRUCTION_RESPONSE_V1
|
||||
),
|
||||
settings = GetRecipeSettingsResponseV1(disableAmount = true),
|
||||
)
|
||||
|
||||
val MIX_ADD_RECIPE_INSTRUCTION_REQUEST_V0 = AddRecipeInstructionV0("Mix the ingredients")
|
||||
|
||||
val BOIL_ADD_RECIPE_INSTRUCTION_REQUEST_V0 = AddRecipeInstructionV0("Boil the ingredients")
|
||||
|
||||
val SUGAR_ADD_RECIPE_INGREDIENT_REQUEST_V0 = AddRecipeIngredientV0("2 oz of white sugar")
|
||||
|
||||
val MILK_ADD_RECIPE_INGREDIENT_REQUEST_V0 = AddRecipeIngredientV0("2 oz of white milk")
|
||||
|
||||
val ADD_RECIPE_REQUEST_SETTINGS_V0 = AddRecipeSettingsV0(disableComments = false, public = true)
|
||||
|
||||
val PORRIDGE_ADD_RECIPE_REQUEST_V0 = AddRecipeRequestV0(
|
||||
name = "Porridge",
|
||||
description = "A tasty porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeInstructions = listOf(
|
||||
MIX_ADD_RECIPE_INSTRUCTION_REQUEST_V0,
|
||||
BOIL_ADD_RECIPE_INSTRUCTION_REQUEST_V0,
|
||||
),
|
||||
recipeIngredient = listOf(
|
||||
MILK_ADD_RECIPE_INGREDIENT_REQUEST_V0,
|
||||
SUGAR_ADD_RECIPE_INGREDIENT_REQUEST_V0,
|
||||
),
|
||||
settings = ADD_RECIPE_REQUEST_SETTINGS_V0
|
||||
)
|
||||
|
||||
val MIX_ADD_RECIPE_INSTRUCTION_REQUEST_V1 = AddRecipeInstructionV1(
|
||||
id = "1",
|
||||
text = "Mix the ingredients",
|
||||
ingredientReferences = emptyList()
|
||||
)
|
||||
|
||||
val BOIL_ADD_RECIPE_INSTRUCTION_REQUEST_V1 = AddRecipeInstructionV1(
|
||||
id = "2",
|
||||
text = "Boil the ingredients",
|
||||
ingredientReferences = emptyList()
|
||||
)
|
||||
|
||||
val SUGAR_ADD_RECIPE_INGREDIENT_REQUEST_V1 = AddRecipeIngredientV1(
|
||||
id = "3",
|
||||
note = "2 oz of white sugar"
|
||||
)
|
||||
|
||||
val MILK_ADD_RECIPE_INGREDIENT_REQUEST_V1 = AddRecipeIngredientV1(
|
||||
id = "4",
|
||||
note = "2 oz of white milk"
|
||||
)
|
||||
|
||||
val ADD_RECIPE_REQUEST_SETTINGS_V1 = AddRecipeSettingsV1(disableComments = false, public = true)
|
||||
|
||||
val PORRIDGE_CREATE_RECIPE_REQUEST_V1 = CreateRecipeRequestV1(name = "Porridge")
|
||||
|
||||
val PORRIDGE_UPDATE_RECIPE_REQUEST_V1 = UpdateRecipeRequestV1(
|
||||
description = "A tasty porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeInstructions = listOf(
|
||||
MIX_ADD_RECIPE_INSTRUCTION_REQUEST_V1,
|
||||
BOIL_ADD_RECIPE_INSTRUCTION_REQUEST_V1,
|
||||
),
|
||||
recipeIngredient = listOf(
|
||||
MILK_ADD_RECIPE_INGREDIENT_REQUEST_V1,
|
||||
SUGAR_ADD_RECIPE_INGREDIENT_REQUEST_V1,
|
||||
),
|
||||
settings = ADD_RECIPE_REQUEST_SETTINGS_V1
|
||||
)
|
||||
}
|
||||
@@ -6,10 +6,13 @@ import gq.kirmanak.mealient.data.disclaimer.DisclaimerStorage
|
||||
import gq.kirmanak.mealient.data.recipes.RecipeRepo
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.ui.ActivityUiState
|
||||
import gq.kirmanak.mealient.ui.ActivityUiStateController
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@@ -28,6 +31,9 @@ class MainActivityViewModelTest : BaseUnitTest() {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var recipeRepo: RecipeRepo
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var activityUiStateController: ActivityUiStateController
|
||||
|
||||
private lateinit var subject: MainActivityViewModel
|
||||
|
||||
@Before
|
||||
@@ -36,12 +42,17 @@ class MainActivityViewModelTest : BaseUnitTest() {
|
||||
every { authRepo.isAuthorizedFlow } returns emptyFlow()
|
||||
coEvery { disclaimerStorage.isDisclaimerAccepted() } returns true
|
||||
coEvery { serverInfoRepo.getUrl() } returns TEST_BASE_URL
|
||||
every { activityUiStateController.getUiStateFlow() } returns MutableStateFlow(
|
||||
ActivityUiState()
|
||||
)
|
||||
coEvery { serverInfoRepo.versionUpdates() } returns emptyFlow()
|
||||
subject = MainActivityViewModel(
|
||||
authRepo = authRepo,
|
||||
logger = logger,
|
||||
disclaimerStorage = disclaimerStorage,
|
||||
serverInfoRepo = serverInfoRepo,
|
||||
recipeRepo = recipeRepo,
|
||||
activityUiStateController = activityUiStateController,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ package gq.kirmanak.mealient.ui.add
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeRepo
|
||||
import gq.kirmanak.mealient.datasource_test.PORRIDGE_ADD_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_INFO
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.impl.annotations.MockK
|
||||
|
||||
@@ -5,6 +5,7 @@ import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||
import gq.kirmanak.mealient.data.recipes.RecipeRepo
|
||||
import gq.kirmanak.mealient.datasource.NetworkError
|
||||
import gq.kirmanak.mealient.shopping_lists.repo.ShoppingListsRepo
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.ui.OperationUiState
|
||||
@@ -31,6 +32,9 @@ class BaseURLViewModelTest : BaseUnitTest() {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var recipeRepo: RecipeRepo
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var shoppingListsRepo: ShoppingListsRepo
|
||||
|
||||
lateinit var subject: BaseURLViewModel
|
||||
|
||||
@Before
|
||||
@@ -41,6 +45,7 @@ class BaseURLViewModelTest : BaseUnitTest() {
|
||||
authRepo = authRepo,
|
||||
recipeRepo = recipeRepo,
|
||||
logger = logger,
|
||||
shoppingListsRepo = shoppingListsRepo,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ import androidx.lifecycle.asFlow
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||
import gq.kirmanak.mealient.data.recipes.RecipeRepo
|
||||
import gq.kirmanak.mealient.database.CAKE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_RECIPE_SUMMARY_ENTITY
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
|
||||
@@ -3,8 +3,8 @@ package gq.kirmanak.mealient.ui.recipes.info
|
||||
import androidx.lifecycle.asFlow
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.recipes.RecipeRepo
|
||||
import gq.kirmanak.mealient.database.FULL_CAKE_INFO_ENTITY
|
||||
import gq.kirmanak.mealient.test.BaseUnitTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.FULL_CAKE_INFO_ENTITY
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
|
||||
Reference in New Issue
Block a user