From 16421d6a2a52c68ff6fffe1d886af4350684f40a Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Fri, 16 Dec 2022 17:41:01 +0100 Subject: [PATCH] Add tests for some affected components --- .../network/MealieDataSourceWrapperTest.kt | 79 +++++++++++++++++-- .../data/recipes/impl/RecipeRepoTest.kt | 36 +++++++++ .../recipes/impl/RecipesRemoteMediatorTest.kt | 29 +++++++ .../mealient/test/AuthImplTestData.kt | 6 ++ 4 files changed, 145 insertions(+), 5 deletions(-) diff --git a/app/src/test/java/gq/kirmanak/mealient/data/network/MealieDataSourceWrapperTest.kt b/app/src/test/java/gq/kirmanak/mealient/data/network/MealieDataSourceWrapperTest.kt index 418933f..d1de8af 100644 --- a/app/src/test/java/gq/kirmanak/mealient/data/network/MealieDataSourceWrapperTest.kt +++ b/app/src/test/java/gq/kirmanak/mealient/data/network/MealieDataSourceWrapperTest.kt @@ -5,9 +5,12 @@ 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.test.AuthImplTestData.FAVORITE_RECIPES_LIST import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION_V0 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 @@ -36,10 +39,10 @@ class MealieDataSourceWrapperTest : BaseUnitTest() { @MockK(relaxUnitFun = true) lateinit var authRepo: AuthRepo - @MockK + @MockK(relaxUnitFun = true) lateinit var v0Source: MealieDataSourceV0 - @MockK + @MockK(relaxUnitFun = true) lateinit var v1Source: MealieDataSourceV1 lateinit var subject: MealieDataSourceWrapper @@ -48,14 +51,14 @@ class MealieDataSourceWrapperTest : BaseUnitTest() { override fun setUp() { super.setUp() subject = MealieDataSourceWrapper(serverInfoRepo, v0Source, v1Source) + coEvery { v0Source.requestUserInfo() } returns USER_INFO_V0 + coEvery { v1Source.requestUserInfo() } returns USER_INFO_V1 } @Test fun `when server version v1 expect requestRecipeInfo to call v1`() = runTest { val slug = "porridge" - coEvery { - v1Source.requestRecipeInfo(eq(slug)) - } returns PORRIDGE_RECIPE_RESPONSE_V1 + coEvery { v1Source.requestRecipeInfo(eq(slug)) } returns PORRIDGE_RECIPE_RESPONSE_V1 coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V1 coEvery { authRepo.getAuthHeader() } returns TEST_AUTH_HEADER @@ -157,4 +160,70 @@ class MealieDataSourceWrapperTest : BaseUnitTest() { assertThat(actual).isEqualTo(slug) } + + @Test + fun `when remove favorite recipe info with v0 expect correct sequence`() = runTest { + coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0 + subject.updateIsRecipeFavorite(recipeSlug = "cake", isFavorite = false) + coVerify { + v0Source.requestUserInfo() + v0Source.removeFavoriteRecipe(eq(3), eq("cake")) + } + } + + @Test + fun `when remove favorite recipe info with v1 expect correct sequence`() = runTest { + coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V1 + subject.updateIsRecipeFavorite(recipeSlug = "cake", isFavorite = false) + coVerify { + v1Source.requestUserInfo() + v1Source.removeFavoriteRecipe(eq("userId"), eq("cake")) + } + } + + @Test + fun `when add favorite recipe info with v0 expect correct sequence`() = runTest { + coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0 + subject.updateIsRecipeFavorite(recipeSlug = "cake", isFavorite = true) + coVerify { + v0Source.requestUserInfo() + v0Source.addFavoriteRecipe(eq(3), eq("cake")) + } + } + + @Test + fun `when add favorite recipe info with v1 expect correct sequence`() = runTest { + coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V1 + subject.updateIsRecipeFavorite(recipeSlug = "cake", isFavorite = true) + coVerify { + v1Source.requestUserInfo() + v1Source.addFavoriteRecipe(eq("userId"), eq("cake")) + } + } + + @Test + fun `when get favorite recipes with v1 expect correct call`() = runTest { + coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V1 + subject.getFavoriteRecipes() + coVerify { v1Source.requestUserInfo() } + } + + @Test + fun `when get favorite recipes with v0 expect correct call`() = runTest { + coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0 + subject.getFavoriteRecipes() + coVerify { v0Source.requestUserInfo() } + } + + @Test + fun `when get favorite recipes with v1 expect correct result`() = runTest { + coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V1 + assertThat(subject.getFavoriteRecipes()).isEqualTo(FAVORITE_RECIPES_LIST) + } + + @Test + fun `when get favorite recipes with v0 expect correct result`() = runTest { + coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0 + assertThat(subject.getFavoriteRecipes()).isEqualTo(FAVORITE_RECIPES_LIST) + } } \ No newline at end of file diff --git a/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoTest.kt b/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoTest.kt index 20c4568..ee03000 100644 --- a/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoTest.kt +++ b/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoTest.kt @@ -1,9 +1,11 @@ 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.datasource.NetworkError.Unauthorized import gq.kirmanak.mealient.test.BaseUnitTest import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_FULL_RECIPE_INFO import gq.kirmanak.mealient.test.RecipeImplTestData.FULL_CAKE_INFO_ENTITY @@ -15,6 +17,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test +import java.io.IOException @OptIn(ExperimentalCoroutinesApi::class) class RecipeRepoTest : BaseUnitTest() { @@ -64,4 +67,37 @@ class RecipeRepoTest : BaseUnitTest() { subject.updateNameQuery("query") verify { pagingSourceFactory.setQuery("query") } } + + @Test + fun `when remove favorite recipe expect correct sequence`() = runTest { + subject.updateIsRecipeFavorite("cake", false) + coVerify { + dataSource.updateIsRecipeFavorite(eq("cake"), eq(false)) + remoteMediator.onFavoritesChange() + } + } + + @Test + fun `when add favorite recipe expect correct sequence`() = runTest { + subject.updateIsRecipeFavorite("porridge", true) + coVerify { + dataSource.updateIsRecipeFavorite(eq("porridge"), eq(true)) + remoteMediator.onFavoritesChange() + } + } + + @Test + fun `when add favorite recipe fails expect no mediator call`() = runTest { + coEvery { + dataSource.updateIsRecipeFavorite(any(), any()) + } throws Unauthorized(IOException()) + subject.updateIsRecipeFavorite("porridge", true) + coVerify(inverse = true) { remoteMediator.onFavoritesChange() } + } + + @Test + fun `when refresh recipes expect correct parameters`() = runTest { + subject.refreshRecipes() + coVerify { remoteMediator.updateRecipes(eq(0), eq(150), eq(LoadType.REFRESH)) } + } } \ No newline at end of file diff --git a/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediatorTest.kt b/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediatorTest.kt index 5b13581..59a742c 100644 --- a/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediatorTest.kt +++ b/app/src/test/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediatorTest.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Test +import java.io.IOException @ExperimentalCoroutinesApi @OptIn(ExperimentalPagingApi::class) @@ -143,6 +144,34 @@ class RecipesRemoteMediatorTest : BaseUnitTest() { coVerify { storage.refreshAll(TEST_RECIPE_SUMMARY_ENTITIES) } } + @Test + fun `when favorites change expect network call`() = runTest { + coEvery { dataSource.getFavoriteRecipes() } returns listOf("cake", "porridge") + subject.onFavoritesChange() + coVerify { dataSource.getFavoriteRecipes() } + } + + @Test + fun `when favorites change expect storage update`() = runTest { + coEvery { dataSource.getFavoriteRecipes() } returns listOf("cake", "porridge") + subject.onFavoritesChange() + coVerify { storage.updateFavoriteRecipes(eq(listOf("cake", "porridge"))) } + } + + @Test + fun `when favorites change expect factory invalidation`() = runTest { + coEvery { dataSource.getFavoriteRecipes() } returns listOf("cake", "porridge") + subject.onFavoritesChange() + coVerify { pagingSourceFactory.invalidate() } + } + + @Test + fun `when recipe update requested but favorite fails expect non-zero updates`() = runTest { + coEvery { dataSource.getFavoriteRecipes() } throws Unauthorized(IOException()) + coEvery { dataSource.requestRecipes(eq(0), eq(6)) } returns TEST_RECIPE_SUMMARIES + assertThat(subject.updateRecipes(0, 6, APPEND)).isEqualTo(2) + } + private fun pagingState( pages: List> = emptyList(), anchorPosition: Int? = null diff --git a/app/src/test/java/gq/kirmanak/mealient/test/AuthImplTestData.kt b/app/src/test/java/gq/kirmanak/mealient/test/AuthImplTestData.kt index a613a84..cc8bb47 100644 --- a/app/src/test/java/gq/kirmanak/mealient/test/AuthImplTestData.kt +++ b/app/src/test/java/gq/kirmanak/mealient/test/AuthImplTestData.kt @@ -1,6 +1,8 @@ package gq.kirmanak.mealient.test import gq.kirmanak.mealient.data.baseurl.ServerVersion +import gq.kirmanak.mealient.datasource.v0.models.GetUserInfoResponseV0 +import gq.kirmanak.mealient.datasource.v1.models.GetUserInfoResponseV1 object AuthImplTestData { const val TEST_USERNAME = "TEST_USERNAME" @@ -13,4 +15,8 @@ object AuthImplTestData { const val TEST_VERSION = "v0.5.6" val TEST_SERVER_VERSION_V0 = ServerVersion.V0 val TEST_SERVER_VERSION_V1 = ServerVersion.V1 + + val FAVORITE_RECIPES_LIST = listOf("cake", "porridge") + val USER_INFO_V1 = GetUserInfoResponseV1("userId", FAVORITE_RECIPES_LIST) + val USER_INFO_V0 = GetUserInfoResponseV0(3, FAVORITE_RECIPES_LIST) } \ No newline at end of file