Repository: wordpress-mobile/WordPress-Android (language: kotlin)

Issue:
Issues with Reader Discover not matching iOS & Web
There are a couple of issues preventing the Android Reader's "Discover" view from matching the iOS and web readers.

* When there are no followed tags we should request the `dailyprompt` and `wordpress` tags.
* If you're not following any tags and try to view Discover, you see this:

![Image](https://github.com/user-attachments/assets/cdee9629-1104-4353-be6d-0e1c9bcfe722)




Discussion hints:
Thanks for reporting! 👍 <!-- generated_by_dangermattic -->


Pull request: Reader Discover not matching iOS & Web
Fixes #21706

The "Discover" stream in the Android reader shows different content than the iOS and web readers. There were two primary reasons for this:

* The Discover stream showed an empty view when the user wasn't following any tags
* We should request the `dailyprompt` and `wordpress` tags to match the other readers when there are no followed tags

To test, I recommend removing all tags in the web reader, then verifying the Android reader shows roughly the same content. Next, add some tags and verify the readers show similar content.



Test command: ./gradlew :WordPress:testWordpressVanillaDebugUnitTest --tests "org.wordpress.android.ui.reader.discover.ReaderDiscoverViewModelTest"

Fix patch:
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/discover/ReaderDiscoverViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/reader/discover/ReaderDiscoverViewModel.kt
index 4fb2ccc2417b..559cce8a0a8a 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/discover/ReaderDiscoverViewModel.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/discover/ReaderDiscoverViewModel.kt
@@ -16,7 +16,6 @@ import org.wordpress.android.models.discover.ReaderDiscoverCard.ReaderRecommende
 import org.wordpress.android.models.discover.ReaderDiscoverCards
 import org.wordpress.android.modules.IO_THREAD
 import org.wordpress.android.modules.UI_THREAD
-import org.wordpress.android.ui.bloggingprompts.BloggingPromptsPostTagProvider.Companion.BLOGGING_PROMPT_TAG
 import org.wordpress.android.ui.pages.SnackbarMessageHolder
 import org.wordpress.android.ui.reader.ReaderTypes.ReaderPostListType.TAG_FOLLOWED
 import org.wordpress.android.ui.reader.discover.ReaderCardUiState.ReaderPostUiState
@@ -32,7 +31,6 @@ import org.wordpress.android.ui.reader.repository.ReaderDiscoverCommunication.Er
 import org.wordpress.android.ui.reader.repository.ReaderDiscoverCommunication.Started
 import org.wordpress.android.ui.reader.repository.ReaderDiscoverCommunication.Success
 import org.wordpress.android.ui.reader.repository.ReaderDiscoverDataProvider
-import org.wordpress.android.ui.reader.repository.usecases.tags.GetFollowedTagsUseCase
 import org.wordpress.android.ui.reader.services.discover.ReaderDiscoverLogic.DiscoverTasks.REQUEST_FIRST_PAGE
 import org.wordpress.android.ui.reader.services.discover.ReaderDiscoverLogic.DiscoverTasks.REQUEST_MORE
 import org.wordpress.android.ui.reader.tracker.ReaderTracker
@@ -59,7 +57,6 @@ class ReaderDiscoverViewModel @Inject constructor(
     private val readerUtilsWrapper: ReaderUtilsWrapper,
     private val readerTracker: ReaderTracker,
     displayUtilsWrapper: DisplayUtilsWrapper,
-    private val getFollowedTagsUseCase: GetFollowedTagsUseCase,
     private val readerAnnouncementHelper: ReaderAnnouncementHelper,
     @Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher,
     @Named(IO_THREAD) private val ioDispatcher: CoroutineDispatcher
@@ -148,40 +145,30 @@ class ReaderDiscoverViewModel @Inject constructor(
         // listen to changes to the discover feed
         _uiState.addSource(readerDiscoverDataProvider.discoverFeed) { posts ->
             launch {
-                val userTags = getFollowedTagsUseCase.get()
-
-                // since new users have the dailyprompt tag followed by default, we need to ignore them when
-                // checking if the user has any tags followed, so we show the onboarding state (ShowNoFollowedTags)
-                if (userTags.filterNot { it.tagSlug == BLOGGING_PROMPT_TAG }.isEmpty()) {
-                    _uiState.value = DiscoverUiState.EmptyUiState.ShowNoFollowedTagsUiState {
-                        parentViewModel.onShowReaderInterests()
-                    }
-                } else {
-                    if (posts != null && posts.cards.isNotEmpty()) {
-                        val announcement = if (readerAnnouncementHelper.hasReaderAnnouncement()) {
-                            listOf(
-                                ReaderCardUiState.ReaderAnnouncementCardUiState(
-                                    readerAnnouncementHelper.getReaderAnnouncementItems(),
-                                    ::dismissAnnouncementCard
-                                )
+                if (posts != null && posts.cards.isNotEmpty()) {
+                    val announcement = if (readerAnnouncementHelper.hasReaderAnnouncement()) {
+                        listOf(
+                            ReaderCardUiState.ReaderAnnouncementCardUiState(
+                                readerAnnouncementHelper.getReaderAnnouncementItems(),
+                                ::dismissAnnouncementCard
                             )
-                        } else {
-                            emptyList()
-                        }
-
-                        _uiState.value = DiscoverUiState.ContentUiState(
-                            announcement + convertCardsToUiStates(posts),
-                            reloadProgressVisibility = false,
-                            loadMoreProgressVisibility = false,
                         )
-                        if (swipeToRefreshTriggered) {
-                            _scrollToTopEvent.postValue(Event(Unit))
-                            swipeToRefreshTriggered = false
-                        }
                     } else {
-                        _uiState.value = DiscoverUiState.EmptyUiState.ShowNoPostsUiState {
-                            _navigationEvents.value = Event(ShowReaderSubs)
-                        }
+                        emptyList()
+                    }
+
+                    _uiState.value = DiscoverUiState.ContentUiState(
+                        announcement + convertCardsToUiStates(posts),
+                        reloadProgressVisibility = false,
+                        loadMoreProgressVisibility = false,
+                    )
+                    if (swipeToRefreshTriggered) {
+                        _scrollToTopEvent.postValue(Event(Unit))
+                        swipeToRefreshTriggered = false
+                    }
+                } else {
+                    _uiState.value = DiscoverUiState.EmptyUiState.ShowNoPostsUiState {
+                        _navigationEvents.value = Event(ShowReaderSubs)
                     }
                 }
             }
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/services/discover/ReaderDiscoverLogic.kt b/WordPress/src/main/java/org/wordpress/android/ui/reader/services/discover/ReaderDiscoverLogic.kt
index 8c187636daf0..d44aa4f0d2e9 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/reader/services/discover/ReaderDiscoverLogic.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/services/discover/ReaderDiscoverLogic.kt
@@ -21,6 +21,7 @@ import org.wordpress.android.models.discover.ReaderDiscoverCard
 import org.wordpress.android.models.discover.ReaderDiscoverCard.InterestsYouMayLikeCard
 import org.wordpress.android.models.discover.ReaderDiscoverCard.ReaderPostCard
 import org.wordpress.android.models.discover.ReaderDiscoverCard.ReaderRecommendedBlogsCard
+import org.wordpress.android.ui.bloggingprompts.BloggingPromptsPostTagProvider.Companion.BLOGGING_PROMPT_TAG
 import org.wordpress.android.ui.prefs.AppPrefsWrapper
 import org.wordpress.android.ui.reader.ReaderConstants.JSON_CARDS
 import org.wordpress.android.ui.reader.ReaderConstants.JSON_CARD_DATA
@@ -86,9 +87,18 @@ class ReaderDiscoverLogic @Inject constructor(
     private fun requestDataForDiscover(taskType: DiscoverTasks, resultListener: UpdateResultListener) {
         coroutineScope?.launch {
             val params = HashMap<String, String>()
-            params["tags"] = getFollowedTagsUseCase.get().joinToString { it.tagSlug }
             params["tag_recs_per_card"] = RECOMMENDED_TAGS_COUNT
 
+            // default to requesting the dailyprompt and wordpress tags if the user isn't following any tags,
+            // otherwise pass the user's followed tags. note we filter out the dailyprompt tag when doing
+            // our empty comparison since new users have that tag followed by default.
+            val userTags = getFollowedTagsUseCase.get()
+            if (userTags.filterNot { it.tagSlug == BLOGGING_PROMPT_TAG }.isEmpty()) {
+                params["tags"] = "$BLOGGING_PROMPT_TAG,wordpress"
+            } else {
+                params["tags"] = userTags.joinToString(",") { it.tagSlug }
+            }
+
             when (taskType) {
                 REQUEST_FIRST_PAGE -> {
                     appPrefsWrapper.readerCardsPageHandle = null


Test patch:
diff --git a/WordPress/src/test/java/org/wordpress/android/ui/reader/discover/ReaderDiscoverViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/reader/discover/ReaderDiscoverViewModelTest.kt
index c1fc2ec37b46..176629483ccc 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/reader/discover/ReaderDiscoverViewModelTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/reader/discover/ReaderDiscoverViewModelTest.kt
@@ -23,7 +23,6 @@ import org.wordpress.android.models.ReaderBlog
 import org.wordpress.android.models.ReaderPost
 import org.wordpress.android.models.ReaderTag
 import org.wordpress.android.models.ReaderTagList
-import org.wordpress.android.models.ReaderTagType
 import org.wordpress.android.models.discover.ReaderDiscoverCard.InterestsYouMayLikeCard
 import org.wordpress.android.models.discover.ReaderDiscoverCard.ReaderPostCard
 import org.wordpress.android.models.discover.ReaderDiscoverCard.ReaderRecommendedBlogsCard
@@ -37,7 +36,6 @@ import org.wordpress.android.ui.reader.discover.ReaderCardUiState.ReaderRecommen
 import org.wordpress.android.ui.reader.discover.ReaderDiscoverViewModel.DiscoverUiState
 import org.wordpress.android.ui.reader.discover.ReaderDiscoverViewModel.DiscoverUiState.ContentUiState
 import org.wordpress.android.ui.reader.discover.ReaderDiscoverViewModel.DiscoverUiState.EmptyUiState.RequestFailedUiState
-import org.wordpress.android.ui.reader.discover.ReaderDiscoverViewModel.DiscoverUiState.EmptyUiState.ShowNoFollowedTagsUiState
 import org.wordpress.android.ui.reader.discover.ReaderDiscoverViewModel.DiscoverUiState.EmptyUiState.ShowNoPostsUiState
 import org.wordpress.android.ui.reader.discover.ReaderDiscoverViewModel.DiscoverUiState.LoadingUiState
 import org.wordpress.android.ui.reader.discover.ReaderNavigationEvents.OpenEditorForReblog
@@ -54,7 +52,6 @@ import org.wordpress.android.ui.reader.repository.ReaderDiscoverCommunication
 import org.wordpress.android.ui.reader.repository.ReaderDiscoverCommunication.Error.NetworkUnavailable
 import org.wordpress.android.ui.reader.repository.ReaderDiscoverCommunication.Started
 import org.wordpress.android.ui.reader.repository.ReaderDiscoverDataProvider
-import org.wordpress.android.ui.reader.repository.usecases.tags.GetFollowedTagsUseCase
 import org.wordpress.android.ui.reader.services.discover.ReaderDiscoverLogic.DiscoverTasks.REQUEST_FIRST_PAGE
 import org.wordpress.android.ui.reader.services.discover.ReaderDiscoverLogic.DiscoverTasks.REQUEST_MORE
 import org.wordpress.android.ui.reader.tracker.ReaderTracker
@@ -105,9 +102,6 @@ class ReaderDiscoverViewModelTest : BaseUnitTest() {
     @Mock
     private lateinit var readerUtilsWrapper: ReaderUtilsWrapper
 
-    @Mock
-    private lateinit var getFollowedTagsUseCase: GetFollowedTagsUseCase
-
     @Mock
     private lateinit var readerTracker: ReaderTracker
 
@@ -141,7 +135,6 @@ class ReaderDiscoverViewModelTest : BaseUnitTest() {
             readerUtilsWrapper,
             readerTracker,
             displayUtilsWrapper,
-            getFollowedTagsUseCase,
             mReaderAnnouncementHelper,
             testDispatcher(),
             testDispatcher()
@@ -205,7 +198,6 @@ class ReaderDiscoverViewModelTest : BaseUnitTest() {
         }
         whenever(reblogUseCase.onReblogSiteSelected(anyInt(), anyOrNull())).thenReturn(mock())
         whenever(reblogUseCase.convertReblogStateToNavigationEvent(anyOrNull())).thenReturn(mock<OpenEditorForReblog>())
-        whenever(getFollowedTagsUseCase.get()).thenReturn(ReaderTagList().apply { add(mock()) })
     }
 
     @Test
@@ -230,41 +222,6 @@ class ReaderDiscoverViewModelTest : BaseUnitTest() {
         assertThat(uiStates[1]).isInstanceOf(ContentUiState::class.java)
     }
 
-    @Test
-    fun `ShowFollowInterestsEmptyUiState is shown when the user does NOT follow any tags`() = test {
-        // Arrange
-        whenever(getFollowedTagsUseCase.get()).thenReturn(ReaderTagList())
-        val uiStates = init().uiStates
-        // Act
-        viewModel.start(parentViewModel)
-        // Assert
-        assertThat(uiStates.size).isEqualTo(2)
-        assertThat(uiStates[1]).isInstanceOf(ShowNoFollowedTagsUiState::class.java)
-    }
-
-    @Test
-    fun `ShowFollowInterestsEmptyUiState is shown when the user follows only the daily prompt tag`() = test {
-        // Arrange
-        val tagsWithDailyPrompt = ReaderTagList().apply {
-            add(
-                ReaderTag(
-                    "dailyprompt",
-                    "dailyprompt",
-                    "dailyprompt",
-                    "https://public-api.wordpress.com/rest/v1.2/read/tags/dailyprompt/posts",
-                    ReaderTagType.DEFAULT
-                )
-            )
-        }
-        whenever(getFollowedTagsUseCase.get()).thenReturn(tagsWithDailyPrompt)
-        val uiStates = init().uiStates
-        // Act
-        viewModel.start(parentViewModel)
-        // Assert
-        assertThat(uiStates.size).isEqualTo(2)
-        assertThat(uiStates[1]).isInstanceOf(ShowNoFollowedTagsUiState::class.java)
-    }
-
     @Test
     fun `ShowNoPostsUiState is shown when the discoverFeed does not contain any posts`() = test {
         // Arrange
@@ -645,18 +602,6 @@ class ReaderDiscoverViewModelTest : BaseUnitTest() {
             assertThat(scrollToTopCounter.count).isZero()
     }
 
-    @Test
-    fun `Action button on no tags empty screen opens reader interests screen`() = test {
-        // Arrange
-        whenever(getFollowedTagsUseCase.get()).thenReturn(ReaderTagList())
-        init()
-        fakeDiscoverFeed.value = ReaderDiscoverCards(listOf())
-        // Act
-        (viewModel.uiState.value as ShowNoFollowedTagsUiState).action.invoke()
-        // Assert
-        verify(parentViewModel).onShowReaderInterests()
-    }
-
     @Test
     fun `Action button on no posts empty screen opens subs screen`() = test {
         // Arrange