From 226097d096eb0dd91dc55d215a67ca46de4985dd Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Fri, 16 Dec 2022 20:24:40 +0100 Subject: [PATCH] Remove recipe from local db when deleted --- .../mealient/data/recipes/RecipeRepo.kt | 2 +- .../mealient/data/recipes/db/RecipeStorage.kt | 2 ++ .../data/recipes/db/RecipeStorageImpl.kt | 5 +++++ .../data/recipes/impl/RecipeRepoImpl.kt | 15 ++++++++----- .../recipes/impl/RecipesRemoteMediator.kt | 6 ------ .../ui/recipes/RecipesListViewModel.kt | 2 +- .../data/recipes/impl/RecipeRepoTest.kt | 12 ++++++++--- .../recipes/impl/RecipesRemoteMediatorTest.kt | 21 ------------------- .../mealient/database/recipe/RecipeDao.kt | 3 +++ 9 files changed, 31 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/RecipeRepo.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/RecipeRepo.kt index 77c2b07..4fd11dd 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/RecipeRepo.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/recipes/RecipeRepo.kt @@ -20,5 +20,5 @@ interface RecipeRepo { suspend fun updateIsRecipeFavorite(recipeSlug: String, isFavorite: Boolean): Result - suspend fun deleteRecipe(recipeSlug: String): Result + suspend fun deleteRecipe(entity: RecipeSummaryEntity): Result } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/db/RecipeStorage.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/db/RecipeStorage.kt index 171d8ab..e0f44e7 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/db/RecipeStorage.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/recipes/db/RecipeStorage.kt @@ -19,4 +19,6 @@ interface RecipeStorage { suspend fun queryRecipeInfo(recipeId: String): FullRecipeEntity? suspend fun updateFavoriteRecipes(favorites: List) + + suspend fun deleteRecipe(entity: RecipeSummaryEntity) } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/db/RecipeStorageImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/db/RecipeStorageImpl.kt index 70fa579..b59f234 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/db/RecipeStorageImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/recipes/db/RecipeStorageImpl.kt @@ -80,4 +80,9 @@ class RecipeStorageImpl @Inject constructor( recipeDao.setNonFavorite(favorites) } } + + override suspend fun deleteRecipe(entity: RecipeSummaryEntity) { + logger.v { "deleteRecipeBySlug() called with: entity = $entity" } + recipeDao.deleteRecipe(entity) + } } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoImpl.kt index e61f134..dadbc78 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipeRepoImpl.kt @@ -78,15 +78,20 @@ class RecipeRepoImpl @Inject constructor( ): Result = runCatchingExceptCancel { logger.v { "updateIsRecipeFavorite() called with: recipeSlug = $recipeSlug, isFavorite = $isFavorite" } dataSource.updateIsRecipeFavorite(recipeSlug, isFavorite) - mediator.onFavoritesChange() + val favorites = dataSource.getFavoriteRecipes() + storage.updateFavoriteRecipes(favorites) + pagingSourceFactory.invalidate() }.onFailure { logger.e(it) { "Can't update recipe's is favorite status" } } - override suspend fun deleteRecipe(recipeSlug: String): Result = runCatchingExceptCancel { - logger.v { "deleteRecipe() called with: recipeSlug = $recipeSlug" } - dataSource.deleteRecipe(recipeSlug) - // TODO update local db + override suspend fun deleteRecipe( + entity: RecipeSummaryEntity + ): Result = runCatchingExceptCancel { + logger.v { "deleteRecipe() called with: entity = $entity" } + dataSource.deleteRecipe(entity.slug) + storage.deleteRecipe(entity) + pagingSourceFactory.invalidate() }.onFailure { logger.e(it) { "Can't delete recipe" } } diff --git a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediator.kt b/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediator.kt index 16f206f..1cd8d56 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediator.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/recipes/impl/RecipesRemoteMediator.kt @@ -83,10 +83,4 @@ class RecipesRemoteMediator @Inject constructor( recipes.size } - suspend fun onFavoritesChange() { - logger.v { "onFavoritesChange() called" } - val favorites = network.getFavoriteRecipes() - storage.updateFavoriteRecipes(favorites) - pagingSourceFactory.invalidate() - } } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/RecipesListViewModel.kt b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/RecipesListViewModel.kt index 028a27c..7efeaad 100644 --- a/app/src/main/java/gq/kirmanak/mealient/ui/recipes/RecipesListViewModel.kt +++ b/app/src/main/java/gq/kirmanak/mealient/ui/recipes/RecipesListViewModel.kt @@ -71,7 +71,7 @@ class RecipesListViewModel @Inject constructor( fun onDeleteConfirm(recipeSummaryEntity: RecipeSummaryEntity) { logger.v { "onDeleteConfirm() called with: recipeSummaryEntity = $recipeSummaryEntity" } viewModelScope.launch { - val result = recipeRepo.deleteRecipe(recipeSummaryEntity.slug) + val result = recipeRepo.deleteRecipe(recipeSummaryEntity) _deleteRecipeResult.emit(result) } } 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 fe98583..7c04429 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 @@ -70,19 +70,25 @@ class RecipeRepoTest : BaseUnitTest() { @Test fun `when remove favorite recipe expect correct sequence`() = runTest { + coEvery { dataSource.getFavoriteRecipes() } returns listOf("porridge") subject.updateIsRecipeFavorite("cake", false) coVerify { dataSource.updateIsRecipeFavorite(eq("cake"), eq(false)) - remoteMediator.onFavoritesChange() + dataSource.getFavoriteRecipes() + storage.updateFavoriteRecipes(eq(listOf("porridge"))) + pagingSourceFactory.invalidate() } } @Test fun `when add favorite recipe expect correct sequence`() = runTest { + coEvery { dataSource.getFavoriteRecipes() } returns listOf("porridge", "cake") subject.updateIsRecipeFavorite("porridge", true) coVerify { dataSource.updateIsRecipeFavorite(eq("porridge"), eq(true)) - remoteMediator.onFavoritesChange() + dataSource.getFavoriteRecipes() + storage.updateFavoriteRecipes(eq(listOf("porridge", "cake"))) + pagingSourceFactory.invalidate() } } @@ -92,7 +98,7 @@ class RecipeRepoTest : BaseUnitTest() { dataSource.updateIsRecipeFavorite(any(), any()) } throws Unauthorized(IOException()) subject.updateIsRecipeFavorite("porridge", true) - coVerify(inverse = true) { remoteMediator.onFavoritesChange() } + coVerify(inverse = true) { dataSource.getFavoriteRecipes() } } @Test 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 59a742c..a85475f 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 @@ -144,27 +144,6 @@ 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()) diff --git a/database/src/main/kotlin/gq/kirmanak/mealient/database/recipe/RecipeDao.kt b/database/src/main/kotlin/gq/kirmanak/mealient/database/recipe/RecipeDao.kt index 29d74e8..e7ef953 100644 --- a/database/src/main/kotlin/gq/kirmanak/mealient/database/recipe/RecipeDao.kt +++ b/database/src/main/kotlin/gq/kirmanak/mealient/database/recipe/RecipeDao.kt @@ -46,4 +46,7 @@ interface RecipeDao { @Query("UPDATE recipe_summaries SET is_favorite = 0 WHERE slug NOT IN (:favorites)") suspend fun setNonFavorite(favorites: List) + + @Delete + suspend fun deleteRecipe(entity: RecipeSummaryEntity) } \ No newline at end of file