Skip to content

Commit

Permalink
Reader Discover not matching iOS & Web (#21707)
Browse files Browse the repository at this point in the history
* Don't show "follow tags" in Discover when followed tags are empty

* Supply default tags when user isn't following any tags

* Pass users followed tags to endpoint

* Fixed failing test

* Removed failing test

* Removed other failing tests
  • Loading branch information
nbradbury authored Feb 25, 2025
1 parent dbf22f7 commit fe06d91
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -141,7 +135,6 @@ class ReaderDiscoverViewModelTest : BaseUnitTest() {
readerUtilsWrapper,
readerTracker,
displayUtilsWrapper,
getFollowedTagsUseCase,
mReaderAnnouncementHelper,
testDispatcher(),
testDispatcher()
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit fe06d91

Please sign in to comment.