Remove recipe from local db when deleted
This commit is contained in:
@@ -20,5 +20,5 @@ interface RecipeRepo {
|
|||||||
|
|
||||||
suspend fun updateIsRecipeFavorite(recipeSlug: String, isFavorite: Boolean): Result<Unit>
|
suspend fun updateIsRecipeFavorite(recipeSlug: String, isFavorite: Boolean): Result<Unit>
|
||||||
|
|
||||||
suspend fun deleteRecipe(recipeSlug: String): Result<Unit>
|
suspend fun deleteRecipe(entity: RecipeSummaryEntity): Result<Unit>
|
||||||
}
|
}
|
||||||
@@ -19,4 +19,6 @@ interface RecipeStorage {
|
|||||||
suspend fun queryRecipeInfo(recipeId: String): FullRecipeEntity?
|
suspend fun queryRecipeInfo(recipeId: String): FullRecipeEntity?
|
||||||
|
|
||||||
suspend fun updateFavoriteRecipes(favorites: List<String>)
|
suspend fun updateFavoriteRecipes(favorites: List<String>)
|
||||||
|
|
||||||
|
suspend fun deleteRecipe(entity: RecipeSummaryEntity)
|
||||||
}
|
}
|
||||||
@@ -80,4 +80,9 @@ class RecipeStorageImpl @Inject constructor(
|
|||||||
recipeDao.setNonFavorite(favorites)
|
recipeDao.setNonFavorite(favorites)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun deleteRecipe(entity: RecipeSummaryEntity) {
|
||||||
|
logger.v { "deleteRecipeBySlug() called with: entity = $entity" }
|
||||||
|
recipeDao.deleteRecipe(entity)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -78,15 +78,20 @@ class RecipeRepoImpl @Inject constructor(
|
|||||||
): Result<Unit> = runCatchingExceptCancel {
|
): Result<Unit> = runCatchingExceptCancel {
|
||||||
logger.v { "updateIsRecipeFavorite() called with: recipeSlug = $recipeSlug, isFavorite = $isFavorite" }
|
logger.v { "updateIsRecipeFavorite() called with: recipeSlug = $recipeSlug, isFavorite = $isFavorite" }
|
||||||
dataSource.updateIsRecipeFavorite(recipeSlug, isFavorite)
|
dataSource.updateIsRecipeFavorite(recipeSlug, isFavorite)
|
||||||
mediator.onFavoritesChange()
|
val favorites = dataSource.getFavoriteRecipes()
|
||||||
|
storage.updateFavoriteRecipes(favorites)
|
||||||
|
pagingSourceFactory.invalidate()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
logger.e(it) { "Can't update recipe's is favorite status" }
|
logger.e(it) { "Can't update recipe's is favorite status" }
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteRecipe(recipeSlug: String): Result<Unit> = runCatchingExceptCancel {
|
override suspend fun deleteRecipe(
|
||||||
logger.v { "deleteRecipe() called with: recipeSlug = $recipeSlug" }
|
entity: RecipeSummaryEntity
|
||||||
dataSource.deleteRecipe(recipeSlug)
|
): Result<Unit> = runCatchingExceptCancel {
|
||||||
// TODO update local db
|
logger.v { "deleteRecipe() called with: entity = $entity" }
|
||||||
|
dataSource.deleteRecipe(entity.slug)
|
||||||
|
storage.deleteRecipe(entity)
|
||||||
|
pagingSourceFactory.invalidate()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
logger.e(it) { "Can't delete recipe" }
|
logger.e(it) { "Can't delete recipe" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,10 +83,4 @@ class RecipesRemoteMediator @Inject constructor(
|
|||||||
recipes.size
|
recipes.size
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun onFavoritesChange() {
|
|
||||||
logger.v { "onFavoritesChange() called" }
|
|
||||||
val favorites = network.getFavoriteRecipes()
|
|
||||||
storage.updateFavoriteRecipes(favorites)
|
|
||||||
pagingSourceFactory.invalidate()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ class RecipesListViewModel @Inject constructor(
|
|||||||
fun onDeleteConfirm(recipeSummaryEntity: RecipeSummaryEntity) {
|
fun onDeleteConfirm(recipeSummaryEntity: RecipeSummaryEntity) {
|
||||||
logger.v { "onDeleteConfirm() called with: recipeSummaryEntity = $recipeSummaryEntity" }
|
logger.v { "onDeleteConfirm() called with: recipeSummaryEntity = $recipeSummaryEntity" }
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val result = recipeRepo.deleteRecipe(recipeSummaryEntity.slug)
|
val result = recipeRepo.deleteRecipe(recipeSummaryEntity)
|
||||||
_deleteRecipeResult.emit(result)
|
_deleteRecipeResult.emit(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,19 +70,25 @@ class RecipeRepoTest : BaseUnitTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when remove favorite recipe expect correct sequence`() = runTest {
|
fun `when remove favorite recipe expect correct sequence`() = runTest {
|
||||||
|
coEvery { dataSource.getFavoriteRecipes() } returns listOf("porridge")
|
||||||
subject.updateIsRecipeFavorite("cake", false)
|
subject.updateIsRecipeFavorite("cake", false)
|
||||||
coVerify {
|
coVerify {
|
||||||
dataSource.updateIsRecipeFavorite(eq("cake"), eq(false))
|
dataSource.updateIsRecipeFavorite(eq("cake"), eq(false))
|
||||||
remoteMediator.onFavoritesChange()
|
dataSource.getFavoriteRecipes()
|
||||||
|
storage.updateFavoriteRecipes(eq(listOf("porridge")))
|
||||||
|
pagingSourceFactory.invalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when add favorite recipe expect correct sequence`() = runTest {
|
fun `when add favorite recipe expect correct sequence`() = runTest {
|
||||||
|
coEvery { dataSource.getFavoriteRecipes() } returns listOf("porridge", "cake")
|
||||||
subject.updateIsRecipeFavorite("porridge", true)
|
subject.updateIsRecipeFavorite("porridge", true)
|
||||||
coVerify {
|
coVerify {
|
||||||
dataSource.updateIsRecipeFavorite(eq("porridge"), eq(true))
|
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())
|
dataSource.updateIsRecipeFavorite(any(), any())
|
||||||
} throws Unauthorized(IOException())
|
} throws Unauthorized(IOException())
|
||||||
subject.updateIsRecipeFavorite("porridge", true)
|
subject.updateIsRecipeFavorite("porridge", true)
|
||||||
coVerify(inverse = true) { remoteMediator.onFavoritesChange() }
|
coVerify(inverse = true) { dataSource.getFavoriteRecipes() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -144,27 +144,6 @@ class RecipesRemoteMediatorTest : BaseUnitTest() {
|
|||||||
coVerify { storage.refreshAll(TEST_RECIPE_SUMMARY_ENTITIES) }
|
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
|
@Test
|
||||||
fun `when recipe update requested but favorite fails expect non-zero updates`() = runTest {
|
fun `when recipe update requested but favorite fails expect non-zero updates`() = runTest {
|
||||||
coEvery { dataSource.getFavoriteRecipes() } throws Unauthorized(IOException())
|
coEvery { dataSource.getFavoriteRecipes() } throws Unauthorized(IOException())
|
||||||
|
|||||||
@@ -46,4 +46,7 @@ interface RecipeDao {
|
|||||||
|
|
||||||
@Query("UPDATE recipe_summaries SET is_favorite = 0 WHERE slug NOT IN (:favorites)")
|
@Query("UPDATE recipe_summaries SET is_favorite = 0 WHERE slug NOT IN (:favorites)")
|
||||||
suspend fun setNonFavorite(favorites: List<String>)
|
suspend fun setNonFavorite(favorites: List<String>)
|
||||||
|
|
||||||
|
@Delete
|
||||||
|
suspend fun deleteRecipe(entity: RecipeSummaryEntity)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user