From 04d368bb5820fc09f12bd9a98f0ed6e8156c3d88 Mon Sep 17 00:00:00 2001 From: Alex Vanyo Date: Tue, 12 Apr 2022 14:49:40 -0700 Subject: [PATCH] Allow saving authors and topics only Bug: 229012243 Change-Id: I4c8bc77002d39b8f97c925ea811d307e2cbe93db --- .../feature/foryou/ForYouScreen.kt | 2 +- .../feature/foryou/ForYouViewModel.kt | 28 ++- .../feature/foryou/ForYouViewModelTest.kt | 170 ++++++++++++++++++ 3 files changed, 184 insertions(+), 16 deletions(-) diff --git a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index ec1127764..71d713ed4 100644 --- a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -153,7 +153,7 @@ fun ForYouScreen( ) { Button( onClick = saveFollowedTopics, - enabled = uiState.canSaveSelectedTopics, + enabled = uiState.canSaveInterests, modifier = Modifier .padding(horizontal = 40.dp) .width(364.dp) diff --git a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt index 9023c0314..ba8882fe6 100644 --- a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt +++ b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt @@ -55,7 +55,7 @@ class ForYouViewModel @Inject constructor( authorsRepository.getFollowedAuthorIdsStream(), topicsRepository.getFollowedTopicIdsStream(), ) { followedAuthors, followedTopics -> - if (followedAuthors.isEmpty() || followedTopics.isEmpty()) { + if (followedAuthors.isEmpty() && followedTopics.isEmpty()) { FollowedInterestsState.None } else { FollowedInterestsState.FollowedInterests( @@ -204,20 +204,18 @@ class ForYouViewModel @Inject constructor( } fun saveFollowedInterests() { - if (inProgressTopicSelection.isNotEmpty()) { - viewModelScope.launch { - topicsRepository.setFollowedTopicIds(inProgressTopicSelection) - withMutableSnapshot { - inProgressTopicSelection = emptySet() - } - } + // Don't attempt to save anything if nothing is selected + if (inProgressTopicSelection.isEmpty() && inProgressAuthorSelection.isEmpty()) { + return } - if (inProgressAuthorSelection.isNotEmpty()) { - viewModelScope.launch { - authorsRepository.setFollowedAuthorIds(inProgressAuthorSelection) - withMutableSnapshot { - inProgressAuthorSelection = emptySet() - } + + viewModelScope.launch { + topicsRepository.setFollowedTopicIds(inProgressTopicSelection) + authorsRepository.setFollowedAuthorIds(inProgressAuthorSelection) + // Clear out the old selection, in case we return to onboarding + withMutableSnapshot { + inProgressTopicSelection = emptySet() + inProgressAuthorSelection = emptySet() } } } @@ -275,7 +273,7 @@ sealed interface ForYouFeedUiState { val authors: List, override val feed: List ) : PopulatedFeed { - val canSaveSelectedTopics: Boolean = + val canSaveInterests: Boolean = topics.any { it.isFollowed } || authors.any { it.isFollowed } } diff --git a/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index 05044b2d5..b7b18a089 100644 --- a/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -644,6 +644,82 @@ class ForYouViewModelTest { } } + @Test + fun topicSelectionUpdatesAfterSavingTopicsOnly() = runTest { + viewModel.uiState + .test { + awaitItem() + + topicsRepository.sendTopics(sampleTopics) + topicsRepository.setFollowedTopicIds(emptySet()) + authorsRepository.sendAuthors(sampleAuthors) + authorsRepository.setFollowedAuthorIds(emptySet()) + newsRepository.sendNewsResources(sampleNewsResources) + awaitItem() + + viewModel.updateTopicSelection(1, isChecked = true) + awaitItem() + + viewModel.saveFollowedInterests() + awaitItem() + + assertEquals( + ForYouFeedUiState.PopulatedFeed.FeedWithoutTopicSelection( + feed = listOf( + SaveableNewsResource( + newsResource = sampleNewsResources[1], + isSaved = false, + ), + SaveableNewsResource( + newsResource = sampleNewsResources[2], + isSaved = false, + ) + ) + ), + awaitItem() + ) + assertEquals(setOf(1), topicsRepository.getCurrentFollowedTopics()) + assertEquals(emptySet(), authorsRepository.getCurrentFollowedAuthors()) + cancel() + } + } + + @Test + fun topicSelectionUpdatesAfterSavingAuthorsOnly() = runTest { + viewModel.uiState + .test { + awaitItem() + + topicsRepository.sendTopics(sampleTopics) + topicsRepository.setFollowedTopicIds(emptySet()) + authorsRepository.sendAuthors(sampleAuthors) + authorsRepository.setFollowedAuthorIds(emptySet()) + newsRepository.sendNewsResources(sampleNewsResources) + awaitItem() + + viewModel.updateAuthorSelection(0, isChecked = true) + awaitItem() + + viewModel.saveFollowedInterests() + awaitItem() + + assertEquals( + ForYouFeedUiState.PopulatedFeed.FeedWithoutTopicSelection( + feed = listOf( + SaveableNewsResource( + newsResource = sampleNewsResources[0], + isSaved = false + ), + ) + ), + awaitItem() + ) + assertEquals(emptySet(), topicsRepository.getCurrentFollowedTopics()) + assertEquals(setOf(0), authorsRepository.getCurrentFollowedAuthors()) + cancel() + } + } + @Test fun topicSelectionUpdatesAfterSavingAuthorsAndTopics() = runTest { viewModel.uiState @@ -779,6 +855,100 @@ class ForYouViewModelTest { } } + @Test + fun authorSelectionIsResetAfterSavingAuthorsAndRemovingThem() = runTest { + viewModel.uiState + .test { + awaitItem() + topicsRepository.sendTopics(sampleTopics) + topicsRepository.setFollowedTopicIds(emptySet()) + authorsRepository.sendAuthors(sampleAuthors) + authorsRepository.setFollowedAuthorIds(emptySet()) + newsRepository.sendNewsResources(sampleNewsResources) + awaitItem() + + viewModel.updateAuthorSelection(1, isChecked = true) + viewModel.saveFollowedInterests() + awaitItem() + + authorsRepository.setFollowedAuthorIds(emptySet()) + assertEquals( + ForYouFeedUiState.PopulatedFeed.FeedWithInterestsSelection( + topics = listOf( + FollowableTopic( + topic = Topic( + id = 0, + name = "Headlines", + shortDescription = "", + longDescription = "long description", + url = "URL", + imageUrl = "image URL", + ), + isFollowed = false + ), + FollowableTopic( + topic = Topic( + id = 1, + name = "UI", + shortDescription = "", + longDescription = "long description", + url = "URL", + imageUrl = "image URL", + ), + isFollowed = false + ), + FollowableTopic( + topic = Topic( + id = 2, + name = "Tools", + shortDescription = "", + longDescription = "long description", + url = "URL", + imageUrl = "image URL", + ), + isFollowed = false + ) + ), + feed = emptyList(), + authors = listOf( + FollowableAuthor( + author = Author( + id = 0, + name = "Android Dev", + imageUrl = "", + twitter = "", + mediumPage = "" + ), + isFollowed = false + ), + FollowableAuthor( + author = Author( + id = 1, + name = "Android Dev 2", + imageUrl = "", + twitter = "", + mediumPage = "" + ), + isFollowed = false + ), + FollowableAuthor( + author = Author( + id = 2, + name = "Android Dev 3", + imageUrl = "", + twitter = "", + mediumPage = "" + ), + isFollowed = false + ) + ) + ), + awaitItem() + ) + cancel() + } + } + @Test fun newsResourceSelectionUpdatesAfterLoadingFollowedTopics() = runTest { viewModel.uiState