From 751fe980ccda407dad8aa0a5fa31b3a2ca5668ed Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 28 Dec 2023 17:34:45 +0530 Subject: [PATCH 001/250] =?UTF-8?q?=E2=86=91=20Updates:=20the=20build=20lo?= =?UTF-8?q?gic=20to=20use=20mergeAsync?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/checkstyle-idea.xml | 26 ++++++++--------- .idea/codeStyles/Project.xml | 4 +-- .../android/ui/mysite/MySiteViewModel.kt | 12 ++++++-- .../wordpress/android/util/LiveDataUtils.kt | 28 +++++++++++++++++++ 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml index 7f921dc3495d..d45e0aca52e1 100644 --- a/.idea/checkstyle-idea.xml +++ b/.idea/checkstyle-idea.xml @@ -1,18 +1,18 @@ - - diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index a145657e502b..5ee4f2b40452 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -35,8 +35,6 @@ - + , + sourceB: LiveData, + sourceC: LiveData, + sourceD: LiveData, + sourceE: LiveData, + sourceF: LiveData, + sourceG: LiveData, + sourceH: LiveData, + sourceI: LiveData, + sourceJ: LiveData, + sourceK: LiveData, distinct: Boolean = false, - merger: (Q?, R?, S?, T?, U?, V?, W?, X?, Y?, Z?) -> A? -): LiveData { - data class NineItemContainer( - val first: Q? = null, - val second: R? = null, - val third: S? = null, - val fourth: T? = null, - val fifth: U? = null, - val sixth: V? = null, - val seventh: W? = null, - val eighth: X? = null, - val ninth: Y? = null, - val tenth: Z? = null, + merger: (A?, B?, C?, D?, E?, F?, G?, H?, I?, J?, K?) -> Z? +): LiveData { + data class ElevenItemContainer( + val first: A? = null, + val second: B? = null, + val third: C? = null, + val fourth: D? = null, + val fifth: E? = null, + val sixth: F? = null, + val seventh: G? = null, + val eighth: H? = null, + val ninth: I? = null, + val tenth: J? = null, + val eleventh: K? = null ) - val mediator = MediatorLiveData() - mediator.value = NineItemContainer() + val mediator = MediatorLiveData() + mediator.value = ElevenItemContainer() mediator.addSource(sourceA) { val container = mediator.value if (container?.first != it || !distinct) { @@ -455,8 +460,16 @@ fun merge( mediator.value = container?.copy(tenth = it) } } - return mediator.mapSafe { (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth) -> - merger(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth) + + mediator.addSource(sourceK) { + val container = mediator.value + if (container?.eleventh != it || !distinct) { + mediator.value = container?.copy(eleventh = it) + } + } + + return mediator.mapSafe { (first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh) -> + merger(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh) } } From 9767ede39e18d85360094f8ddf33b4e96461dd25 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 18 Jan 2024 15:36:10 +0530 Subject: [PATCH 148/250] =?UTF-8?q?=E2=86=91=20Updates:=20the=20JetpackBad?= =?UTF-8?q?geViewModelSlice=20and=20adds=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JetpackBadgeViewModelSlice.kt | 3 +- .../JetpackBadgeViewModelSliceTest.kt | 87 +++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSliceTest.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt index f38702ff9856..de7ec7657ac0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt @@ -19,10 +19,11 @@ class JetpackBadgeViewModelSlice @Inject constructor( private val _uiModel = MutableLiveData() val uiModel = _uiModel.distinctUntilChanged() + val screen = JetpackPoweredScreen.WithStaticText.HOME + suspend fun buildJetpackBadge(){ if(jetpackBrandingUtils.shouldShowJetpackBrandingInDashboard().not()) _uiModel.postValue(null) - val screen = JetpackPoweredScreen.WithStaticText.HOME _uiModel.postValue(MySiteCardAndItem.JetpackBadge( text = jetpackBrandingUtils.getBrandingTextForScreen(screen), onClick = if (jetpackBrandingUtils.shouldShowJetpackPoweredBottomSheet()) { diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSliceTest.kt new file mode 100644 index 000000000000..18446e70b7f9 --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSliceTest.kt @@ -0,0 +1,87 @@ +package org.wordpress.android.ui.mysite.items.jetpackBadge + +import junit.framework.TestCase.assertEquals +import junit.framework.TestCase.assertNull +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.mockito.kotlin.whenever +import org.wordpress.android.BaseUnitTest +import org.wordpress.android.models.JetpackPoweredScreen +import org.wordpress.android.ui.mysite.MySiteCardAndItem +import org.wordpress.android.ui.mysite.SiteNavigationAction +import org.wordpress.android.ui.utils.UiString +import org.wordpress.android.util.JetpackBrandingUtils + +@ExperimentalCoroutinesApi +@RunWith(MockitoJUnitRunner::class) +class JetpackBadgeViewModelSliceTest : BaseUnitTest() { + @Mock + lateinit var jetpackBrandingUtils: JetpackBrandingUtils + + private lateinit var viewModelSlice: JetpackBadgeViewModelSlice + + val uiModels = mutableListOf() + + val navigationEvents = mutableListOf() + + fun setUp() { + viewModelSlice = JetpackBadgeViewModelSlice(jetpackBrandingUtils) + + viewModelSlice.uiModel.observeForever { + uiModels.add(it) + } + + viewModelSlice.onNavigation.observeForever { + it?.let { navigationEvents.add(it.peekContent()) } + } + } + + @Test + fun `given jetpack branding should not be shown, ui model is null`() = test { + // given + whenever(jetpackBrandingUtils.shouldShowJetpackBrandingInDashboard()).thenReturn(false) + + // when + viewModelSlice.buildJetpackBadge() + + // then + assertEquals(1, uiModels.size) + assertNull(uiModels[0]) + } + + @Test + fun `given jetpack branding should be shown, ui model is not null`() = test { + // given + val brandingText = UiString.UiStringText("Jetpack") + whenever(jetpackBrandingUtils.shouldShowJetpackBrandingInDashboard()).thenReturn(true) + whenever(jetpackBrandingUtils.shouldShowJetpackPoweredBottomSheet()).thenReturn(true) + whenever(jetpackBrandingUtils.getBrandingTextForScreen(JetpackPoweredScreen.WithStaticText.HOME)) + .thenReturn(brandingText) + + // when + viewModelSlice.buildJetpackBadge() + + // then + assertEquals(1, uiModels.size) + assertEquals(brandingText, uiModels[0]?.text) + } + + @Test + fun `given jetpack branding should be shown, when badge is clicked, then navigation event is emitted`() = test { + // given + whenever(jetpackBrandingUtils.shouldShowJetpackBrandingInDashboard()).thenReturn(true) + whenever(jetpackBrandingUtils.shouldShowJetpackPoweredBottomSheet()).thenReturn(true) + + // when + viewModelSlice.buildJetpackBadge() + uiModels[0]?.onClick?.click() + + // then + assertEquals(1, navigationEvents.size) + assertEquals(SiteNavigationAction.OpenJetpackPoweredBottomSheet, navigationEvents[0]) + } +} + From 08074a4b985a42017fb21252237e260d2f595b9a Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 18 Jan 2024 16:11:37 +0530 Subject: [PATCH 149/250] * Fixes: JetpackBadgeViewModelSlice and tests --- .../jetpackBadge/JetpackBadgeViewModelSlice.kt | 2 +- .../jetpackBadge/JetpackBadgeViewModelSliceTest.kt | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt index de7ec7657ac0..521f94e54952 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt @@ -23,7 +23,7 @@ class JetpackBadgeViewModelSlice @Inject constructor( suspend fun buildJetpackBadge(){ if(jetpackBrandingUtils.shouldShowJetpackBrandingInDashboard().not()) - _uiModel.postValue(null) + return _uiModel.postValue(null) _uiModel.postValue(MySiteCardAndItem.JetpackBadge( text = jetpackBrandingUtils.getBrandingTextForScreen(screen), onClick = if (jetpackBrandingUtils.shouldShowJetpackPoweredBottomSheet()) { diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSliceTest.kt index 18446e70b7f9..e08bb1e68125 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSliceTest.kt @@ -3,6 +3,7 @@ package org.wordpress.android.ui.mysite.items.jetpackBadge import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertNull import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock @@ -23,17 +24,20 @@ class JetpackBadgeViewModelSliceTest : BaseUnitTest() { private lateinit var viewModelSlice: JetpackBadgeViewModelSlice - val uiModels = mutableListOf() + private lateinit var uiModels: MutableList - val navigationEvents = mutableListOf() + private lateinit var navigationEvents: MutableList + @Before fun setUp() { viewModelSlice = JetpackBadgeViewModelSlice(jetpackBrandingUtils) + uiModels = mutableListOf() viewModelSlice.uiModel.observeForever { uiModels.add(it) } + navigationEvents = mutableListOf() viewModelSlice.onNavigation.observeForever { it?.let { navigationEvents.add(it.peekContent()) } } @@ -46,9 +50,9 @@ class JetpackBadgeViewModelSliceTest : BaseUnitTest() { // when viewModelSlice.buildJetpackBadge() + advanceUntilIdle() // then - assertEquals(1, uiModels.size) assertNull(uiModels[0]) } @@ -72,8 +76,11 @@ class JetpackBadgeViewModelSliceTest : BaseUnitTest() { @Test fun `given jetpack branding should be shown, when badge is clicked, then navigation event is emitted`() = test { // given + val brandingText = UiString.UiStringText("Jetpack") whenever(jetpackBrandingUtils.shouldShowJetpackBrandingInDashboard()).thenReturn(true) whenever(jetpackBrandingUtils.shouldShowJetpackPoweredBottomSheet()).thenReturn(true) + whenever(jetpackBrandingUtils.getBrandingTextForScreen(JetpackPoweredScreen.WithStaticText.HOME)) + .thenReturn(brandingText) // when viewModelSlice.buildJetpackBadge() From 9f22dccbb035b81b3aded3cf129f1abfec8f5fca Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Thu, 18 Jan 2024 11:31:58 -0500 Subject: [PATCH 150/250] Fix failing unit tests --- .../siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt index 9369e3b1e92b..c9a089e5db13 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt @@ -4,7 +4,6 @@ import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.ExperimentalCoroutinesApi import org.assertj.core.api.Assertions import org.junit.Before -import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock @@ -36,7 +35,6 @@ import org.wordpress.android.viewmodel.ContextProvider @Suppress("LargeClass") @ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) -@Ignore("The tests are failing, update it to the latest code") class SiteInfoHeaderCardViewModelSliceTest : BaseUnitTest() { @Mock lateinit var wpMediaUtilsWrapper: WPMediaUtilsWrapper @@ -84,8 +82,14 @@ class SiteInfoHeaderCardViewModelSliceTest : BaseUnitTest() { @Mock lateinit var quickStartType: QuickStartType + @Mock + lateinit var siteModel: SiteModel @Before fun setUp() { + whenever(quickStartRepository.activeTask).thenReturn(activeTask) + whenever(selectedSiteRepository.showSiteIconProgressBar).thenReturn(MutableLiveData(false)) + whenever(selectedSiteRepository.selectedSiteChange).thenReturn(MutableLiveData(siteModel)) + viewModelSlice = SiteInfoHeaderCardViewModelSlice( testDispatcher(), quickStartRepository, From 157c0be4c46763b32914bd6c63729252ae22cb15 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Thu, 18 Jan 2024 12:15:53 -0500 Subject: [PATCH 151/250] Add tests for verification of card build --- .../SiteInfoHeaderCardViewModelSliceTest.kt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt index c9a089e5db13..140cb17f4862 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt @@ -9,13 +9,17 @@ import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.any +import org.mockito.kotlin.clearInvocations +import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.R import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.QuickStartStore +import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.SiteInfoHeaderCard import org.wordpress.android.ui.mysite.MySiteViewModel import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.SiteDialogModel @@ -71,6 +75,7 @@ class SiteInfoHeaderCardViewModelSliceTest : BaseUnitTest() { private lateinit var textInputDialogModels: MutableList private lateinit var dialogModels: MutableList private lateinit var navigationActions: MutableList + private lateinit var uiModels: MutableList private val siteLocalId = 1 private val siteUrl = "http://site.com" @@ -108,6 +113,7 @@ class SiteInfoHeaderCardViewModelSliceTest : BaseUnitTest() { textInputDialogModels = mutableListOf() dialogModels = mutableListOf() navigationActions = mutableListOf() + uiModels = mutableListOf() viewModelSlice.onSnackbarMessage.observeForever { event -> event?.getContentIfNotHandled()?.let { @@ -129,6 +135,9 @@ class SiteInfoHeaderCardViewModelSliceTest : BaseUnitTest() { navigationActions.add(it) } } + viewModelSlice.uiModel.observeForever { + uiModels.add(it) + } site = SiteModel() site.id = siteLocalId @@ -457,6 +466,34 @@ class SiteInfoHeaderCardViewModelSliceTest : BaseUnitTest() { verify(quickStartRepository).checkAndShowQuickStartNotice() } + @Test + fun `when selectedSite is null, then card is not built`() { + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(null) + + clearInvocations(siteInfoHeaderCardBuilder) + + viewModelSlice.onResume() + + verifyNoInteractions(siteInfoHeaderCardBuilder) + } + + @Test + fun `when selectedSite is not null, then card is built`() { + val siteModel = mock().apply { + id = 1 + name = "name" + url = "https://site.wordpress.com" + } + + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(siteModel) + + clearInvocations(siteInfoHeaderCardBuilder) + + viewModelSlice.onResume() + + verify(siteInfoHeaderCardBuilder).buildSiteInfoCard(any()) + } + private enum class SiteInfoHeaderCardAction { TITLE_CLICK, ICON_CLICK, URL_CLICK, SWITCH_SITE_CLICK } From cbc597303af7fc829215d8831f8df4cb809f8366 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Fri, 19 Jan 2024 01:05:49 +0530 Subject: [PATCH 152/250] * Fixes: Site icon upload not reflecting --- .../wordpress/android/ui/mysite/SelectedSiteRepository.kt | 7 +++++++ .../wordpress/android/ui/mysite/SiteIconUploadHandler.kt | 2 ++ 2 files changed, 9 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/SelectedSiteRepository.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/SelectedSiteRepository.kt index 3b175415b647..f72a297628b1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/SelectedSiteRepository.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/SelectedSiteRepository.kt @@ -33,6 +33,13 @@ class SelectedSiteRepository @Inject constructor( val siteSelected = _selectedSiteChange.mapSafe { it?.id }.distinctUntilChanged() + fun refresh() { + updateSiteSettingsIfNecessary() + _selectedSiteChange.value?.let { + dispatcher.dispatch(SiteActionBuilder.newFetchSiteAction(it)) + } + } + fun updateSite(selectedSite: SiteModel) { if (getSelectedSite()?.iconUrl != selectedSite.iconUrl) { showSiteIconProgressBar(false) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteIconUploadHandler.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteIconUploadHandler.kt index dc049b346f46..a24603ba15d6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteIconUploadHandler.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteIconUploadHandler.kt @@ -74,6 +74,8 @@ class SiteIconUploadHandler if (event.mediaModelList.size > 0) { val media = event.mediaModelList[0] selectedSiteRepository.updateSiteIconMediaId(media.mediaId.toInt(), true) + selectedSiteRepository.showSiteIconProgressBar(false) + selectedSiteRepository.refresh() } else { AppLog.w( MAIN, From 56b74ddf05ae321dec8dcf1cb39f44bab9d9e211 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Fri, 19 Jan 2024 11:59:42 +0530 Subject: [PATCH 153/250] * Fixes: Typo in QuickStartCardViewModelSlice --- .../cards/DashboardCardsViewModelSlice.kt | 14 ++++---- ...ice.kt => QuickStartCardViewModelSlice.kt} | 2 +- .../QuickStartCardViewModelSliceTest.kt | 36 +++++++++---------- 3 files changed, 26 insertions(+), 26 deletions(-) rename WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/{QuickStartCardVewModelSlice.kt => QuickStartCardViewModelSlice.kt} (99%) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index eff10025ddc2..7fd35d8e85a0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -19,7 +19,7 @@ import org.wordpress.android.ui.mysite.cards.nocards.NoCardsMessageViewModelSlic import org.wordpress.android.ui.mysite.cards.personalize.PersonalizeCardViewModelSlice import org.wordpress.android.ui.mysite.cards.plans.PlansCardViewModelSlice import org.wordpress.android.ui.mysite.cards.quicklinksitem.QuickLinksItemViewModelSlice -import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardVewModelSlice +import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardViewModelSlice import org.wordpress.android.ui.pages.SnackbarMessageHolder import org.wordpress.android.util.BuildConfigWrapper import org.wordpress.android.util.merge @@ -34,7 +34,7 @@ class DashboardCardsViewModelSlice @Inject constructor( private val cardViewModelSlice: CardViewModelSlice, private val personalizeCardViewModelSlice: PersonalizeCardViewModelSlice, private val bloggingPromptCardViewModelSlice: BloggingPromptCardViewModelSlice, - private val quickStartCardVewModelSlice: QuickStartCardVewModelSlice, + private val quickStartCardViewModelSlice: QuickStartCardViewModelSlice, private val noCardsMessageViewModelSlice: NoCardsMessageViewModelSlice, private val quickLinksItemViewModelSlice: QuickLinksItemViewModelSlice, private val bloganuaryNudgeCardViewModelSlice: BloganuaryNudgeCardViewModelSlice, @@ -63,7 +63,7 @@ class DashboardCardsViewModelSlice @Inject constructor( quickLinksItemViewModelSlice.navigation, plansCardViewModelSlice.onNavigation, jpMigrationSuccessCardViewModelSlice.onNavigation, - quickStartCardVewModelSlice.onNavigation, + quickStartCardViewModelSlice.onNavigation, domainRegistrationCardViewModelSlice.onNavigation, ) @@ -76,13 +76,13 @@ class DashboardCardsViewModelSlice @Inject constructor( blazeCardViewModelSlice.isRefreshing, cardViewModelSlice.isRefreshing, bloggingPromptCardViewModelSlice.isRefreshing, - quickStartCardVewModelSlice.isRefreshing, + quickStartCardViewModelSlice.isRefreshing, domainRegistrationCardViewModelSlice.isRefreshing ) val uiModel: MutableLiveData> = merge( quickLinksItemViewModelSlice.uiState, - quickStartCardVewModelSlice.uiModel, + quickStartCardViewModelSlice.uiModel, blazeCardViewModelSlice.uiModel, cardViewModelSlice.uiModel, bloggingPromptCardViewModelSlice.uiModel, @@ -161,7 +161,7 @@ class DashboardCardsViewModelSlice @Inject constructor( personalizeCardViewModelSlice.initialize(scope) quickLinksItemViewModelSlice.initialization(scope) cardViewModelSlice.initialize(scope) - quickStartCardVewModelSlice.initialize(scope) + quickStartCardViewModelSlice.initialize(scope) } private fun buildCards(site: SiteModel) { @@ -174,7 +174,7 @@ class DashboardCardsViewModelSlice @Inject constructor( quickLinksItemViewModelSlice.buildCard(site) plansCardViewModelSlice.buildCard(site) cardViewModelSlice.buildCard(site) - quickStartCardVewModelSlice.build(site) + quickStartCardViewModelSlice.build(site) } fun onResume() { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardVewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt similarity index 99% rename from WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardVewModelSlice.kt rename to WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt index 17718ed0327a..a62ea44c2a9c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardVewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt @@ -18,7 +18,7 @@ import org.wordpress.android.util.QuickStartUtilsWrapper import org.wordpress.android.viewmodel.Event import javax.inject.Inject -class QuickStartCardVewModelSlice @Inject constructor( +class QuickStartCardViewModelSlice @Inject constructor( private val quickStartRepository: QuickStartRepository, private val quickStartStore: QuickStartStore, private val quickStartUtilsWrapper: QuickStartUtilsWrapper, diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt index 29876108ef03..7f54f1cc107a 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt @@ -89,7 +89,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { private lateinit var site: SiteModel private lateinit var quickStartRepository: QuickStartRepository - private lateinit var quickStartCardVewModelSlice: QuickStartCardVewModelSlice + private lateinit var mQuickStartCardViewModelSlice: QuickStartCardViewModelSlice private lateinit var snackbars: MutableList private lateinit var quickStartPrompts: MutableList @@ -120,7 +120,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { htmlMessageUtils, quickStartTracker ) - quickStartCardVewModelSlice = QuickStartCardVewModelSlice( + mQuickStartCardViewModelSlice = QuickStartCardViewModelSlice( quickStartRepository, quickStartStore, quickStartUtilsWrapper, @@ -140,17 +140,17 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { } result = mutableListOf() - quickStartCardVewModelSlice.uiModel.observeForever { result.add(it) } + mQuickStartCardViewModelSlice.uiModel.observeForever { result.add(it) } isRefreshing = mutableListOf() - quickStartCardVewModelSlice.isRefreshing.observeForever { isRefreshing.add(it) } + mQuickStartCardViewModelSlice.isRefreshing.observeForever { isRefreshing.add(it) } } @Test fun `refresh loads model`() = test { initStore() - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.refresh() assertModel() } @@ -169,8 +169,8 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { fun `start marks CREATE_SITE as done and loads model`() = test { initStore() - quickStartCardVewModelSlice.build(testScope(), site.id) - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.build(testScope(), site.id) + mQuickStartCardViewModelSlice.refresh() assertModel() } @@ -178,7 +178,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { @Test fun `sets active task and shows stylized snackbar when not UPDATE_SITE_TITLE`() = test { initStore() - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.refresh() quickStartRepository.setActiveTask(PUBLISH_POST) @@ -190,7 +190,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { fun `completeTask marks current active task as done and refreshes model`() = test { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) initStore() - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.refresh() val task = PUBLISH_POST quickStartRepository.setActiveTask(task) @@ -207,7 +207,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { fun `completeTask marks current pending task as done and refreshes model`() = test { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) initStore() - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.refresh() val task = PUBLISH_POST quickStartRepository.setActiveTask(task) @@ -280,11 +280,11 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { site.id = updatedSiteId site.showOnFront = ShowOnFront.POSTS.value whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) - quickStartCardVewModelSlice.refresh.observeForever { isRefreshing.add(it) } + mQuickStartCardViewModelSlice.refresh.observeForever { isRefreshing.add(it) } - quickStartCardVewModelSlice.build(testScope(), site.id) + mQuickStartCardViewModelSlice.build(testScope(), site.id) - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.refresh() assertThat(isRefreshing.last()).isFalse } @@ -294,7 +294,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { whenever(quickStartUtilsWrapper.isQuickStartAvailableForTheSite(site)).thenReturn(true) initStore() - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.refresh() val update = result.last() assertThat(update.categories).isNotEmpty @@ -305,7 +305,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { whenever(quickStartUtilsWrapper.isQuickStartAvailableForTheSite(site)).thenReturn(false) initStore() - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.refresh() val update = result.last() assertThat(update.categories).isEmpty() @@ -317,12 +317,12 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { val task = PUBLISH_POST quickStartRepository.setActiveTask(task) quickStartRepository.completeTask(task) - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.refresh() } private suspend fun initQuickStartInProgress() { initStore() - quickStartCardVewModelSlice.refresh() + mQuickStartCardViewModelSlice.refresh() } private suspend fun initStore( @@ -358,7 +358,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { } private fun initBuild() { - quickStartCardVewModelSlice.build(siteLocalId) + mQuickStartCardViewModelSlice.build(siteLocalId) } private fun assertModel() { From 56f476e19e65cea63007376ddfb940a72a6dcd88 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Fri, 19 Jan 2024 14:41:36 +0530 Subject: [PATCH 154/250] =?UTF-8?q?=E2=86=92=20Moves:=20SiteInfoHeaderCard?= =?UTF-8?q?ViewModelSlice=20on=20Resume=20inside=20site=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/wordpress/android/ui/mysite/MySiteViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 7a0220c7b2bd..92059ffe985f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -263,7 +263,6 @@ class MySiteViewModel @Inject constructor( } fun onResume() { - siteInfoHeaderCardViewModelSlice.onResume() // mySiteSourceManager.onResume(isSiteSelected) isSiteSelected = false checkAndShowJetpackFullPluginInstallOnboarding() @@ -273,6 +272,7 @@ class MySiteViewModel @Inject constructor( selectedSiteRepository.getSelectedSite()?.let { dashboardCardsViewModelSlice.onResume() dashboardItemsViewModelSlice.onResume() + siteInfoHeaderCardViewModelSlice.onResume() }?: run { accountDataViewModelSlice.onResume() } From a1ae2be2b2fcd238599749fadfe548a71366deb2 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Fri, 19 Jan 2024 14:41:56 +0530 Subject: [PATCH 155/250] + Adds: Missing show quick start notice function --- .../java/org/wordpress/android/ui/mysite/MySiteViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 92059ffe985f..6563e687628f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -415,7 +415,7 @@ class MySiteViewModel @Inject constructor( quickStartRepository.quickStartType, quickStartTracker ) -// mySiteSourceManager.refreshQuickStart() + quickStartRepository.checkAndShowQuickStartNotice() } } From 674904cc767fd4c25daa9f7bb019e8358a5d317f Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Sat, 20 Jan 2024 15:43:01 +0530 Subject: [PATCH 156/250] + Adds: logic to refresh the blogging prompt data --- .../bloggingprompts/BloggingPromptCardViewModelSlice.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index 015b4f5f4d50..ef5823cbb33e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -73,6 +73,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( .map { it.model?.filter { prompt -> isSameDay(prompt.date, Date()) } } .collect { result -> postState(result?.firstOrNull()) + refreshData(siteModel) } } else { postEmptyState() From f6fd8cac0be32bec0684e7c5d04fdb8bc1701c7c Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Sun, 21 Jan 2024 16:28:01 -0500 Subject: [PATCH 157/250] Add tests for dashboardItemsViewModelSlice --- .../DashboardItemsViewModelSliceTest.kt | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt new file mode 100644 index 000000000000..1f5a99f36d1f --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt @@ -0,0 +1,190 @@ +package org.wordpress.android.ui.mysite + +import androidx.lifecycle.MutableLiveData +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.isActive +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.mockito.kotlin.any +import org.mockito.kotlin.atLeastOnce +import org.mockito.kotlin.atMost +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever +import org.wordpress.android.BaseUnitTest +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardHelper +import org.wordpress.android.ui.mysite.cards.sotw2023.WpSotw2023NudgeCardViewModelSlice +import org.wordpress.android.ui.mysite.items.DashboardItemsViewModelSlice +import org.wordpress.android.ui.mysite.items.jetpackBadge.JetpackBadgeViewModelSlice +import org.wordpress.android.ui.mysite.items.jetpackSwitchmenu.JetpackSwitchMenuViewModelSlice +import org.wordpress.android.ui.mysite.items.jetpackfeaturecard.JetpackFeatureCardViewModelSlice +import org.wordpress.android.ui.mysite.items.listitem.SiteItemsViewModelSlice +import org.wordpress.android.ui.pages.SnackbarMessageHolder +import org.wordpress.android.util.BuildConfigWrapper + +@ExperimentalCoroutinesApi +@RunWith(MockitoJUnitRunner::class) +class DashboardItemsViewModelSliceTest: BaseUnitTest() { + @Mock + lateinit var jetpackFeatureCardViewModelSlice: JetpackFeatureCardViewModelSlice + + @Mock + lateinit var jetpackSwitchMenuViewModelSlice: JetpackSwitchMenuViewModelSlice + + @Mock + lateinit var jetpackBadgeViewModelSlice: JetpackBadgeViewModelSlice + + @Mock + lateinit var siteItemsViewModelSlice: SiteItemsViewModelSlice + + @Mock + lateinit var sotw2023NudgeCardViewModelSlice: WpSotw2023NudgeCardViewModelSlice + + @Mock + lateinit var jetpackFeatureCardHelper: JetpackFeatureCardHelper + + @Mock + lateinit var selectedSiteRepository: SelectedSiteRepository + + @Mock + lateinit var buildConfigWrapper: BuildConfigWrapper + + private lateinit var dashboardItemsViewModelSlice: DashboardItemsViewModelSlice + + private lateinit var navigationActions: MutableList + private lateinit var snackBarMessages: MutableList + private lateinit var uiModels: MutableList> + + @Before + fun setup() { + whenever(jetpackFeatureCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(jetpackSwitchMenuViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(jetpackBadgeViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(siteItemsViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(sotw2023NudgeCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + + dashboardItemsViewModelSlice = DashboardItemsViewModelSlice( + jetpackFeatureCardViewModelSlice, + jetpackSwitchMenuViewModelSlice, + jetpackBadgeViewModelSlice, + siteItemsViewModelSlice, + sotw2023NudgeCardViewModelSlice, + jetpackFeatureCardHelper, + selectedSiteRepository, + buildConfigWrapper + ) + + navigationActions = mutableListOf() + snackBarMessages = mutableListOf() + uiModels = mutableListOf() + + dashboardItemsViewModelSlice.onNavigation.observeForever { event -> + event?.getContentIfNotHandled()?.let { navigationActions.add(it) } + } + + dashboardItemsViewModelSlice.onSnackbarMessage.observeForever { event -> + event?.getContentIfNotHandled()?.let { snackBarMessages.add(it) } + } + + dashboardItemsViewModelSlice.uiModel.observeForever { uiModel -> + uiModels.add(uiModel) + } + } + + + @Test + fun `when initialize is invoked then should call initialize on sotw2023NudgeCardViewModelSlice`() { + val scope = testScope() + dashboardItemsViewModelSlice.initialize(scope) + verify(sotw2023NudgeCardViewModelSlice).initialize(scope) + } + + @Test + fun `given shouldShowSiteItems is false, when onResume, then should not build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) + whenever(mockSite.isUsingWpComRestApi).thenReturn(true) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardItemsViewModelSlice.initialize(testScope()) + dashboardItemsViewModelSlice.onResume() + + verify(selectedSiteRepository).getSelectedSite() + verify(siteItemsViewModelSlice, never()).buildSiteItems(any()) + verify(jetpackFeatureCardViewModelSlice, never()).buildJetpackFeatureCard() + } + + @Test + fun `given shouldShowSiteItems is true, when onResume, then should build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) + whenever(mockSite.isUsingWpComRestApi).thenReturn(false) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardItemsViewModelSlice.initialize(testScope()) + + dashboardItemsViewModelSlice.onResume() + + verify(selectedSiteRepository).getSelectedSite() + verify(siteItemsViewModelSlice, atLeastOnce()).buildSiteItems(any()) + verify(jetpackFeatureCardViewModelSlice, atMost(1)).buildJetpackFeatureCard() + verify(jetpackSwitchMenuViewModelSlice, atMost(1)).buildJetpackSwitchMenu() + verify(jetpackBadgeViewModelSlice, atMost(1)).buildJetpackBadge() + verify(siteItemsViewModelSlice, atMost(1)).buildSiteItems(mockSite) + verify(sotw2023NudgeCardViewModelSlice, atMost(1)).buildCard() + } + + @Test + fun `given shouldShowSiteItems is false, when onRefreshed invoked, then should not build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) + whenever(mockSite.isUsingWpComRestApi).thenReturn(true) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardItemsViewModelSlice.initialize(testScope()) + dashboardItemsViewModelSlice.onRefresh() + + verify(selectedSiteRepository).getSelectedSite() + verify(siteItemsViewModelSlice, never()).buildSiteItems(any()) + verify(jetpackFeatureCardViewModelSlice, never()).buildJetpackFeatureCard() + } + + @Test + fun `given shouldShowSiteItems is true, when onRefresh invoked, then should build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) + whenever(mockSite.isUsingWpComRestApi).thenReturn(false) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardItemsViewModelSlice.initialize(testScope()) + + dashboardItemsViewModelSlice.onRefresh() + + verify(selectedSiteRepository).getSelectedSite() + verify(siteItemsViewModelSlice, atLeastOnce()).buildSiteItems(any()) + verify(jetpackFeatureCardViewModelSlice, atMost(1)).buildJetpackFeatureCard() + verify(jetpackSwitchMenuViewModelSlice, atMost(1)).buildJetpackSwitchMenu() + verify(jetpackBadgeViewModelSlice, atMost(1)).buildJetpackBadge() + verify(siteItemsViewModelSlice, atMost(1)).buildSiteItems(mockSite) + verify(sotw2023NudgeCardViewModelSlice, atMost(1)).buildCard() + } + @Test + fun `given initialized scope, when onCleared, then should cancel the coroutine scope`() { + val scope = testScope() + dashboardItemsViewModelSlice.initialize(scope) + + // Verify that scope is not canceled before calling onCleared + assertThat(scope.isActive).isTrue() + + dashboardItemsViewModelSlice.onCleared() + + // Verify that the scope is canceled after calling onCleared + assertThat(scope.isActive).isFalse() + } +} From fb2b9a4ba7605b1ff81ae327aa165422521b4c9c Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Sun, 21 Jan 2024 17:51:02 -0500 Subject: [PATCH 158/250] Add tests for dashboardCardsViewModelSlice --- .../DashboardCardsViewModelSliceTest.kt | 298 ++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt new file mode 100644 index 000000000000..9ec4365e3473 --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt @@ -0,0 +1,298 @@ +package org.wordpress.android.ui.mysite + +import androidx.lifecycle.MutableLiveData +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.isActive +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.assertj.core.api.Assertions.assertThat +import org.mockito.kotlin.atMost +import org.mockito.kotlin.clearInvocations +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoMoreInteractions +import org.mockito.kotlin.whenever +import org.wordpress.android.BaseUnitTest +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.ui.mysite.cards.DashboardCardsViewModelSlice +import org.wordpress.android.ui.mysite.cards.dashboard.CardViewModelSlice +import org.wordpress.android.ui.mysite.cards.dashboard.bloganuary.BloganuaryNudgeCardViewModelSlice +import org.wordpress.android.ui.mysite.cards.dashboard.bloggingprompts.BloggingPromptCardViewModelSlice +import org.wordpress.android.ui.mysite.cards.domainregistration.DomainRegistrationCardViewModelSlice +import org.wordpress.android.ui.mysite.cards.jpfullplugininstall.JetpackInstallFullPluginCardViewModelSlice +import org.wordpress.android.ui.mysite.cards.migration.JpMigrationSuccessCardViewModelSlice +import org.wordpress.android.ui.mysite.cards.nocards.NoCardsMessageViewModelSlice +import org.wordpress.android.ui.mysite.cards.personalize.PersonalizeCardViewModelSlice +import org.wordpress.android.ui.mysite.cards.plans.PlansCardViewModelSlice +import org.wordpress.android.ui.mysite.cards.quicklinksitem.QuickLinksItemViewModelSlice +import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardViewModelSlice +import org.wordpress.android.util.BuildConfigWrapper + +@ExperimentalCoroutinesApi +@RunWith(MockitoJUnitRunner::class) +class DashboardCardsViewModelSliceTest: BaseUnitTest() { + @Mock + lateinit var jpMigrationSuccessCardViewModelSlice: JpMigrationSuccessCardViewModelSlice + @Mock + lateinit var jetpackInstallFullPluginCardViewModelSlice: JetpackInstallFullPluginCardViewModelSlice + @Mock + lateinit var domainRegistrationCardViewModelSlice: DomainRegistrationCardViewModelSlice + @Mock + lateinit var blazeCardViewModelSlice: BlazeCardViewModelSlice + @Mock + lateinit var cardViewModelSlice: CardViewModelSlice + @Mock + lateinit var personalizeCardViewModelSlice: PersonalizeCardViewModelSlice + @Mock + lateinit var bloggingPromptCardViewModelSlice: BloggingPromptCardViewModelSlice + @Mock + lateinit var quickStartCardViewModelSlice: QuickStartCardViewModelSlice + @Mock + lateinit var noCardsMessageViewModelSlice: NoCardsMessageViewModelSlice + @Mock + lateinit var quickLinksItemViewModelSlice: QuickLinksItemViewModelSlice + @Mock + lateinit var bloganuaryNudgeCardViewModelSlice: BloganuaryNudgeCardViewModelSlice + @Mock + lateinit var plansCardViewModelSlice: PlansCardViewModelSlice + @Mock + lateinit var selectedSiteRepository: SelectedSiteRepository + @Mock + lateinit var buildConfigWrapper: BuildConfigWrapper + + private lateinit var dashboardCardsViewModelSlice: DashboardCardsViewModelSlice + + @Before + fun setup() { + whenever(jpMigrationSuccessCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(jetpackInstallFullPluginCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(domainRegistrationCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(blazeCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(cardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(personalizeCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(bloggingPromptCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(quickStartCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(quickLinksItemViewModelSlice.uiState).thenReturn(MutableLiveData()) + whenever(bloganuaryNudgeCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(plansCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + + dashboardCardsViewModelSlice = DashboardCardsViewModelSlice( + jpMigrationSuccessCardViewModelSlice, + jetpackInstallFullPluginCardViewModelSlice, + domainRegistrationCardViewModelSlice, + blazeCardViewModelSlice, + cardViewModelSlice, + personalizeCardViewModelSlice, + bloggingPromptCardViewModelSlice, + quickStartCardViewModelSlice, + noCardsMessageViewModelSlice, + quickLinksItemViewModelSlice, + bloganuaryNudgeCardViewModelSlice, + plansCardViewModelSlice, + selectedSiteRepository, + buildConfigWrapper + ) + } + + @Test + fun `when initialize is invoked, then should call initialize on required slices`() { + val scope = testScope() + + dashboardCardsViewModelSlice.initialize(scope) + + verify(blazeCardViewModelSlice).initialize(scope) + verify(bloggingPromptCardViewModelSlice).initialize(scope) + verify(bloganuaryNudgeCardViewModelSlice).initialize(scope) + verify(personalizeCardViewModelSlice).initialize(scope) + verify(quickLinksItemViewModelSlice).initialization(scope) + verify(cardViewModelSlice).initialize(scope) + verify(quickStartCardViewModelSlice).initialize(scope) + } + + @Test + fun `given showDashboardCards is true, when onResume, then should build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) + whenever(mockSite.isUsingWpComRestApi).thenReturn(true) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardCardsViewModelSlice.initialize(testScope()) + dashboardCardsViewModelSlice.onResume() + + verify(selectedSiteRepository).getSelectedSite() + verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() + verify(jetpackInstallFullPluginCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(blazeCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(bloggingPromptCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(bloganuaryNudgeCardViewModelSlice, atMost(1)).buildCard() + verify(personalizeCardViewModelSlice, atMost(1)).buildCard() + verify(quickLinksItemViewModelSlice, atMost(1)).buildCard(mockSite) + verify(plansCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(cardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(quickStartCardViewModelSlice, atMost(1)).build(mockSite) + } + + @Test + fun `given showDashboardCards is false, when onResume, then should not build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) + whenever(mockSite.isUsingWpComRestApi).thenReturn(true) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardCardsViewModelSlice.initialize(testScope()) + dashboardCardsViewModelSlice.onResume() + + verify(selectedSiteRepository).getSelectedSite() + verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() + verify(jetpackInstallFullPluginCardViewModelSlice, never()).buildCard(mockSite) + verify(blazeCardViewModelSlice, never()).buildCard(mockSite) + verify(bloggingPromptCardViewModelSlice, never()).buildCard(mockSite) + verify(bloganuaryNudgeCardViewModelSlice, never()).buildCard() + verify(personalizeCardViewModelSlice, never()).buildCard() + verify(quickLinksItemViewModelSlice, never()).buildCard(mockSite) + verify(plansCardViewModelSlice, never()).buildCard(mockSite) + verify(cardViewModelSlice, never()).buildCard(mockSite) + verify(quickStartCardViewModelSlice, never()).build(mockSite) + } + + @Test + fun `given showDashboardCards is true, when onRefresh, then should build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) + whenever(mockSite.isUsingWpComRestApi).thenReturn(true) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardCardsViewModelSlice.initialize(testScope()) + dashboardCardsViewModelSlice.onRefresh() + + verify(selectedSiteRepository).getSelectedSite() + verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() + verify(jetpackInstallFullPluginCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(blazeCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(bloggingPromptCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(bloganuaryNudgeCardViewModelSlice, atMost(1)).buildCard() + verify(personalizeCardViewModelSlice, atMost(1)).buildCard() + verify(quickLinksItemViewModelSlice, atMost(1)).buildCard(mockSite) + verify(plansCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(cardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(quickStartCardViewModelSlice, atMost(1)).build(mockSite) + } + + @Test + fun `given showDashboardCards is false, when onRefresh, then should not build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) + whenever(mockSite.isUsingWpComRestApi).thenReturn(true) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardCardsViewModelSlice.initialize(testScope()) + dashboardCardsViewModelSlice.onRefresh() + + verify(selectedSiteRepository).getSelectedSite() + verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() + verify(jetpackInstallFullPluginCardViewModelSlice, never()).buildCard(mockSite) + verify(blazeCardViewModelSlice, never()).buildCard(mockSite) + verify(bloggingPromptCardViewModelSlice, never()).buildCard(mockSite) + verify(bloganuaryNudgeCardViewModelSlice, never()).buildCard() + verify(personalizeCardViewModelSlice, never()).buildCard() + verify(quickLinksItemViewModelSlice, never()).buildCard(mockSite) + verify(plansCardViewModelSlice, never()).buildCard(mockSite) + verify(cardViewModelSlice, never()).buildCard(mockSite) + verify(quickStartCardViewModelSlice, never()).build(mockSite) + } + + @Test + fun `given showDashboardCards is true, when onSiteChanged, then should build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) + whenever(mockSite.isUsingWpComRestApi).thenReturn(true) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardCardsViewModelSlice.initialize(testScope()) + dashboardCardsViewModelSlice.onSiteChanged() + + verify(selectedSiteRepository).getSelectedSite() + verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() + verify(jetpackInstallFullPluginCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(blazeCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(bloggingPromptCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(bloganuaryNudgeCardViewModelSlice, atMost(1)).buildCard() + verify(personalizeCardViewModelSlice, atMost(1)).buildCard() + verify(quickLinksItemViewModelSlice, atMost(1)).buildCard(mockSite) + verify(plansCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(cardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(quickStartCardViewModelSlice, atMost(1)).build(mockSite) + } + + @Test + fun `given showDashboardCards is false, when onSiteChanged, then should not build cards`() = test { + val mockSite = mock() + whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) + whenever(mockSite.isUsingWpComRestApi).thenReturn(true) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardCardsViewModelSlice.initialize(testScope()) + dashboardCardsViewModelSlice.onSiteChanged() + + verify(selectedSiteRepository).getSelectedSite() + verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() + verify(jetpackInstallFullPluginCardViewModelSlice, never()).buildCard(mockSite) + verify(blazeCardViewModelSlice, never()).buildCard(mockSite) + verify(bloggingPromptCardViewModelSlice, never()).buildCard(mockSite) + verify(bloganuaryNudgeCardViewModelSlice, never()).buildCard() + verify(personalizeCardViewModelSlice, never()).buildCard() + verify(quickLinksItemViewModelSlice, never()).buildCard(mockSite) + verify(plansCardViewModelSlice, never()).buildCard(mockSite) + verify(cardViewModelSlice, never()).buildCard(mockSite) + verify(quickStartCardViewModelSlice, never()).build(mockSite) + } + + @Test + fun `given initialized scope, when onCleared, then should cancel the coroutine scope`() { + val scope = testScope() + + dashboardCardsViewModelSlice.initialize(scope) + + assertThat(scope.isActive).isTrue() + + dashboardCardsViewModelSlice.onCleared() + + verify(quickLinksItemViewModelSlice).onCleared() + + assertThat(scope.isActive).isFalse() + } + + @Test + fun `given selectedSite is not null, when refreshBloggingPrompt, then should build blogging prompt card`() { + val mockSite = mock() + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) + + dashboardCardsViewModelSlice.refreshBloggingPrompt() + + verify(bloggingPromptCardViewModelSlice).buildCard(mockSite) + } + + @Test + fun `given selectedSite is null, when refreshBloggingPrompt, then should not build blogging prompt card`() { + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(null) + dashboardCardsViewModelSlice.initialize(testScope()) + clearInvocations(bloggingPromptCardViewModelSlice) + + dashboardCardsViewModelSlice.refreshBloggingPrompt() + + verifyNoMoreInteractions(bloggingPromptCardViewModelSlice) + } + + @Test + fun `when resetShownTracker, then trackers are reset`() { + dashboardCardsViewModelSlice.initialize(testScope()) + + dashboardCardsViewModelSlice.resetShownTracker() + + verify(personalizeCardViewModelSlice).resetShown() + } +} From ae70da2cb5862bb8179d500b249682b0b8595780 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Tue, 23 Jan 2024 16:21:20 +0530 Subject: [PATCH 159/250] - Removes: redundant ui model clear logic --- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 7fd35d8e85a0..ff52f290225c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -199,7 +199,6 @@ class DashboardCardsViewModelSlice @Inject constructor( } fun onCleared() { - uiModel quickLinksItemViewModelSlice.onCleared() scope.cancel() } From c567d58c6ada1951a30923c8bece45d153eeb47f Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 5 Feb 2024 12:57:37 +0530 Subject: [PATCH 160/250] =?UTF-8?q?=E2=86=92=20Moves:=20refresh=20data=20t?= =?UTF-8?q?o=20outside=20the=20flow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bloggingprompts/BloggingPromptCardViewModelSlice.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index ef5823cbb33e..79b5ce045c8a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -82,6 +82,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( } else { postLastState() } + refreshData(siteModel) } fun refreshData( From 7635a43330a85df4552a4125509e114ce32a75eb Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 5 Feb 2024 13:17:51 +0530 Subject: [PATCH 161/250] =?UTF-8?q?=E2=86=91=20Updates:=20the=20implementa?= =?UTF-8?q?tion=20to=20pass=20the=20site=20model?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/ui/mysite/MySiteViewModel.kt | 13 +++++++++---- .../mysite/cards/DashboardCardsViewModelSlice.kt | 16 ++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 6563e687628f..53c85a48dcb3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -257,9 +257,14 @@ class MySiteViewModel @Inject constructor( fun refresh(isPullToRefresh: Boolean = false) { if (isPullToRefresh) analyticsTrackerWrapper.track(Stat.MY_SITE_PULL_TO_REFRESH) - dashboardCardsViewModelSlice.onRefresh() - dashboardItemsViewModelSlice.onRefresh() - accountDataViewModelSlice.onRefresh() + selectedSiteRepository.getSelectedSite()?.let { + if (shouldShowDashboard(it)) { + dashboardCardsViewModelSlice.onRefresh(it) + dashboardItemsViewModelSlice.onRefresh() + } else { + accountDataViewModelSlice.onRefresh() + } + } } fun onResume() { @@ -270,7 +275,7 @@ class MySiteViewModel @Inject constructor( // bloggingPromptCardViewModelSlice.onResume(uiModel.value as? SiteSelected) // dashboardCardPlansUtils.onResume(uiModel.value as? SiteSelected) selectedSiteRepository.getSelectedSite()?.let { - dashboardCardsViewModelSlice.onResume() + dashboardCardsViewModelSlice.onResume(it) dashboardItemsViewModelSlice.onResume() siteInfoHeaderCardViewModelSlice.onResume() }?: run { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index ff52f290225c..2125423892cb 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -177,11 +177,9 @@ class DashboardCardsViewModelSlice @Inject constructor( quickStartCardViewModelSlice.build(site) } - fun onResume() { - selectedSiteRepository.getSelectedSite()?.let { - if(showDashboardCards(it))buildCards(it) - else uiModel.postValue(emptyList()) - } + fun onResume(site: SiteModel) { + if (showDashboardCards(site)) buildCards(site) + else uiModel.postValue(emptyList()) } fun onSiteChanged() { @@ -191,11 +189,9 @@ class DashboardCardsViewModelSlice @Inject constructor( } } - fun onRefresh() { - selectedSiteRepository.getSelectedSite()?.let { - if(showDashboardCards(it))buildCards(it) - else uiModel.postValue(emptyList()) - } + fun onRefresh(site: SiteModel) { + if (showDashboardCards(site)) buildCards(site) + else uiModel.postValue(emptyList()) } fun onCleared() { From b66b9f0b331f6b82d15fa70e187fa0d4021f18df Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 5 Feb 2024 13:29:11 +0530 Subject: [PATCH 162/250] =?UTF-8?q?=E2=86=91=20Updates:=20DashboardItemsVi?= =?UTF-8?q?ewModelSlice=20implementation=20to=20use=20site=20model?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/ui/mysite/MySiteViewModel.kt | 4 ++-- .../items/DashboardItemsViewModelSlice.kt | 18 +++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 53c85a48dcb3..15bb86575d35 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -260,7 +260,7 @@ class MySiteViewModel @Inject constructor( selectedSiteRepository.getSelectedSite()?.let { if (shouldShowDashboard(it)) { dashboardCardsViewModelSlice.onRefresh(it) - dashboardItemsViewModelSlice.onRefresh() + dashboardItemsViewModelSlice.onRefresh(it) } else { accountDataViewModelSlice.onRefresh() } @@ -276,7 +276,7 @@ class MySiteViewModel @Inject constructor( // dashboardCardPlansUtils.onResume(uiModel.value as? SiteSelected) selectedSiteRepository.getSelectedSite()?.let { dashboardCardsViewModelSlice.onResume(it) - dashboardItemsViewModelSlice.onResume() + dashboardItemsViewModelSlice.onResume(it) siteInfoHeaderCardViewModelSlice.onResume() }?: run { accountDataViewModelSlice.onResume() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt index b24d657bf8b9..711d00d2c391 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt @@ -71,7 +71,7 @@ class DashboardItemsViewModelSlice @Inject constructor( siteItems: List?, sotw2023NudgeCard: MySiteCardAndItem.Card.WpSotw2023NudgeCardModel? ): List { - val dasbhboardSiteItems = mutableListOf().apply { + val dasbhboardSiteItems = mutableListOf().apply { sotw2023NudgeCard?.let { add(it) } siteItems?.let { addAll(siteItems) } jetpackSwitchMenu?.let { add(jetpackSwitchMenu) } @@ -83,18 +83,14 @@ class DashboardItemsViewModelSlice @Inject constructor( return dasbhboardSiteItems } - fun onResume() { - selectedSiteRepository.getSelectedSite()?.let { site -> - if(shouldShowSiteItems(site)) buildCards(site) - else uiModel.postValue(emptyList()) - } + fun onResume(site: SiteModel) { + if (shouldShowSiteItems(site)) buildCards(site) + else uiModel.postValue(emptyList()) } - fun onRefresh() { - selectedSiteRepository.getSelectedSite()?.let { site -> - if(shouldShowSiteItems(site)) buildCards(site) - else uiModel.postValue(emptyList()) - } + fun onRefresh(site: SiteModel) { + if (shouldShowSiteItems(site)) buildCards(site) + else uiModel.postValue(emptyList()) } private fun buildCards(site: SiteModel) { From 770f9f83d96d6d62f37745929c7adb0d40e756a5 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 5 Feb 2024 13:34:18 +0530 Subject: [PATCH 163/250] - Removes: Selected site repository from DashboardItemsViewModelSlice --- .../android/ui/mysite/items/DashboardItemsViewModelSlice.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt index 711d00d2c391..c442ad7ab04f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt @@ -7,7 +7,6 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.mysite.MySiteCardAndItem -import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardHelper import org.wordpress.android.ui.mysite.cards.sotw2023.WpSotw2023NudgeCardViewModelSlice import org.wordpress.android.ui.mysite.items.jetpackBadge.JetpackBadgeViewModelSlice @@ -25,7 +24,6 @@ class DashboardItemsViewModelSlice @Inject constructor( private val siteItemsViewModelSlice: SiteItemsViewModelSlice, private val sotw2023NudgeCardViewModelSlice: WpSotw2023NudgeCardViewModelSlice, private val jetpackFeatureCardHelper: JetpackFeatureCardHelper, - private val selectedSiteRepository: SelectedSiteRepository, private val buildConfigWrapper: BuildConfigWrapper ) { private lateinit var scope: CoroutineScope From 31a3c11192506228a27a975caf758e88f1a00610 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 5 Feb 2024 13:36:19 +0530 Subject: [PATCH 164/250] * Fixes: Unit tests * Fixes: Unit tests in DashboardCardsViewModelSliceTest and DashboardItemsViewModelSliceTest.kt --- .../ui/mysite/DashboardCardsViewModelSliceTest.kt | 14 +++++--------- .../ui/mysite/DashboardItemsViewModelSliceTest.kt | 13 ++++--------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt index 9ec4365e3473..888e33382954 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt @@ -3,12 +3,12 @@ package org.wordpress.android.ui.mysite import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.isActive +import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner -import org.assertj.core.api.Assertions.assertThat import org.mockito.kotlin.atMost import org.mockito.kotlin.clearInvocations import org.mockito.kotlin.mock @@ -118,10 +118,9 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { val mockSite = mock() whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onResume() + dashboardCardsViewModelSlice.onResume(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() @@ -141,10 +140,9 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { val mockSite = mock() whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onResume() + dashboardCardsViewModelSlice.onResume(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() @@ -164,10 +162,9 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { val mockSite = mock() whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onRefresh() + dashboardCardsViewModelSlice.onRefresh(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() @@ -187,10 +184,9 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { val mockSite = mock() whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onRefresh() + dashboardCardsViewModelSlice.onRefresh(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt index 1f5a99f36d1f..1d6ef40a7a11 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt @@ -76,7 +76,6 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { siteItemsViewModelSlice, sotw2023NudgeCardViewModelSlice, jetpackFeatureCardHelper, - selectedSiteRepository, buildConfigWrapper ) @@ -110,10 +109,9 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { val mockSite = mock() whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardItemsViewModelSlice.initialize(testScope()) - dashboardItemsViewModelSlice.onResume() + dashboardItemsViewModelSlice.onResume(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(siteItemsViewModelSlice, never()).buildSiteItems(any()) @@ -125,11 +123,10 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { val mockSite = mock() whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) whenever(mockSite.isUsingWpComRestApi).thenReturn(false) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardItemsViewModelSlice.initialize(testScope()) - dashboardItemsViewModelSlice.onResume() + dashboardItemsViewModelSlice.onResume(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(siteItemsViewModelSlice, atLeastOnce()).buildSiteItems(any()) @@ -145,10 +142,9 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { val mockSite = mock() whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardItemsViewModelSlice.initialize(testScope()) - dashboardItemsViewModelSlice.onRefresh() + dashboardItemsViewModelSlice.onRefresh(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(siteItemsViewModelSlice, never()).buildSiteItems(any()) @@ -160,11 +156,10 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { val mockSite = mock() whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) whenever(mockSite.isUsingWpComRestApi).thenReturn(false) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardItemsViewModelSlice.initialize(testScope()) - dashboardItemsViewModelSlice.onRefresh() + dashboardItemsViewModelSlice.onRefresh(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(siteItemsViewModelSlice, atLeastOnce()).buildSiteItems(any()) From 657682cd90d41518c39f592c6d1beed66e2b40b7 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Tue, 6 Feb 2024 13:11:10 +0530 Subject: [PATCH 165/250] [WIP] : Fixes some of the unit tests in QuickStartCardViewModelSlice Some of the tests were checking the active quick start value which is not needed in the QuickStartCardViewModelSliceTest anymore as that logic is already tested in QuickStartRepositoryTest --- .../QuickStartCardViewModelSliceTest.kt | 203 ++++++------------ 1 file changed, 63 insertions(+), 140 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt index 7f54f1cc107a..a0fbdf6a2d02 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt @@ -8,11 +8,9 @@ import org.mockito.Mock import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.verify -import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.Dispatcher -import org.wordpress.android.fluxc.model.SiteHomepageSettings.ShowOnFront import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.QuickStartStore import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartNewSiteTask.CREATE_SITE @@ -22,16 +20,12 @@ import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartNewSiteTask.U import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTask import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTaskType.CUSTOMIZE import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTaskType.GROW -import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.QuickStartUpdate +import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker import org.wordpress.android.ui.pages.SnackbarMessageHolder import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.quickstart.QuickStartMySitePrompts -import org.wordpress.android.ui.quickstart.QuickStartTaskDetails -import org.wordpress.android.ui.quickstart.QuickStartTaskDetails.CREATE_SITE_TUTORIAL -import org.wordpress.android.ui.quickstart.QuickStartTaskDetails.PUBLISH_POST_TUTORIAL -import org.wordpress.android.ui.quickstart.QuickStartTaskDetails.SHARE_SITE_TUTORIAL import org.wordpress.android.ui.quickstart.QuickStartTracker import org.wordpress.android.ui.quickstart.QuickStartType.NewSiteQuickStartType import org.wordpress.android.ui.utils.HtmlMessageUtils @@ -41,6 +35,8 @@ import org.wordpress.android.util.HtmlCompatWrapper import org.wordpress.android.util.QuickStartUtilsWrapper import org.wordpress.android.viewmodel.ContextProvider import org.wordpress.android.viewmodel.ResourceProvider +import kotlin.test.assertNotNull +import kotlin.test.assertNull @ExperimentalCoroutinesApi class QuickStartCardViewModelSliceTest : BaseUnitTest() { @@ -93,7 +89,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { private lateinit var snackbars: MutableList private lateinit var quickStartPrompts: MutableList - private lateinit var result: MutableList + private lateinit var result: MutableList private val siteLocalId = 1 private val quickStartType = NewSiteQuickStartType @@ -104,7 +100,9 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { site = SiteModel() site.id = siteLocalId whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) - whenever(appPrefsWrapper.getLastSelectedQuickStartTypeForSite(any())).thenReturn(NewSiteQuickStartType) + whenever(appPrefsWrapper.getLastSelectedQuickStartTypeForSite(any())).thenReturn( + NewSiteQuickStartType + ) whenever(quickStartUtilsWrapper.isQuickStartAvailableForTheSite(site)).thenReturn(true) quickStartRepository = QuickStartRepository( testDispatcher(), @@ -144,15 +142,17 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { isRefreshing = mutableListOf() mQuickStartCardViewModelSlice.isRefreshing.observeForever { isRefreshing.add(it) } + + mQuickStartCardViewModelSlice.initialize(testScope()) } @Test fun `refresh loads model`() = test { initStore() - mQuickStartCardViewModelSlice.refresh() + mQuickStartCardViewModelSlice.build(site) + - assertModel() } @Test @@ -162,27 +162,29 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { triggerQSRefreshAfterSameTypeTasksAreComplete() - assertThat(result.last().categories.map { it.taskType }).isEqualTo(listOf(CUSTOMIZE, GROW)) + assertThat(result.last()?.taskTypeItems?.map { it.quickStartTaskType }).contains( + CUSTOMIZE, + GROW + ) } @Test fun `start marks CREATE_SITE as done and loads model`() = test { initStore() - mQuickStartCardViewModelSlice.build(testScope(), site.id) - mQuickStartCardViewModelSlice.refresh() + mQuickStartCardViewModelSlice.build(site) - assertModel() + assertThat(result.last()?.quickStartCardType).isEqualTo(QuickStartCardType.GET_TO_KNOW_THE_APP) } @Test fun `sets active task and shows stylized snackbar when not UPDATE_SITE_TITLE`() = test { initStore() - mQuickStartCardViewModelSlice.refresh() quickStartRepository.setActiveTask(PUBLISH_POST) + mQuickStartCardViewModelSlice.build(site) - assertThat(result.last().activeTask).isEqualTo(PUBLISH_POST) + assertThat(result.last()?.taskTypeItems?.last()).isEqualTo(PUBLISH_POST) assertThat(quickStartPrompts.last()).isEqualTo(QuickStartMySitePrompts.PUBLISH_POST_TUTORIAL) } @@ -190,24 +192,21 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { fun `completeTask marks current active task as done and refreshes model`() = test { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) initStore() - mQuickStartCardViewModelSlice.refresh() + mQuickStartCardViewModelSlice.build(site) val task = PUBLISH_POST quickStartRepository.setActiveTask(task) - quickStartRepository.completeTask(task) verify(quickStartStore).setDoneTask(siteLocalId.toLong(), task, true) - val update = result.last() - assertThat(update.activeTask).isNull() - assertThat(update.categories).isNotEmpty + assertNull(result.last()) } @Test fun `completeTask marks current pending task as done and refreshes model`() = test { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) initStore() - mQuickStartCardViewModelSlice.refresh() + mQuickStartCardViewModelSlice.build(site) val task = PUBLISH_POST quickStartRepository.setActiveTask(task) @@ -215,101 +214,30 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { quickStartRepository.completeTask(task) verify(quickStartStore).setDoneTask(siteLocalId.toLong(), task, true) - val update = result.last() - assertThat(update.activeTask).isNull() - assertThat(update.categories).isNotEmpty - } - - @Test - fun `requestNextStepOfTask clears current active task`() = test { - initQuickStartInProgress() - - quickStartRepository.setActiveTask(QuickStartStore.QuickStartNewSiteTask.FOLLOW_SITE) - quickStartRepository.requestNextStepOfTask(QuickStartStore.QuickStartNewSiteTask.FOLLOW_SITE) - - val update = result.last() - assertThat(update.activeTask).isNull() - } - - @Test - fun `requestNextStepOfTask does not proceed if the active task is different`() = test { - initQuickStartInProgress() - - quickStartRepository.setActiveTask(PUBLISH_POST) - quickStartRepository.requestNextStepOfTask(ENABLE_POST_SHARING) - - verifyNoInteractions(eventBus) - val update = result.last() - assertThat(update.activeTask).isEqualTo(PUBLISH_POST) - } - - @Test - fun `clearActiveTask clears current active task`() = test { - initQuickStartInProgress() - - quickStartRepository.setActiveTask(ENABLE_POST_SHARING) - quickStartRepository.clearActiveTask() - - val update = result.last() - assertThat(update.activeTask).isNull() + assertNull(result.last()) } @Test - fun `given uncompleted task, when quick start notice button action is clicked, then the task is marked active`() = + fun `given quick start available for site, when source is refreshed, then non empty categories returned`() = test { - initStore(nextUncompletedTask = PUBLISH_POST) - quickStartRepository.checkAndShowQuickStartNotice() + whenever(quickStartUtilsWrapper.isQuickStartAvailableForTheSite(site)).thenReturn(true) + initStore() - snackbars.last().buttonAction.invoke() + mQuickStartCardViewModelSlice.build(site) - assertThat(result.last().activeTask).isEqualTo(PUBLISH_POST) + assertNotNull(result.last()) } @Test - fun `when source is invoked, then refresh is false`() = test { - initBuild() - - assertThat(isRefreshing.last()).isFalse - } - - @Test - fun `when data has been refreshed, then refresh is set to false`() = test { - initStore() - - val updatedSiteId = 2 - site.id = updatedSiteId - site.showOnFront = ShowOnFront.POSTS.value - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) - mQuickStartCardViewModelSlice.refresh.observeForever { isRefreshing.add(it) } - - mQuickStartCardViewModelSlice.build(testScope(), site.id) - - mQuickStartCardViewModelSlice.refresh() - - assertThat(isRefreshing.last()).isFalse - } - - @Test - fun `given quick start available for site, when source is refreshed, then non empty categories returned`() = test { - whenever(quickStartUtilsWrapper.isQuickStartAvailableForTheSite(site)).thenReturn(true) - initStore() - - mQuickStartCardViewModelSlice.refresh() - - val update = result.last() - assertThat(update.categories).isNotEmpty - } - - @Test - fun `given quick start not available for site, when source is refreshed, then empty categories returned`() = test { - whenever(quickStartUtilsWrapper.isQuickStartAvailableForTheSite(site)).thenReturn(false) - initStore() + fun `given quick start not available for site, when source is refreshed, then empty categories returned`() = + test { + whenever(quickStartUtilsWrapper.isQuickStartAvailableForTheSite(site)).thenReturn(false) + initStore() - mQuickStartCardViewModelSlice.refresh() + mQuickStartCardViewModelSlice.build(site) - val update = result.last() - assertThat(update.categories).isEmpty() - } + assertNull(result.last()) + } private fun triggerQSRefreshAfterSameTypeTasksAreComplete() { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) @@ -317,26 +245,36 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { val task = PUBLISH_POST quickStartRepository.setActiveTask(task) quickStartRepository.completeTask(task) - mQuickStartCardViewModelSlice.refresh() - } - - private suspend fun initQuickStartInProgress() { - initStore() - mQuickStartCardViewModelSlice.refresh() + mQuickStartCardViewModelSlice.build(site) } private suspend fun initStore( nextUncompletedTask: QuickStartTask? = null ) { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) - whenever(quickStartType.isQuickStartInProgress(quickStartStore, siteLocalId.toLong())).thenReturn(true) + whenever( + quickStartType.isQuickStartInProgress( + quickStartStore, + siteLocalId.toLong() + ) + ).thenReturn(true) whenever(appPrefsWrapper.isQuickStartNoticeRequired()).thenReturn(true) - whenever(quickStartStore.getUncompletedTasksByType(siteLocalId.toLong(), CUSTOMIZE)).thenReturn( + whenever( + quickStartStore.getUncompletedTasksByType( + siteLocalId.toLong(), + CUSTOMIZE + ) + ).thenReturn( listOf( CREATE_SITE ) ) - whenever(quickStartStore.getCompletedTasksByType(siteLocalId.toLong(), CUSTOMIZE)).thenReturn( + whenever( + quickStartStore.getCompletedTasksByType( + siteLocalId.toLong(), + CUSTOMIZE + ) + ).thenReturn( listOf( UPDATE_SITE_TITLE ) @@ -347,34 +285,19 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { GROW ) ).thenReturn(listOf(ENABLE_POST_SHARING)) - whenever(quickStartStore.getCompletedTasksByType(siteLocalId.toLong(), GROW)).thenReturn(listOf(PUBLISH_POST)) - whenever(quickStartUtilsWrapper.getNextUncompletedQuickStartTask(quickStartType, siteLocalId.toLong())) + whenever(quickStartStore.getCompletedTasksByType(siteLocalId.toLong(), GROW)).thenReturn( + listOf(PUBLISH_POST) + ) + whenever( + quickStartUtilsWrapper.getNextUncompletedQuickStartTask( + quickStartType, + siteLocalId.toLong() + ) + ) .thenReturn(nextUncompletedTask) whenever(htmlMessageUtils.getHtmlMessageFromStringFormat(anyOrNull())).thenReturn("") whenever(resourceProvider.getString(any())).thenReturn("") whenever(resourceProvider.getString(any(), any())).thenReturn("") whenever(htmlCompat.fromHtml(any(), any())).thenReturn(" ") - initBuild() - } - - private fun initBuild() { - mQuickStartCardViewModelSlice.build(siteLocalId) - } - - private fun assertModel() { - val quickStartUpdate = result.last() - quickStartUpdate.categories.let { categories -> - assertThat(categories).hasSize(2) - assertThat(categories[0].taskType).isEqualTo(CUSTOMIZE) - assertThat(categories[0].uncompletedTasks).containsExactly(CREATE_SITE_TUTORIAL) - assertThat(categories[0].completedTasks).containsExactly(QuickStartTaskDetails.UPDATE_SITE_TITLE) - assertThat(categories[1].taskType).isEqualTo(GROW) - assertThat(categories[1].uncompletedTasks).containsExactly(SHARE_SITE_TUTORIAL) - assertThat(categories[1].completedTasks).containsExactly(PUBLISH_POST_TUTORIAL) - } - } - - companion object { - const val ALL_TASKS_COMPLETED_MESSAGE = "All tasks completed!" } } From 6d4d11cf3cb3c5bcec70aef9bf6c021ea1441e9a Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Tue, 6 Feb 2024 13:18:40 +0530 Subject: [PATCH 166/250] =?UTF-8?q?=E2=86=91=20Updates:=20the=20on=20site?= =?UTF-8?q?=20picked=20logic=20in=20my=20site=20viewmodel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates the logic to call the VM slices on site changed and pass the site --- .../android/ui/mysite/MySiteViewModel.kt | 11 ++++++++--- .../mysite/cards/DashboardCardsViewModelSlice.kt | 8 +++----- .../siteinfo/SiteInfoHeaderCardViewModelSlice.kt | 11 ++++++----- .../mysite/items/DashboardItemsViewModelSlice.kt | 5 +++++ .../mysite/DashboardCardsViewModelSliceTest.kt | 4 ++-- .../SiteInfoHeaderCardViewModelSliceTest.kt | 16 +--------------- 6 files changed, 25 insertions(+), 30 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 15bb86575d35..34883aaf4583 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -163,7 +163,6 @@ class MySiteViewModel @Inject constructor( val state: LiveData = selectedSiteRepository.siteSelected.switchMap { _ -> isSiteSelected = true - dashboardCardsViewModelSlice.onSiteChanged() resetShownTrackers() val result = MediatorLiveData() @@ -277,8 +276,8 @@ class MySiteViewModel @Inject constructor( selectedSiteRepository.getSelectedSite()?.let { dashboardCardsViewModelSlice.onResume(it) dashboardItemsViewModelSlice.onResume(it) - siteInfoHeaderCardViewModelSlice.onResume() - }?: run { + siteInfoHeaderCardViewModelSlice.onResume(it) + } ?: run { accountDataViewModelSlice.onResume() } } @@ -374,9 +373,15 @@ class MySiteViewModel @Inject constructor( val siteLocalId = it.id.toLong() val lastSelectedQuickStartType = appPrefsWrapper.getLastSelectedQuickStartTypeForSite(siteLocalId) quickStartRepository.checkAndSetQuickStartType(lastSelectedQuickStartType == NewSiteQuickStartType) + dashboardCardsViewModelSlice.onSiteChanged(it) + dashboardItemsViewModelSlice.onSiteChanged(it) + siteInfoHeaderCardViewModelSlice.onSiteChanged(it) + } ?: run { + accountDataViewModelSlice.onResume() } } + fun performFirstStepAfterSiteCreation( isSiteTitleTaskCompleted: Boolean, isNewSite: Boolean diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 2125423892cb..11a295c6d3d9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -182,11 +182,9 @@ class DashboardCardsViewModelSlice @Inject constructor( else uiModel.postValue(emptyList()) } - fun onSiteChanged() { - selectedSiteRepository.getSelectedSite()?.let { - if(showDashboardCards(it))buildCards(it) - else uiModel.postValue(emptyList()) - } + fun onSiteChanged(site: SiteModel) { + if (showDashboardCards(site)) buildCards(site) + else uiModel.postValue(emptyList()) } fun onRefresh(site: SiteModel) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt index 8c7950511365..7baac24dfd33 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt @@ -83,11 +83,12 @@ class SiteInfoHeaderCardViewModelSlice @Inject constructor( this.scope = viewModelScope } - fun onResume() { - val selectedSite = selectedSiteRepository.getSelectedSite() - if (selectedSite != null) { - buildCard(null, null, siteModel = selectedSite) - } + fun onResume(siteModel: SiteModel) { + buildCard(null, null, siteModel = siteModel) + } + + fun onSiteChanged(siteModel: SiteModel) { + buildCard(null, null, siteModel = siteModel) } private fun buildCard( diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt index c442ad7ab04f..87539b7c9954 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt @@ -86,6 +86,11 @@ class DashboardItemsViewModelSlice @Inject constructor( else uiModel.postValue(emptyList()) } + fun onSiteChanged(site: SiteModel) { + if (shouldShowSiteItems(site)) buildCards(site) + else uiModel.postValue(emptyList()) + } + fun onRefresh(site: SiteModel) { if (shouldShowSiteItems(site)) buildCards(site) else uiModel.postValue(emptyList()) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt index 888e33382954..93810fcd93ae 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt @@ -209,7 +209,7 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onSiteChanged() + dashboardCardsViewModelSlice.onSiteChanged(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() @@ -232,7 +232,7 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onSiteChanged() + dashboardCardsViewModelSlice.onSiteChanged(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt index 140cb17f4862..165bb53f6883 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt @@ -13,7 +13,6 @@ import org.mockito.kotlin.clearInvocations import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.verify -import org.mockito.kotlin.verifyNoInteractions import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.R @@ -466,17 +465,6 @@ class SiteInfoHeaderCardViewModelSliceTest : BaseUnitTest() { verify(quickStartRepository).checkAndShowQuickStartNotice() } - @Test - fun `when selectedSite is null, then card is not built`() { - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(null) - - clearInvocations(siteInfoHeaderCardBuilder) - - viewModelSlice.onResume() - - verifyNoInteractions(siteInfoHeaderCardBuilder) - } - @Test fun `when selectedSite is not null, then card is built`() { val siteModel = mock().apply { @@ -485,11 +473,9 @@ class SiteInfoHeaderCardViewModelSliceTest : BaseUnitTest() { url = "https://site.wordpress.com" } - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(siteModel) - clearInvocations(siteInfoHeaderCardBuilder) - viewModelSlice.onResume() + viewModelSlice.onResume(siteModel) verify(siteInfoHeaderCardBuilder).buildSiteInfoCard(any()) } From c9850df7c27f9a12a777d973d865d053c2d7df39 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Tue, 6 Feb 2024 15:05:53 +0530 Subject: [PATCH 167/250] + Adds: a clear value and should build card check + Adds: a check to clear or build items based on whether the site is self hosted or not. If the items are not cleared on child level then the ui model still retains the previous values and passes to the parent VM Slice --- .../ui/mysite/BlazeCardViewModelSlice.kt | 4 + .../android/ui/mysite/MySiteViewModel.kt | 31 +++++--- .../cards/DashboardCardsViewModelSlice.kt | 77 +++++++++++-------- .../cards/dashboard/CardViewModelSlice.kt | 8 +- .../BloganuaryNudgeCardViewModelSlice.kt | 4 + .../BloggingPromptCardViewModelSlice.kt | 4 + ...packInstallFullPluginCardViewModelSlice.kt | 4 + .../JpMigrationSuccessCardViewModelSlice.kt | 4 + .../PersonalizeCardViewModelSlice.kt | 8 +- .../cards/plans/PlansCardViewModelSlice.kt | 4 + .../QuickLinksItemViewModelSlice.kt | 6 +- .../QuickStartCardViewModelSlice.kt | 49 +++++++----- .../SiteInfoHeaderCardViewModelSlice.kt | 6 +- .../WpSotw2023NudgeCardViewModelSlice.kt | 4 + .../items/DashboardItemsViewModelSlice.kt | 60 +++++++-------- .../JetpackBadgeViewModelSlice.kt | 4 + .../JetpackSwitchMenuViewModelSlice.kt | 6 +- .../JetpackFeatureCardViewModelSlice.kt | 4 + .../items/listitem/SiteItemsViewModelSlice.kt | 8 +- 19 files changed, 184 insertions(+), 111 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSlice.kt index 05521b1e8b84..b87296f5c8fc 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSlice.kt @@ -245,6 +245,10 @@ class BlazeCardViewModelSlice @Inject constructor( _onNavigation.value = Event(SiteNavigationAction.OpenPromoteWithBlazeOverlay(source = BlazeFlowSource.DASHBOARD_CARD)) } + + fun clearValue() { + _uiModel.postValue(null) + } } enum class CampaignCardMenuItem(val label: String) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 34883aaf4583..2d7bf3161f0e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -258,8 +258,7 @@ class MySiteViewModel @Inject constructor( if (isPullToRefresh) analyticsTrackerWrapper.track(Stat.MY_SITE_PULL_TO_REFRESH) selectedSiteRepository.getSelectedSite()?.let { if (shouldShowDashboard(it)) { - dashboardCardsViewModelSlice.onRefresh(it) - dashboardItemsViewModelSlice.onRefresh(it) + buildDashboardOrSiteItems(it) } else { accountDataViewModelSlice.onRefresh() } @@ -274,9 +273,7 @@ class MySiteViewModel @Inject constructor( // bloggingPromptCardViewModelSlice.onResume(uiModel.value as? SiteSelected) // dashboardCardPlansUtils.onResume(uiModel.value as? SiteSelected) selectedSiteRepository.getSelectedSite()?.let { - dashboardCardsViewModelSlice.onResume(it) - dashboardItemsViewModelSlice.onResume(it) - siteInfoHeaderCardViewModelSlice.onResume(it) + buildDashboardOrSiteItems(it) } ?: run { accountDataViewModelSlice.onResume() } @@ -373,9 +370,7 @@ class MySiteViewModel @Inject constructor( val siteLocalId = it.id.toLong() val lastSelectedQuickStartType = appPrefsWrapper.getLastSelectedQuickStartTypeForSite(siteLocalId) quickStartRepository.checkAndSetQuickStartType(lastSelectedQuickStartType == NewSiteQuickStartType) - dashboardCardsViewModelSlice.onSiteChanged(it) - dashboardItemsViewModelSlice.onSiteChanged(it) - siteInfoHeaderCardViewModelSlice.onSiteChanged(it) + buildDashboardOrSiteItems(it) } ?: run { accountDataViewModelSlice.onResume() } @@ -448,9 +443,12 @@ class MySiteViewModel @Inject constructor( } fun startQuickStart() { - quickStartTracker.track(Stat.QUICK_START_REQUEST_DIALOG_POSITIVE_TAPPED) - startQuickStart(selectedSiteRepository.getSelectedSiteLocalId(), shouldMarkUpdateSiteTitleTaskComplete) - shouldMarkUpdateSiteTitleTaskComplete = false + selectedSiteRepository.getSelectedSite()?.let { + dashboardCardsViewModelSlice.startQuickStart(it) + quickStartTracker.track(Stat.QUICK_START_REQUEST_DIALOG_POSITIVE_TAPPED) + startQuickStart(selectedSiteRepository.getSelectedSiteLocalId(), shouldMarkUpdateSiteTitleTaskComplete) + shouldMarkUpdateSiteTitleTaskComplete = false + } } fun ignoreQuickStart() { @@ -458,6 +456,17 @@ class MySiteViewModel @Inject constructor( quickStartTracker.track(Stat.QUICK_START_REQUEST_DIALOG_NEGATIVE_TAPPED) } + fun buildDashboardOrSiteItems(site: SiteModel) { + siteInfoHeaderCardViewModelSlice.buildCard(site) + if(shouldShowDashboard(site)) { + dashboardCardsViewModelSlice.buildCards(site) + dashboardItemsViewModelSlice.clearValue() + } else { + dashboardItemsViewModelSlice.buildItems(site) + dashboardCardsViewModelSlice.clearValue() + } + } + private fun onDashboardErrorRetry() { // mySiteSourceManager.refresh() } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 11a295c6d3d9..1d04d6d124f3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -21,7 +21,6 @@ import org.wordpress.android.ui.mysite.cards.plans.PlansCardViewModelSlice import org.wordpress.android.ui.mysite.cards.quicklinksitem.QuickLinksItemViewModelSlice import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardViewModelSlice import org.wordpress.android.ui.pages.SnackbarMessageHolder -import org.wordpress.android.util.BuildConfigWrapper import org.wordpress.android.util.merge import org.wordpress.android.viewmodel.Event import javax.inject.Inject @@ -39,8 +38,7 @@ class DashboardCardsViewModelSlice @Inject constructor( private val quickLinksItemViewModelSlice: QuickLinksItemViewModelSlice, private val bloganuaryNudgeCardViewModelSlice: BloganuaryNudgeCardViewModelSlice, private val plansCardViewModelSlice: PlansCardViewModelSlice, - private val selectedSiteRepository: SelectedSiteRepository, - private val buildConfigWrapper: BuildConfigWrapper + private val selectedSiteRepository: SelectedSiteRepository ) { private lateinit var scope: CoroutineScope @@ -54,6 +52,8 @@ class DashboardCardsViewModelSlice @Inject constructor( val onOpenJetpackInstallFullPluginOnboarding = jetpackInstallFullPluginCardViewModelSlice.onOpenJetpackInstallFullPluginOnboarding + var shouldShowDashboard: Boolean = false + val onNavigation = merge( blazeCardViewModelSlice.onNavigation, cardViewModelSlice.onNavigation, @@ -133,23 +133,31 @@ class DashboardCardsViewModelSlice @Inject constructor( domainRegistrationCard: MySiteCardAndItem.Card.DomainRegistrationCard?, ): List { val cards = mutableListOf() - quicklinks?.let { cards.add(it) } - quickStart?.let { cards.add(it) } - domainRegistrationCard?.let { cards.add(it) } - bloganuaryNudgeCard?.let { cards.add(it) } - bloggingPromptCard?.let { cards.add(it) } - blazeCard?.let { cards.add(it) } - cardsState?.let { - when (cardsState) { - is CardsState.Success -> cards.addAll(cardsState.cards) - is CardsState.ErrorState -> cards.add(cardsState.error) + if(shouldShowDashboard) { + quicklinks?.let { cards.add(it) } + quickStart?.let { cards.add(it) } + domainRegistrationCard?.let { cards.add(it) } + bloganuaryNudgeCard?.let { cards.add(it) } + bloggingPromptCard?.let { cards.add(it) } + blazeCard?.let { cards.add(it) } + cardsState?.let { + when (cardsState) { + is CardsState.Success -> cards.addAll(cardsState.cards) + is CardsState.ErrorState -> cards.add(cardsState.error) + } + } + migrationSuccessCard?.let { cards.add(it) } + plansCard?.let { cards.add(it) } + jpFullInstallFullPlugin?.let { cards.add(it) } + // when clearing the values of all child VM Slices, + // the no cards message will still be shown and hence we need to check if the personalize card + // is shown or not, if the personalize card is not shown, then it means that + // we are not showing dashboard at all + personalizeCard?.let { + noCardsMessageViewModelSlice.buildNoCardsMessage(cards)?.let { cards.add(it) } + cards.add(it) } } - migrationSuccessCard?.let { cards.add(it) } - plansCard?.let { cards.add(it) } - jpFullInstallFullPlugin?.let { cards.add(it) } - noCardsMessageViewModelSlice.buildNoCardsMessage(cards)?.let { cards.add(it) } - personalizeCard?.let { cards.add(it) } return cards.toList() } @@ -164,7 +172,8 @@ class DashboardCardsViewModelSlice @Inject constructor( quickStartCardViewModelSlice.initialize(scope) } - private fun buildCards(site: SiteModel) { + fun buildCards(site: SiteModel) { + shouldShowDashboard = true jpMigrationSuccessCardViewModelSlice.buildCard() jetpackInstallFullPluginCardViewModelSlice.buildCard(site) blazeCardViewModelSlice.buildCard(site) @@ -177,19 +186,20 @@ class DashboardCardsViewModelSlice @Inject constructor( quickStartCardViewModelSlice.build(site) } - fun onResume(site: SiteModel) { - if (showDashboardCards(site)) buildCards(site) - else uiModel.postValue(emptyList()) - } - - fun onSiteChanged(site: SiteModel) { - if (showDashboardCards(site)) buildCards(site) - else uiModel.postValue(emptyList()) - } - fun onRefresh(site: SiteModel) { - if (showDashboardCards(site)) buildCards(site) - else uiModel.postValue(emptyList()) + fun clearValue() { + shouldShowDashboard = false + jpMigrationSuccessCardViewModelSlice.clearValue() + jetpackInstallFullPluginCardViewModelSlice.clearValue() + blazeCardViewModelSlice.clearValue() + bloggingPromptCardViewModelSlice.clearValue() + bloganuaryNudgeCardViewModelSlice.clearValue() + personalizeCardViewModelSlice.clearValue() + quickLinksItemViewModelSlice.clearValue() + plansCardViewModelSlice.clearValue() + cardViewModelSlice.clearValue() + quickStartCardViewModelSlice.clearValue() + uiModel.postValue(emptyList()) } fun onCleared() { @@ -211,6 +221,7 @@ class DashboardCardsViewModelSlice @Inject constructor( // quickStartTracker.resetShown() } - private fun showDashboardCards(site: SiteModel) = - site.isUsingWpComRestApi && buildConfigWrapper.isJetpackApp + fun startQuickStart(siteModel: SiteModel) { + quickStartCardViewModelSlice.build(siteModel) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt index 7a8e22e33b25..23d47d274450 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt @@ -57,8 +57,8 @@ class CardViewModelSlice @Inject constructor( private val _isRefreshing = MutableLiveData() val isRefreshing: LiveData = _isRefreshing - private val _uiModel = MutableLiveData() - val uiModel: LiveData = _uiModel.distinctUntilChanged() + private val _uiModel = MutableLiveData() + val uiModel: LiveData = _uiModel.distinctUntilChanged() private val _onNavigation = MutableLiveData>() val onNavigation = merge( @@ -242,6 +242,10 @@ class CardViewModelSlice @Inject constructor( _uiModel.postValue(CardsState.Success(result)) } } + + fun clearValue() { + _uiModel.postValue(null) + } } sealed class CardsState { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloganuary/BloganuaryNudgeCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloganuary/BloganuaryNudgeCardViewModelSlice.kt index 65dec2d28ec8..8fdf55088265 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloganuary/BloganuaryNudgeCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloganuary/BloganuaryNudgeCardViewModelSlice.kt @@ -95,4 +95,8 @@ class BloganuaryNudgeCardViewModelSlice @Inject constructor( _uiModel.postValue(null) } } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index 79b5ce045c8a..25fb804e8bcf 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -260,4 +260,8 @@ class BloggingPromptCardViewModelSlice @Inject constructor( fun onResume(state: MySiteViewModel.State.SiteSelected?) { bloggingPromptsCardTrackHelper.onResume(state) } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt index e91b446358b8..c0ac1b712682 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt @@ -69,4 +69,8 @@ class JetpackInstallFullPluginCardViewModelSlice @Inject constructor( return site.id != 0 && !appPrefsWrapper.getShouldHideJetpackInstallFullPluginCard(site.id) && site.isJetpackIndividualPluginConnectedWithoutFullPlugin() } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/migration/JpMigrationSuccessCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/migration/JpMigrationSuccessCardViewModelSlice.kt index 121e32b40384..da2749e6c268 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/migration/JpMigrationSuccessCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/migration/JpMigrationSuccessCardViewModelSlice.kt @@ -46,4 +46,8 @@ class JpMigrationSuccessCardViewModelSlice @Inject constructor( contentMigrationAnalyticsTracker.trackPleaseDeleteWordPressCardTapped() _onNavigation.value = Event(SiteNavigationAction.OpenJetpackMigrationDeleteWP) } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt index 772d2d84eeb6..35d32d4c64f6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt @@ -22,8 +22,8 @@ class PersonalizeCardViewModelSlice @Inject constructor( private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation as LiveData> - private val _uiModel = MutableLiveData() - val uiModel: LiveData = _uiModel + private val _uiModel = MutableLiveData() + val uiModel: LiveData = _uiModel fun initialize(scope: CoroutineScope) { this.scope = scope @@ -51,4 +51,8 @@ class PersonalizeCardViewModelSlice @Inject constructor( fun resetShown() { personalizeCardShownTracker.resetShown() } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/plans/PlansCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/plans/PlansCardViewModelSlice.kt index 99db481b7dc3..9b545ffcbde0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/plans/PlansCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/plans/PlansCardViewModelSlice.kt @@ -55,4 +55,8 @@ class PlansCardViewModelSlice @Inject constructor( } _uiModel.postValue(null) } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quicklinksitem/QuickLinksItemViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quicklinksitem/QuickLinksItemViewModelSlice.kt index 1ffe9f68b2d2..ffdd2c1641c0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quicklinksitem/QuickLinksItemViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quicklinksitem/QuickLinksItemViewModelSlice.kt @@ -59,7 +59,7 @@ class QuickLinksItemViewModelSlice @Inject constructor( private val _onSnackbarMessage = MutableLiveData>() val onSnackbarMessage = _onSnackbarMessage - private val _uiState = MutableLiveData() + private val _uiState = MutableLiveData() val uiState: LiveData = merge( _uiState, quickStartRepository.quickStartMenuStep @@ -268,6 +268,10 @@ class QuickLinksItemViewModelSlice @Inject constructor( activeTask == QuickStartStore.QuickStartExistingSiteTask.CHECK_STATS } + fun clearValue() { + _uiState.postValue(null) + } + data class MoreClickWithTask( val listActionType: ListItemAction, val quickStartEvent: QuickStartEvent diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt index a62ea44c2a9c..3c06f92d8657 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt @@ -26,7 +26,7 @@ class QuickStartCardViewModelSlice @Inject constructor( private val cardsTracker: CardsTracker, private val quickStartTracker: QuickStartTracker, private val quickStartCardBuilder: QuickStartCardBuilder -) { +) { private lateinit var scope: CoroutineScope private val _onNavigation = MutableLiveData>() @@ -43,7 +43,6 @@ class QuickStartCardViewModelSlice @Inject constructor( } fun build(selectedSite: SiteModel) { - val siteLocalId = selectedSite.id scope.launch { _isRefreshing.postValue(true) if (!quickStartUtilsWrapper.isQuickStartAvailableForTheSite(selectedSite)) { @@ -56,25 +55,29 @@ class QuickStartCardViewModelSlice @Inject constructor( if (selectedSite.showOnFront == ShowOnFront.POSTS.value) { _isRefreshing.postValue(true) } - val quickStartTaskTypes = quickStartRepository.getQuickStartTaskTypes() - - quickStartRepository.activeTask.value.let { _ -> - val categories = - if(quickStartRepository.quickStartType - .isQuickStartInProgress(quickStartStore, siteLocalId.toLong()) - ) { - quickStartTaskTypes.map { quickStartRepository.buildQuickStartCategory(siteLocalId, it) } - .filter { !isEmptyCategory(siteLocalId, it.taskType) } - } else { - listOf() - } - - if (shouldShowQuickStartCard(categories, selectedSite)) { - postState(categories) - } else { - postState(listOf()) - } + postQuickStartCard(selectedSite) + } + } + + private fun postQuickStartCard( + selectedSite: SiteModel + ) { + val siteLocalId = selectedSite.id + val quickStartTaskTypes = quickStartRepository.getQuickStartTaskTypes() + val categories = + if (quickStartRepository.quickStartType + .isQuickStartInProgress(quickStartStore, siteLocalId.toLong()) + ) { + quickStartTaskTypes.map { quickStartRepository.buildQuickStartCategory(siteLocalId, it) } + .filter { !isEmptyCategory(siteLocalId, it.taskType) } + } else { + listOf() } + + if (shouldShowQuickStartCard(categories, selectedSite)) { + postState(categories) + } else { + postState(listOf()) } } @@ -135,7 +138,7 @@ class QuickStartCardViewModelSlice @Inject constructor( private fun shouldShowQuickStartCard( categories: List, selectedSite: SiteModel? - ) : Boolean { + ): Boolean { selectedSite?.let { site -> return if (categories.any { it.taskType == QuickStartTaskType.GET_TO_KNOW_APP }) { quickStartRepository.shouldShowGetToKnowTheAppCard(site.siteId) @@ -154,4 +157,8 @@ class QuickStartCardViewModelSlice @Inject constructor( val unCompletedTasks = quickStartStore.getUncompletedTasksByType(siteLocalId.toLong(), taskType) return (completedTasks + unCompletedTasks).isEmpty() } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt index 7baac24dfd33..ec2b74ff8365 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt @@ -83,11 +83,7 @@ class SiteInfoHeaderCardViewModelSlice @Inject constructor( this.scope = viewModelScope } - fun onResume(siteModel: SiteModel) { - buildCard(null, null, siteModel = siteModel) - } - - fun onSiteChanged(siteModel: SiteModel) { + fun buildCard(siteModel: SiteModel) { buildCard(null, null, siteModel = siteModel) } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/sotw2023/WpSotw2023NudgeCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/sotw2023/WpSotw2023NudgeCardViewModelSlice.kt index 0cc5e97c2dac..dab700fd2656 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/sotw2023/WpSotw2023NudgeCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/sotw2023/WpSotw2023NudgeCardViewModelSlice.kt @@ -84,6 +84,10 @@ class WpSotw2023NudgeCardViewModelSlice @Inject constructor( isLanguageEligible } + fun clearValue() { + _uiModel.postValue(null) + } + companion object { private const val URL = "https://wordpress.org/state-of-the-word/" + "?utm_source=mobile&utm_medium=appnudge&utm_campaign=sotw2023" diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt index 87539b7c9954..095c86bf9931 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt @@ -13,7 +13,6 @@ import org.wordpress.android.ui.mysite.items.jetpackBadge.JetpackBadgeViewModelS import org.wordpress.android.ui.mysite.items.jetpackSwitchmenu.JetpackSwitchMenuViewModelSlice import org.wordpress.android.ui.mysite.items.jetpackfeaturecard.JetpackFeatureCardViewModelSlice import org.wordpress.android.ui.mysite.items.listitem.SiteItemsViewModelSlice -import org.wordpress.android.util.BuildConfigWrapper import org.wordpress.android.util.merge import javax.inject.Inject @@ -23,11 +22,12 @@ class DashboardItemsViewModelSlice @Inject constructor( private val jetpackBadgeViewModelSlice: JetpackBadgeViewModelSlice, private val siteItemsViewModelSlice: SiteItemsViewModelSlice, private val sotw2023NudgeCardViewModelSlice: WpSotw2023NudgeCardViewModelSlice, - private val jetpackFeatureCardHelper: JetpackFeatureCardHelper, - private val buildConfigWrapper: BuildConfigWrapper + private val jetpackFeatureCardHelper: JetpackFeatureCardHelper ) { private lateinit var scope: CoroutineScope + var shouldShowSiteItems: Boolean = false + fun initialize(scope: CoroutineScope) { this.scope = scope sotw2023NudgeCardViewModelSlice.initialize(scope) @@ -47,8 +47,7 @@ class DashboardItemsViewModelSlice @Inject constructor( jetpackBadgeViewModelSlice.uiModel, siteItemsViewModelSlice.uiModel, sotw2023NudgeCardViewModelSlice.uiModel - ) { - jetpackFeatureCard, jetpackSwitchMenu, jetpackBadge, siteItems, sotw2023NudgeCard -> + ) { jetpackFeatureCard, jetpackSwitchMenu, jetpackBadge, siteItems, sotw2023NudgeCard -> mergeUiModels( jetpackFeatureCard, jetpackSwitchMenu, @@ -69,34 +68,23 @@ class DashboardItemsViewModelSlice @Inject constructor( siteItems: List?, sotw2023NudgeCard: MySiteCardAndItem.Card.WpSotw2023NudgeCardModel? ): List { - val dasbhboardSiteItems = mutableListOf().apply { - sotw2023NudgeCard?.let { add(it) } - siteItems?.let { addAll(siteItems) } - jetpackSwitchMenu?.let { add(jetpackSwitchMenu) } - if (jetpackFeatureCardHelper.shouldShowFeatureCardAtTop()) - jetpackFeatureCard?.let { add(0, jetpackFeatureCard) } - else jetpackFeatureCard?.let { add(jetpackFeatureCard) } - jetpackBadge?.let { add(jetpackBadge) } - }.toList() + val dasbhboardSiteItems = mutableListOf() + if (shouldShowSiteItems) { + dasbhboardSiteItems.apply { + sotw2023NudgeCard?.let { add(it) } + siteItems?.let { addAll(siteItems) } + jetpackSwitchMenu?.let { add(jetpackSwitchMenu) } + if (jetpackFeatureCardHelper.shouldShowFeatureCardAtTop()) + jetpackFeatureCard?.let { add(0, jetpackFeatureCard) } + else jetpackFeatureCard?.let { add(jetpackFeatureCard) } + jetpackBadge?.let { add(jetpackBadge) } + }.toList() + } return dasbhboardSiteItems } - fun onResume(site: SiteModel) { - if (shouldShowSiteItems(site)) buildCards(site) - else uiModel.postValue(emptyList()) - } - - fun onSiteChanged(site: SiteModel) { - if (shouldShowSiteItems(site)) buildCards(site) - else uiModel.postValue(emptyList()) - } - - fun onRefresh(site: SiteModel) { - if (shouldShowSiteItems(site)) buildCards(site) - else uiModel.postValue(emptyList()) - } - - private fun buildCards(site: SiteModel) { + fun buildItems(site: SiteModel) { + shouldShowSiteItems = true scope.launch { jetpackFeatureCardViewModelSlice.buildJetpackFeatureCard() jetpackSwitchMenuViewModelSlice.buildJetpackSwitchMenu() @@ -106,9 +94,15 @@ class DashboardItemsViewModelSlice @Inject constructor( } } - private fun shouldShowSiteItems(site: SiteModel) = - (buildConfigWrapper.isJetpackApp && site.isUsingWpComRestApi).not() - + fun clearValue() { + shouldShowSiteItems = false + jetpackFeatureCardViewModelSlice.clearValue() + jetpackSwitchMenuViewModelSlice.clearValue() + jetpackBadgeViewModelSlice.clearValue() + siteItemsViewModelSlice.clearValue() + sotw2023NudgeCardViewModelSlice.clearValue() + uiModel.postValue(emptyList()) + } fun onCleared() { scope.cancel() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt index 521f94e54952..b6988527d8b4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackBadge/JetpackBadgeViewModelSlice.kt @@ -38,4 +38,8 @@ class JetpackBadgeViewModelSlice @Inject constructor( jetpackBrandingUtils.trackBadgeTapped(screen) _onNavigation.value = Event(SiteNavigationAction.OpenJetpackPoweredBottomSheet) } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSlice.kt index f9c20f76025a..375a2babe948 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSlice.kt @@ -19,7 +19,7 @@ class JetpackSwitchMenuViewModelSlice @Inject constructor( private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation - private val _uiModel = MutableLiveData() + private val _uiModel = MutableLiveData() val uiModel = _uiModel.distinctUntilChanged() suspend fun buildJetpackSwitchMenu() { @@ -59,4 +59,8 @@ class JetpackSwitchMenuViewModelSlice @Inject constructor( private fun onJetpackFeatureCardMoreMenuClick() { jetpackFeatureCardHelper.track(AnalyticsTracker.Stat.REMOVE_FEATURE_CARD_MENU_ACCESSED) } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSlice.kt index 0bb015c14a12..2f43653d7934 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSlice.kt @@ -70,5 +70,9 @@ class JetpackFeatureCardViewModelSlice @Inject constructor( private fun onJetpackFeatureCardMoreMenuClick() { jetpackFeatureCardHelper.track(AnalyticsTracker.Stat.REMOVE_FEATURE_CARD_MENU_ACCESSED) } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSlice.kt index a31024ba320b..be5309ea7b70 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSlice.kt @@ -37,8 +37,8 @@ class SiteItemsViewModelSlice @Inject constructor( private val _onSnackbarMessage = MutableLiveData>() val onSnackbarMessage = _onSnackbarMessage - private val _uiModel = MutableLiveData>() - val uiModel: LiveData> = _uiModel.distinctUntilChanged() + private val _uiModel = MutableLiveData?>() + val uiModel: LiveData?> = _uiModel.distinctUntilChanged() // Quick start is disabled in all the cases where site items are built. suspend fun buildSiteItems( @@ -110,4 +110,8 @@ class SiteItemsViewModelSlice @Inject constructor( private fun isSiteBlazeEligible(site: SiteModel) = blazeFeatureUtils.isSiteBlazeEligible(site) + + fun clearValue() { + _uiModel.postValue(null) + } } From e13919db671164d5f6ac1aab3f53d53ca0d96e33 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 7 Feb 2024 10:22:43 +0530 Subject: [PATCH 168/250] * Fixes: Blogging prompt card refresh logic --- .../bloggingprompts/BloggingPromptCardViewModelSlice.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index 25fb804e8bcf..cfa5b331c061 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -73,8 +73,8 @@ class BloggingPromptCardViewModelSlice @Inject constructor( .map { it.model?.filter { prompt -> isSameDay(prompt.date, Date()) } } .collect { result -> postState(result?.firstOrNull()) - refreshData(siteModel) } + refreshData(siteModel) } else { postEmptyState() } @@ -82,7 +82,6 @@ class BloggingPromptCardViewModelSlice @Inject constructor( } else { postLastState() } - refreshData(siteModel) } fun refreshData( From beca4319432261c72705c31e3b127814c990384f Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 7 Feb 2024 10:23:33 +0530 Subject: [PATCH 169/250] * Updates: the clear and switch site logic --- .../android/ui/mysite/MySiteViewModel.kt | 14 +++++- .../cards/DashboardCardsViewModelSlice.kt | 49 ++++++++----------- .../items/DashboardItemsViewModelSlice.kt | 25 ++++------ 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 2d7bf3161f0e..6dedc66bc80f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -370,7 +370,7 @@ class MySiteViewModel @Inject constructor( val siteLocalId = it.id.toLong() val lastSelectedQuickStartType = appPrefsWrapper.getLastSelectedQuickStartTypeForSite(siteLocalId) quickStartRepository.checkAndSetQuickStartType(lastSelectedQuickStartType == NewSiteQuickStartType) - buildDashboardOrSiteItems(it) + onSitePicked(it) } ?: run { accountDataViewModelSlice.onResume() } @@ -467,6 +467,18 @@ class MySiteViewModel @Inject constructor( } } + fun onSitePicked(site: SiteModel) { + siteInfoHeaderCardViewModelSlice.buildCard(site) + dashboardItemsViewModelSlice.clearValue() + dashboardCardsViewModelSlice.clearValue() + if(shouldShowDashboard(site)) { + dashboardCardsViewModelSlice.buildCards(site) + } else { + dashboardItemsViewModelSlice.buildItems(site) + } + + } + private fun onDashboardErrorRetry() { // mySiteSourceManager.refresh() } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 1d04d6d124f3..27db2f502707 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -52,8 +52,6 @@ class DashboardCardsViewModelSlice @Inject constructor( val onOpenJetpackInstallFullPluginOnboarding = jetpackInstallFullPluginCardViewModelSlice.onOpenJetpackInstallFullPluginOnboarding - var shouldShowDashboard: Boolean = false - val onNavigation = merge( blazeCardViewModelSlice.onNavigation, cardViewModelSlice.onNavigation, @@ -133,31 +131,29 @@ class DashboardCardsViewModelSlice @Inject constructor( domainRegistrationCard: MySiteCardAndItem.Card.DomainRegistrationCard?, ): List { val cards = mutableListOf() - if(shouldShowDashboard) { - quicklinks?.let { cards.add(it) } - quickStart?.let { cards.add(it) } - domainRegistrationCard?.let { cards.add(it) } - bloganuaryNudgeCard?.let { cards.add(it) } - bloggingPromptCard?.let { cards.add(it) } - blazeCard?.let { cards.add(it) } - cardsState?.let { - when (cardsState) { - is CardsState.Success -> cards.addAll(cardsState.cards) - is CardsState.ErrorState -> cards.add(cardsState.error) - } - } - migrationSuccessCard?.let { cards.add(it) } - plansCard?.let { cards.add(it) } - jpFullInstallFullPlugin?.let { cards.add(it) } - // when clearing the values of all child VM Slices, - // the no cards message will still be shown and hence we need to check if the personalize card - // is shown or not, if the personalize card is not shown, then it means that - // we are not showing dashboard at all - personalizeCard?.let { - noCardsMessageViewModelSlice.buildNoCardsMessage(cards)?.let { cards.add(it) } - cards.add(it) + quicklinks?.let { cards.add(it) } + quickStart?.let { cards.add(it) } + domainRegistrationCard?.let { cards.add(it) } + bloganuaryNudgeCard?.let { cards.add(it) } + bloggingPromptCard?.let { cards.add(it) } + blazeCard?.let { cards.add(it) } + cardsState?.let { + when (cardsState) { + is CardsState.Success -> cards.addAll(cardsState.cards) + is CardsState.ErrorState -> cards.add(cardsState.error) } } + migrationSuccessCard?.let { cards.add(it) } + plansCard?.let { cards.add(it) } + jpFullInstallFullPlugin?.let { cards.add(it) } + // when clearing the values of all child VM Slices, + // the no cards message will still be shown and hence we need to check if the personalize card + // is shown or not, if the personalize card is not shown, then it means that + // we are not showing dashboard at all + personalizeCard?.let { + noCardsMessageViewModelSlice.buildNoCardsMessage(cards)?.let { cards.add(it) } + cards.add(it) + } return cards.toList() } @@ -173,7 +169,6 @@ class DashboardCardsViewModelSlice @Inject constructor( } fun buildCards(site: SiteModel) { - shouldShowDashboard = true jpMigrationSuccessCardViewModelSlice.buildCard() jetpackInstallFullPluginCardViewModelSlice.buildCard(site) blazeCardViewModelSlice.buildCard(site) @@ -188,7 +183,6 @@ class DashboardCardsViewModelSlice @Inject constructor( fun clearValue() { - shouldShowDashboard = false jpMigrationSuccessCardViewModelSlice.clearValue() jetpackInstallFullPluginCardViewModelSlice.clearValue() blazeCardViewModelSlice.clearValue() @@ -199,7 +193,6 @@ class DashboardCardsViewModelSlice @Inject constructor( plansCardViewModelSlice.clearValue() cardViewModelSlice.clearValue() quickStartCardViewModelSlice.clearValue() - uiModel.postValue(emptyList()) } fun onCleared() { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt index 095c86bf9931..96d4643af2c5 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt @@ -26,8 +26,6 @@ class DashboardItemsViewModelSlice @Inject constructor( ) { private lateinit var scope: CoroutineScope - var shouldShowSiteItems: Boolean = false - fun initialize(scope: CoroutineScope) { this.scope = scope sotw2023NudgeCardViewModelSlice.initialize(scope) @@ -69,22 +67,19 @@ class DashboardItemsViewModelSlice @Inject constructor( sotw2023NudgeCard: MySiteCardAndItem.Card.WpSotw2023NudgeCardModel? ): List { val dasbhboardSiteItems = mutableListOf() - if (shouldShowSiteItems) { - dasbhboardSiteItems.apply { - sotw2023NudgeCard?.let { add(it) } - siteItems?.let { addAll(siteItems) } - jetpackSwitchMenu?.let { add(jetpackSwitchMenu) } - if (jetpackFeatureCardHelper.shouldShowFeatureCardAtTop()) - jetpackFeatureCard?.let { add(0, jetpackFeatureCard) } - else jetpackFeatureCard?.let { add(jetpackFeatureCard) } - jetpackBadge?.let { add(jetpackBadge) } - }.toList() - } + dasbhboardSiteItems.apply { + sotw2023NudgeCard?.let { add(it) } + siteItems?.let { addAll(siteItems) } + jetpackSwitchMenu?.let { add(jetpackSwitchMenu) } + if (jetpackFeatureCardHelper.shouldShowFeatureCardAtTop()) + jetpackFeatureCard?.let { add(0, jetpackFeatureCard) } + else jetpackFeatureCard?.let { add(jetpackFeatureCard) } + jetpackBadge?.let { add(jetpackBadge) } + }.toList() return dasbhboardSiteItems } fun buildItems(site: SiteModel) { - shouldShowSiteItems = true scope.launch { jetpackFeatureCardViewModelSlice.buildJetpackFeatureCard() jetpackSwitchMenuViewModelSlice.buildJetpackSwitchMenu() @@ -95,13 +90,11 @@ class DashboardItemsViewModelSlice @Inject constructor( } fun clearValue() { - shouldShowSiteItems = false jetpackFeatureCardViewModelSlice.clearValue() jetpackSwitchMenuViewModelSlice.clearValue() jetpackBadgeViewModelSlice.clearValue() siteItemsViewModelSlice.clearValue() sotw2023NudgeCardViewModelSlice.clearValue() - uiModel.postValue(emptyList()) } fun onCleared() { From 6e1a9558b1e6d4cbb3bb61e25b5d9190ac240e69 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 7 Feb 2024 12:56:14 +0530 Subject: [PATCH 170/250] * Fixes: the switch from one wp.com site to another wp.com Fixes: the issue in which dashboard cards shown were not correct, the collect job for cards was not cancelled properly which resulted in dashboard cards shown in the wrong site. --- .../cards/DashboardCardsViewModelSlice.kt | 28 ++-- .../cards/dashboard/CardViewModelSlice.kt | 139 ++++++++++-------- .../activity/ActivityLogCardViewModelSlice.kt | 13 +- .../pages/PagesCardViewModelSlice.kt | 14 +- .../posts/PostsCardViewModelSlice.kt | 12 +- .../todaysstats/TodaysStatsViewModelSlice.kt | 12 +- .../dynamiccard/DynamicCardsViewModelSlice.kt | 24 ++- 7 files changed, 160 insertions(+), 82 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 27db2f502707..86a7ecb4a958 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -3,7 +3,9 @@ package org.wordpress.android.ui.mysite.cards import androidx.lifecycle.MutableLiveData import androidx.lifecycle.distinctUntilChanged import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.mysite.BlazeCardViewModelSlice import org.wordpress.android.ui.mysite.MySiteCardAndItem @@ -42,6 +44,8 @@ class DashboardCardsViewModelSlice @Inject constructor( ) { private lateinit var scope: CoroutineScope + private var job: Job? = null + private val _onSnackbar = MutableLiveData>() val onSnackbarMessage = merge( _onSnackbar, @@ -169,16 +173,19 @@ class DashboardCardsViewModelSlice @Inject constructor( } fun buildCards(site: SiteModel) { - jpMigrationSuccessCardViewModelSlice.buildCard() - jetpackInstallFullPluginCardViewModelSlice.buildCard(site) - blazeCardViewModelSlice.buildCard(site) - bloggingPromptCardViewModelSlice.buildCard(site) - bloganuaryNudgeCardViewModelSlice.buildCard() - personalizeCardViewModelSlice.buildCard() - quickLinksItemViewModelSlice.buildCard(site) - plansCardViewModelSlice.buildCard(site) - cardViewModelSlice.buildCard(site) - quickStartCardViewModelSlice.build(site) + job?.cancel() + job = scope.launch { + jpMigrationSuccessCardViewModelSlice.buildCard() + jetpackInstallFullPluginCardViewModelSlice.buildCard(site) + blazeCardViewModelSlice.buildCard(site) + bloggingPromptCardViewModelSlice.buildCard(site) + bloganuaryNudgeCardViewModelSlice.buildCard() + personalizeCardViewModelSlice.buildCard() + quickLinksItemViewModelSlice.buildCard(site) + plansCardViewModelSlice.buildCard(site) + cardViewModelSlice.buildCard(site) + quickStartCardViewModelSlice.build(site) + } } @@ -197,6 +204,7 @@ class DashboardCardsViewModelSlice @Inject constructor( fun onCleared() { quickLinksItemViewModelSlice.onCleared() + job?.cancel() scope.cancel() } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt index 23d47d274450..d3d7b4f8a09e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt @@ -2,10 +2,9 @@ package org.wordpress.android.ui.mysite.cards.dashboard import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.distinctUntilChanged import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.async +import kotlinx.coroutines.Job import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import org.wordpress.android.R @@ -54,11 +53,48 @@ class CardViewModelSlice @Inject constructor( ) { private lateinit var scope: CoroutineScope + private var collectJob: Job? = null + private var fetchJob: Job? = null + private val _isRefreshing = MutableLiveData() val isRefreshing: LiveData = _isRefreshing - private val _uiModel = MutableLiveData() - val uiModel: LiveData = _uiModel.distinctUntilChanged() + val uiModel: MutableLiveData = merge( + dynamicCardsViewModelSlice.topDynamicCards, + todaysStatsViewModelSlice.uiModel, + pagesCardViewModelSlice.uiModel, + postsCardViewModelSlice.uiModel, + activityLogCardViewModelSlice.uiModel, + dynamicCardsViewModelSlice.bottomDynamicCards + ) { topDynamicCards, todaysStatsCard, pagesCard, postsCard, activityCard, bottomDynamicCards -> + val state = mergeUiModels( + topDynamicCards, + todaysStatsCard, + pagesCard, + postsCard, + activityCard, + bottomDynamicCards + ) + state + } as MutableLiveData + + private fun mergeUiModels( + topDynamicCards: List?, + todaysStatsCard: MySiteCardAndItem.Card.TodaysStatsCard?, + pagesCard: MySiteCardAndItem.Card.PagesCard?, + postsCard: List?, + activityCard: MySiteCardAndItem.Card.ActivityCard?, + bottomDynamicCards: List? + ): CardsState { + val cards = mutableListOf() + topDynamicCards?.let { cards.addAll(topDynamicCards) } + todaysStatsCard?.let { cards.add(todaysStatsCard) } + pagesCard?.let { cards.add(pagesCard) } + postsCard?.let { cards.addAll(postsCard) } + activityCard?.let { cards.add(activityCard) } + bottomDynamicCards?.let { cards.addAll(bottomDynamicCards) } + return CardsState.Success(cards) + } private val _onNavigation = MutableLiveData>() val onNavigation = merge( @@ -94,7 +130,8 @@ class CardViewModelSlice @Inject constructor( ) { _isRefreshing.postValue(true) // fetch data from store and then refresh the data from the server - scope.launch(bgDispatcher) { + collectJob?.cancel() + collectJob = scope.launch(bgDispatcher) { cardsStore.getCards(siteModel) .map { it.model } .map { cards -> cards?.filter { getCardTypes(siteModel).contains(it.type) } } @@ -109,7 +146,8 @@ class CardViewModelSlice @Inject constructor( selectedSite: SiteModel ) { _isRefreshing.postValue(true) - scope.launch(bgDispatcher) { + fetchJob?.cancel() + fetchJob = scope.launch(bgDispatcher) { val payload = CardsRestClient.FetchCardsPayload( selectedSite, getCardTypes(selectedSite), @@ -157,28 +195,28 @@ class CardViewModelSlice @Inject constructor( } private fun postErrorState() { - if ((_uiModel.value == null) || isUiModelEmpty()){ + if ((uiModel.value == null) || isUiModelEmpty()) { // if the - _uiModel.postValue( + uiModel.postValue( CardsState.ErrorState( MySiteCardAndItem.Card.ErrorCard( onRetryClick = ListItemInteraction.create(this::onDashboardErrorRetry) ) ) ) - } else if (_uiModel.value is CardsState.ErrorState) { + } else if (uiModel.value is CardsState.ErrorState) { // if the error state is already posted, then post the snackbar message - _onSnackbarMessage.postValue( - Event( - SnackbarMessageHolder(UiString.UiStringRes(R.string.my_site_dashboard_update_error)) - ) + _onSnackbarMessage.postValue( + Event( + SnackbarMessageHolder(UiString.UiStringRes(R.string.my_site_dashboard_update_error)) ) - } + ) + } _isRefreshing.postValue(false) } private fun isUiModelEmpty(): Boolean { - return (_uiModel.value is CardsState.Success) && (_uiModel.value as CardsState.Success).cards.isEmpty() + return (uiModel.value is CardsState.Success) && (uiModel.value as CardsState.Success).cards.isEmpty() } private fun onDashboardErrorRetry() { @@ -188,63 +226,46 @@ class CardViewModelSlice @Inject constructor( fun postState(cards: List?) { _isRefreshing.postValue(false) if (cards.isNullOrEmpty()) { - _uiModel.postValue(CardsState.Success(emptyList())) + uiModel.postValue(CardsState.Success(emptyList())) return } scope.launch { - val result = mutableListOf() - - val topDynamicCards = async { - dynamicCardsViewModelSlice.buildTopDynamicCards( - cards.firstOrNull { it is CardModel.DynamicCardsModel } as? CardModel.DynamicCardsModel - ) - } - - val todayStatsCard = async { - todaysStatsViewModelSlice.buildTodaysStatsCard( - cards.firstOrNull { it is CardModel.TodaysStatsCardModel } as? CardModel.TodaysStatsCardModel - ) - } + dynamicCardsViewModelSlice.buildTopDynamicCards( + cards.firstOrNull { it is CardModel.DynamicCardsModel } as? CardModel.DynamicCardsModel + ) - val postCard = async { - postsCardViewModelSlice.buildPostCard( - cards.firstOrNull { it is CardModel.PostsCardModel } as? CardModel.PostsCardModel - ) - } - val pagesCard = async { - pagesCardViewModelSlice.buildCard( - cards.firstOrNull { it is CardModel.PagesCardModel } as? CardModel.PagesCardModel - ) - } + todaysStatsViewModelSlice.buildTodaysStatsCard( + cards.firstOrNull { it is CardModel.TodaysStatsCardModel } as? CardModel.TodaysStatsCardModel + ) - val activityCard = async { - activityLogCardViewModelSlice.buildCard( - cards.firstOrNull { it is CardModel.ActivityCardModel } as? CardModel.ActivityCardModel - ) - } + postsCardViewModelSlice.buildPostCard( + cards.firstOrNull { it is CardModel.PostsCardModel } as? CardModel.PostsCardModel + ) - val bottomDynamicCards = async { - dynamicCardsViewModelSlice.buildBottomDynamicCards( - cards.firstOrNull { it is CardModel.DynamicCardsModel } as? CardModel.DynamicCardsModel - ) - } + pagesCardViewModelSlice.buildCard( + cards.firstOrNull { it is CardModel.PagesCardModel } as? CardModel.PagesCardModel + ) - result.apply { - topDynamicCards.await()?.let { addAll(it) } - todayStatsCard.await()?.let { add(it) } - postCard.await().let { addAll(it) } - pagesCard.await()?.let { add(it) } - activityCard.await()?.let { add(it) } - bottomDynamicCards.await()?.let { addAll(it) } - }.toList() + activityLogCardViewModelSlice.buildCard( + cards.firstOrNull { it is CardModel.ActivityCardModel } as? CardModel.ActivityCardModel + ) - _uiModel.postValue(CardsState.Success(result)) + dynamicCardsViewModelSlice.buildBottomDynamicCards( + cards.firstOrNull { it is CardModel.DynamicCardsModel } as? CardModel.DynamicCardsModel + ) } } fun clearValue() { - _uiModel.postValue(null) + uiModel.postValue(CardsState.Success(emptyList())) + collectJob?.cancel() + fetchJob?.cancel() + dynamicCardsViewModelSlice.clearValue() + todaysStatsViewModelSlice.clearValue() + pagesCardViewModelSlice.clearValue() + postsCardViewModelSlice.clearValue() + activityLogCardViewModelSlice.clearValue() } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt index c1c8c9796c93..3cb2354f080c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt @@ -1,6 +1,7 @@ package org.wordpress.android.ui.mysite.cards.dashboard.activity import androidx.annotation.VisibleForTesting +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import org.wordpress.android.fluxc.model.dashboard.CardModel import org.wordpress.android.ui.mysite.MySiteCardAndItem @@ -21,14 +22,17 @@ class ActivityLogCardViewModelSlice @Inject constructor( private val appPrefsWrapper: AppPrefsWrapper, private val activityCardBuilder: ActivityCardBuilder ) { + private val _uiModel = MutableLiveData() + val uiModel = _uiModel as LiveData + private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation private val _refresh = MutableLiveData>() val refresh = _refresh - fun buildCard(activityCardModel: CardModel.ActivityCardModel?): MySiteCardAndItem.Card.ActivityCard? { - return activityCardBuilder.build(getActivityLogCardBuilderParams(activityCardModel)) + fun buildCard(activityCardModel: CardModel.ActivityCardModel?) { + _uiModel.postValue(activityCardBuilder.build(getActivityLogCardBuilderParams(activityCardModel))) } @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @@ -75,8 +79,13 @@ class ActivityLogCardViewModelSlice @Inject constructor( _onNavigation.value = Event(SiteNavigationAction.OpenActivityLog(requireNotNull(selectedSiteRepository.getSelectedSite()))) } + private fun onActivityCardMoreMenuClick() = cardsTracker.trackCardMoreMenuClicked(CardsTracker.Type.ACTIVITY.label) + fun clearValue() { + _uiModel.value = null + } + enum class MenuItemType(val label: String) { ALL_ACTIVITY("all_activity"), HIDE_THIS("hide_this") diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSlice.kt index 33a7b3c263a5..816e4fc72a2f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSlice.kt @@ -1,5 +1,6 @@ package org.wordpress.android.ui.mysite.cards.dashboard.pages +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import org.wordpress.android.fluxc.model.dashboard.CardModel.PagesCardModel import org.wordpress.android.ui.mysite.MySiteCardAndItem @@ -17,14 +18,19 @@ class PagesCardViewModelSlice @Inject constructor( private val appPrefsWrapper: AppPrefsWrapper, private val pagesCardBuilder: PagesCardBuilder ) { + private val _uiModel = MutableLiveData() + val uiModel: LiveData = _uiModel + private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation private val _refresh = MutableLiveData>() val refresh = _refresh - fun buildCard(pagesCardModel: PagesCardModel?): MySiteCardAndItem.Card.PagesCard? { - return pagesCardBuilder.build(getPagesCardBuilderParams(pagesCardModel)) + fun buildCard(pagesCardModel: PagesCardModel?) { + _uiModel.postValue( + pagesCardBuilder.build(getPagesCardBuilderParams(pagesCardModel)) + ) } fun getPagesCardBuilderParams(pagesCardModel: PagesCardModel?): PagesCardBuilderParams { @@ -100,6 +106,10 @@ class PagesCardViewModelSlice @Inject constructor( ) ) } + + fun clearValue() { + _uiModel.postValue(null) + } } enum class PagesMenuItemType(val label: String) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSlice.kt index 67a313e31000..104766119393 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSlice.kt @@ -1,5 +1,6 @@ package org.wordpress.android.ui.mysite.cards.dashboard.posts +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import org.wordpress.android.fluxc.model.dashboard.CardModel.PostsCardModel import org.wordpress.android.ui.mysite.MySiteCardAndItem @@ -18,14 +19,17 @@ class PostsCardViewModelSlice @Inject constructor( private val appPrefsWrapper: AppPrefsWrapper, private val postCardBuilder: PostCardBuilder ) { + private val _uiModel = MutableLiveData?>() + val uiModel = _uiModel as LiveData?> + private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation private val _refresh = MutableLiveData>() val refresh = _refresh - fun buildPostCard(postsCardModel: PostsCardModel?): List { - return postCardBuilder.build(getPostsCardBuilderParams(postsCardModel)) + fun buildPostCard(postsCardModel: PostsCardModel?) { + _uiModel.postValue(postCardBuilder.build(getPostsCardBuilderParams(postsCardModel))) } fun getPostsCardBuilderParams(postsCardModel: PostsCardModel?) : PostCardBuilderParams { @@ -111,4 +115,8 @@ class PostsCardViewModelSlice @Inject constructor( PostCardType.SCHEDULED -> PostMenuCard.SCHEDULED_POSTS } } + + fun clearValue() { + _uiModel.postValue(null) + } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt index 48d45bc8042f..28bad0840fe5 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt @@ -1,5 +1,6 @@ package org.wordpress.android.ui.mysite.cards.dashboard.todaysstats +import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import org.wordpress.android.fluxc.model.dashboard.CardModel.TodaysStatsCardModel import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhaseHelper @@ -19,6 +20,9 @@ class TodaysStatsViewModelSlice @Inject constructor( private val appPrefsWrapper: AppPrefsWrapper, private val todaysStatsCardBuilder: TodaysStatsCardBuilder ) { + private val _uiModel = MutableLiveData() + val uiModel = _uiModel as LiveData + private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation @@ -26,8 +30,8 @@ class TodaysStatsViewModelSlice @Inject constructor( val refresh = _refresh - fun buildTodaysStatsCard(todaysStatsCardModel: TodaysStatsCardModel?): MySiteCardAndItem.Card.TodaysStatsCard? { - return todaysStatsCardBuilder.build(getTodaysStatsBuilderParams(todaysStatsCardModel)) + fun buildTodaysStatsCard(todaysStatsCardModel: TodaysStatsCardModel?) { + _uiModel.postValue(todaysStatsCardBuilder.build(getTodaysStatsBuilderParams(todaysStatsCardModel))) } fun getTodaysStatsBuilderParams(todaysStatsCardModel: TodaysStatsCardModel?): TodaysStatsCardBuilderParams { @@ -93,6 +97,10 @@ class TodaysStatsViewModelSlice @Inject constructor( _onNavigation.value = Event(SiteNavigationAction.OpenStatsInsights(selectedSite)) } } + + fun clearValue() { + _uiModel.value = null + } } enum class TodaysStatsMenuItemType(val label: String) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dynamiccard/DynamicCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dynamiccard/DynamicCardsViewModelSlice.kt index 09c71441cbf7..d5a04181af15 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dynamiccard/DynamicCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dynamiccard/DynamicCardsViewModelSlice.kt @@ -23,19 +23,28 @@ class DynamicCardsViewModelSlice @Inject constructor( private val _refresh = MutableLiveData>() val refresh = _refresh as LiveData> - fun buildTopDynamicCards(dynamicCardsModel: CardModel.DynamicCardsModel?): List? { - return dynamicCardsBuilder.build( + private val _topDynamicCards = MutableLiveData?>() + val topDynamicCards = _topDynamicCards as LiveData?> + + fun buildTopDynamicCards(dynamicCardsModel: CardModel.DynamicCardsModel?) { + _topDynamicCards.postValue( + dynamicCardsBuilder.build( getBuilderParams(dynamicCardsModel), CardModel.DynamicCardsModel.CardOrder.TOP ) + ) } - fun buildBottomDynamicCards(dynamicCardsModel: CardModel.DynamicCardsModel?): - List? { - return dynamicCardsBuilder.build( + private val _bottomDynamicCards = MutableLiveData?>() + val bottomDynamicCards = _bottomDynamicCards as LiveData?> + + fun buildBottomDynamicCards(dynamicCardsModel: CardModel.DynamicCardsModel?) { + _bottomDynamicCards.postValue( + dynamicCardsBuilder.build( getBuilderParams(dynamicCardsModel), CardModel.DynamicCardsModel.CardOrder.BOTTOM ) + ) } fun getBuilderParams(dynamicCards: CardModel.DynamicCardsModel?): DynamicCardsBuilderParams { @@ -81,4 +90,9 @@ class DynamicCardsViewModelSlice @Inject constructor( fun resetShown() { tracker.resetShown() } + + fun clearValue() { + _topDynamicCards.value = null + _bottomDynamicCards.value = null + } } From 40fc54f0e6fe0357dae0586d5d8a73bfece66dc5 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 7 Feb 2024 13:13:44 +0530 Subject: [PATCH 171/250] * Fixes: Quick start card not shown after the site is created --- .../java/org/wordpress/android/ui/mysite/MySiteViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 6dedc66bc80f..057233d92699 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -444,10 +444,10 @@ class MySiteViewModel @Inject constructor( fun startQuickStart() { selectedSiteRepository.getSelectedSite()?.let { - dashboardCardsViewModelSlice.startQuickStart(it) quickStartTracker.track(Stat.QUICK_START_REQUEST_DIALOG_POSITIVE_TAPPED) startQuickStart(selectedSiteRepository.getSelectedSiteLocalId(), shouldMarkUpdateSiteTitleTaskComplete) shouldMarkUpdateSiteTitleTaskComplete = false + dashboardCardsViewModelSlice.startQuickStart(it) } } From a4335742f0f284b6430825a88f5d279854b994fd Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 7 Feb 2024 13:20:26 +0530 Subject: [PATCH 172/250] =?UTF-8?q?=E2=86=92=20Moves:=20refresh=20logic=20?= =?UTF-8?q?to=20child=20VM=20Slices?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/ui/mysite/cards/dashboard/CardViewModelSlice.kt | 4 ---- .../dashboard/activity/ActivityLogCardViewModelSlice.kt | 5 +---- .../mysite/cards/dashboard/pages/PagesCardViewModelSlice.kt | 5 +---- .../mysite/cards/dashboard/posts/PostsCardViewModelSlice.kt | 5 +---- .../dashboard/todaysstats/TodaysStatsViewModelSlice.kt | 6 +----- 5 files changed, 4 insertions(+), 21 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt index d3d7b4f8a09e..51979ee6ddb4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt @@ -113,10 +113,6 @@ class CardViewModelSlice @Inject constructor( val refresh = merge( _refresh, - pagesCardViewModelSlice.refresh, - todaysStatsViewModelSlice.refresh, - postsCardViewModelSlice.refresh, - activityLogCardViewModelSlice.refresh, dynamicCardsViewModelSlice.refresh, ) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt index 3cb2354f080c..e44166b77174 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt @@ -28,9 +28,6 @@ class ActivityLogCardViewModelSlice @Inject constructor( private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation - private val _refresh = MutableLiveData>() - val refresh = _refresh - fun buildCard(activityCardModel: CardModel.ActivityCardModel?) { _uiModel.postValue(activityCardBuilder.build(getActivityLogCardBuilderParams(activityCardModel))) } @@ -68,7 +65,7 @@ class ActivityLogCardViewModelSlice @Inject constructor( appPrefsWrapper.setShouldHideActivityDashboardCard( requireNotNull(selectedSiteRepository.getSelectedSite()).siteId, true ) - _refresh.postValue(Event(true)) + _uiModel.value = null } private fun onActivityCardAllActivityItemClick() { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSlice.kt index 816e4fc72a2f..35cc820f78fe 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSlice.kt @@ -24,9 +24,6 @@ class PagesCardViewModelSlice @Inject constructor( private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation - private val _refresh = MutableLiveData>() - val refresh = _refresh - fun buildCard(pagesCardModel: PagesCardModel?) { _uiModel.postValue( pagesCardBuilder.build(getPagesCardBuilderParams(pagesCardModel)) @@ -61,7 +58,7 @@ class PagesCardViewModelSlice @Inject constructor( private fun onPagesCardHideThisCardClick() { cardsTracker.trackCardMoreMenuItemClicked(CardsTracker.Type.PAGES.label, PagesMenuItemType.HIDE_THIS.label) appPrefsWrapper.setShouldHidePagesDashboardCard(selectedSiteRepository.getSelectedSite()!!.siteId, true) - _refresh.postValue(Event(true)) + _uiModel.value = null } private fun onPagesItemClick(params: PagesCardBuilderParams.PagesItemClickParams) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSlice.kt index 104766119393..4bbc3ccfb0fd 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSlice.kt @@ -25,9 +25,6 @@ class PostsCardViewModelSlice @Inject constructor( private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation - private val _refresh = MutableLiveData>() - val refresh = _refresh - fun buildPostCard(postsCardModel: PostsCardModel?) { _uiModel.postValue(postCardBuilder.build(getPostsCardBuilderParams(postsCardModel))) } @@ -58,7 +55,7 @@ class PostsCardViewModelSlice @Inject constructor( postCardType.name, true ) - refresh.postValue(Event(true)) + _uiModel.postValue(null) } private fun onViewPostsMenuItemClick(postCardType: PostCardType) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt index 28bad0840fe5..0eb21a7bba74 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt @@ -26,10 +26,6 @@ class TodaysStatsViewModelSlice @Inject constructor( private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation - private val _refresh = MutableLiveData>() - val refresh = _refresh - - fun buildTodaysStatsCard(todaysStatsCardModel: TodaysStatsCardModel?) { _uiModel.postValue(todaysStatsCardBuilder.build(getTodaysStatsBuilderParams(todaysStatsCardModel))) } @@ -78,7 +74,7 @@ class TodaysStatsViewModelSlice @Inject constructor( TodaysStatsMenuItemType.HIDE_THIS.label ) appPrefsWrapper.setShouldHideTodaysStatsDashboardCard(selectedSiteRepository.getSelectedSite()!!.siteId, true) - _refresh.postValue(Event(true)) + _uiModel.value = null } private fun onViewStatsMenuItemClick() { From cfd2e7328ebf9ac274f9b9299e5735c58a8205da Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 11:23:27 +0530 Subject: [PATCH 173/250] =?UTF-8?q?=E2=86=92=20Moves:=20coroutine=20calls?= =?UTF-8?q?=20to=20background=20thread=20and=20updates=20live=20data=20set?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wordpress/android/ui/mysite/BlazeCardViewModelSlice.kt | 6 +++++- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 6 +++++- .../android/ui/mysite/cards/dashboard/CardViewModelSlice.kt | 2 +- .../dashboard/activity/ActivityLogCardViewModelSlice.kt | 2 +- .../dashboard/todaysstats/TodaysStatsViewModelSlice.kt | 2 +- .../mysite/cards/dynamiccard/DynamicCardsViewModelSlice.kt | 4 ++-- .../mysite/cards/quickstart/QuickStartCardViewModelSlice.kt | 6 +++++- .../ui/mysite/cards/quickstart/QuickStartRepository.kt | 2 +- 8 files changed, 21 insertions(+), 9 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSlice.kt index b87296f5c8fc..08985a182c9a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSlice.kt @@ -4,12 +4,14 @@ import androidx.annotation.VisibleForTesting import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.distinctUntilChanged +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.wordpress.android.Result import org.wordpress.android.analytics.AnalyticsTracker import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.model.blaze.BlazeCampaignModel +import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.ui.blaze.BlazeFeatureUtils import org.wordpress.android.ui.blaze.BlazeFlowSource import org.wordpress.android.ui.blaze.blazecampaigns.campaigndetail.CampaignDetailPageSource @@ -24,10 +26,12 @@ import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker import org.wordpress.android.util.NetworkUtilsWrapper import org.wordpress.android.viewmodel.Event import javax.inject.Inject +import javax.inject.Named import javax.inject.Singleton @Singleton class BlazeCardViewModelSlice @Inject constructor( + @param:Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher, private val blazeFeatureUtils: BlazeFeatureUtils, private val selectedSiteRepository: SelectedSiteRepository, private val cardsTracker: CardsTracker, @@ -53,7 +57,7 @@ class BlazeCardViewModelSlice @Inject constructor( fun buildCard(site: SiteModel) { _isRefreshing.postValue(true) - scope.launch { + scope.launch(bgDispatcher){ if (blazeFeatureUtils.shouldShowBlazeCardEntryPoint(site)) { if (blazeFeatureUtils.shouldShowBlazeCampaigns()) { fetchCampaigns(site) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 86a7ecb4a958..80b2ea8a0a68 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -2,11 +2,13 @@ package org.wordpress.android.ui.mysite.cards import androidx.lifecycle.MutableLiveData import androidx.lifecycle.distinctUntilChanged +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.ui.mysite.BlazeCardViewModelSlice import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.SelectedSiteRepository @@ -26,8 +28,10 @@ import org.wordpress.android.ui.pages.SnackbarMessageHolder import org.wordpress.android.util.merge import org.wordpress.android.viewmodel.Event import javax.inject.Inject +import javax.inject.Named class DashboardCardsViewModelSlice @Inject constructor( + @param:Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher, private val jpMigrationSuccessCardViewModelSlice: JpMigrationSuccessCardViewModelSlice, private val jetpackInstallFullPluginCardViewModelSlice: JetpackInstallFullPluginCardViewModelSlice, private val domainRegistrationCardViewModelSlice: DomainRegistrationCardViewModelSlice, @@ -174,7 +178,7 @@ class DashboardCardsViewModelSlice @Inject constructor( fun buildCards(site: SiteModel) { job?.cancel() - job = scope.launch { + job = scope.launch(bgDispatcher) { jpMigrationSuccessCardViewModelSlice.buildCard() jetpackInstallFullPluginCardViewModelSlice.buildCard(site) blazeCardViewModelSlice.buildCard(site) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt index 51979ee6ddb4..8712ca19e15d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt @@ -225,7 +225,7 @@ class CardViewModelSlice @Inject constructor( uiModel.postValue(CardsState.Success(emptyList())) return } - scope.launch { + scope.launch(bgDispatcher) { dynamicCardsViewModelSlice.buildTopDynamicCards( cards.firstOrNull { it is CardModel.DynamicCardsModel } as? CardModel.DynamicCardsModel ) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt index e44166b77174..38258b7a7a21 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSlice.kt @@ -80,7 +80,7 @@ class ActivityLogCardViewModelSlice @Inject constructor( private fun onActivityCardMoreMenuClick() = cardsTracker.trackCardMoreMenuClicked(CardsTracker.Type.ACTIVITY.label) fun clearValue() { - _uiModel.value = null + _uiModel.postValue(null) } enum class MenuItemType(val label: String) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt index 0eb21a7bba74..41732c261431 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSlice.kt @@ -95,7 +95,7 @@ class TodaysStatsViewModelSlice @Inject constructor( } fun clearValue() { - _uiModel.value = null + _uiModel.postValue(null) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dynamiccard/DynamicCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dynamiccard/DynamicCardsViewModelSlice.kt index d5a04181af15..ab51c24cc9fc 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dynamiccard/DynamicCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dynamiccard/DynamicCardsViewModelSlice.kt @@ -92,7 +92,7 @@ class DynamicCardsViewModelSlice @Inject constructor( } fun clearValue() { - _topDynamicCards.value = null - _bottomDynamicCards.value = null + _topDynamicCards.postValue(null) + _bottomDynamicCards.postValue(null) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt index 3c06f92d8657..932ee45809e4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt @@ -2,12 +2,14 @@ package org.wordpress.android.ui.mysite.cards.quickstart import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.wordpress.android.fluxc.model.SiteHomepageSettings.ShowOnFront import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.QuickStartStore import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTaskType +import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.QuickStartCardBuilderParams import org.wordpress.android.ui.mysite.SelectedSiteRepository @@ -17,8 +19,10 @@ import org.wordpress.android.ui.quickstart.QuickStartTracker import org.wordpress.android.util.QuickStartUtilsWrapper import org.wordpress.android.viewmodel.Event import javax.inject.Inject +import javax.inject.Named class QuickStartCardViewModelSlice @Inject constructor( + @param:Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher, private val quickStartRepository: QuickStartRepository, private val quickStartStore: QuickStartStore, private val quickStartUtilsWrapper: QuickStartUtilsWrapper, @@ -43,7 +47,7 @@ class QuickStartCardViewModelSlice @Inject constructor( } fun build(selectedSite: SiteModel) { - scope.launch { + scope.launch(bgDispatcher) { _isRefreshing.postValue(true) if (!quickStartUtilsWrapper.isQuickStartAvailableForTheSite(selectedSite)) { _uiModel.postValue(null) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartRepository.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartRepository.kt index b55d0e878e31..d080314be536 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartRepository.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartRepository.kt @@ -99,7 +99,7 @@ class QuickStartRepository } fun clearActiveTask() { - _activeTask.value = null + _activeTask.postValue(null) } fun clearPendingTask() { From de1e71c9e4de52f5118a66984483d400ff321c21 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 11:39:42 +0530 Subject: [PATCH 174/250] =?UTF-8?q?=E2=86=92=20Moves:=20coroutine=20calls?= =?UTF-8?q?=20to=20background=20thread?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/ui/mysite/items/DashboardItemsViewModelSlice.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt index 96d4643af2c5..56052f778279 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt @@ -2,10 +2,12 @@ package org.wordpress.android.ui.mysite.items import androidx.lifecycle.MutableLiveData import androidx.lifecycle.distinctUntilChanged +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardHelper import org.wordpress.android.ui.mysite.cards.sotw2023.WpSotw2023NudgeCardViewModelSlice @@ -15,8 +17,10 @@ import org.wordpress.android.ui.mysite.items.jetpackfeaturecard.JetpackFeatureCa import org.wordpress.android.ui.mysite.items.listitem.SiteItemsViewModelSlice import org.wordpress.android.util.merge import javax.inject.Inject +import javax.inject.Named class DashboardItemsViewModelSlice @Inject constructor( + @param:Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher, private val jetpackFeatureCardViewModelSlice: JetpackFeatureCardViewModelSlice, private val jetpackSwitchMenuViewModelSlice: JetpackSwitchMenuViewModelSlice, private val jetpackBadgeViewModelSlice: JetpackBadgeViewModelSlice, @@ -80,7 +84,7 @@ class DashboardItemsViewModelSlice @Inject constructor( } fun buildItems(site: SiteModel) { - scope.launch { + scope.launch(bgDispatcher) { jetpackFeatureCardViewModelSlice.buildJetpackFeatureCard() jetpackSwitchMenuViewModelSlice.buildJetpackSwitchMenu() jetpackBadgeViewModelSlice.buildJetpackBadge() From dcbc4d77c2f2afb8a888afaba6313835581b10f0 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 11:43:27 +0530 Subject: [PATCH 175/250] * Fixes: Incorrect pull to refresh logic --- .../wordpress/android/ui/mysite/MySiteViewModel.kt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 057233d92699..7ee16ddf6b4d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -257,11 +257,9 @@ class MySiteViewModel @Inject constructor( fun refresh(isPullToRefresh: Boolean = false) { if (isPullToRefresh) analyticsTrackerWrapper.track(Stat.MY_SITE_PULL_TO_REFRESH) selectedSiteRepository.getSelectedSite()?.let { - if (shouldShowDashboard(it)) { - buildDashboardOrSiteItems(it) - } else { - accountDataViewModelSlice.onRefresh() - } + buildDashboardOrSiteItems(it) + } ?: run { + accountDataViewModelSlice.onRefresh() } } @@ -458,7 +456,7 @@ class MySiteViewModel @Inject constructor( fun buildDashboardOrSiteItems(site: SiteModel) { siteInfoHeaderCardViewModelSlice.buildCard(site) - if(shouldShowDashboard(site)) { + if (shouldShowDashboard(site)) { dashboardCardsViewModelSlice.buildCards(site) dashboardItemsViewModelSlice.clearValue() } else { @@ -471,7 +469,7 @@ class MySiteViewModel @Inject constructor( siteInfoHeaderCardViewModelSlice.buildCard(site) dashboardItemsViewModelSlice.clearValue() dashboardCardsViewModelSlice.clearValue() - if(shouldShowDashboard(site)) { + if (shouldShowDashboard(site)) { dashboardCardsViewModelSlice.buildCards(site) } else { dashboardItemsViewModelSlice.buildItems(site) From dc5d3b0c0351dde256a4beb5adb80b29dc162674 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 12:49:47 +0530 Subject: [PATCH 176/250] + Adds: the logic to track and clear tracker on CardViewModelSlice --- .../ui/mysite/cards/dashboard/CardViewModelSlice.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt index 8712ca19e15d..90ee718419fa 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt @@ -50,6 +50,7 @@ class CardViewModelSlice @Inject constructor( private val activityLogCardViewModelSlice: ActivityLogCardViewModelSlice, private val preferences: PreferenceUtils.PreferenceUtilsWrapper, private val buildConfigWrapper: BuildConfigWrapper, + private val cardsTracker: CardsTracker ) { private lateinit var scope: CoroutineScope @@ -263,6 +264,18 @@ class CardViewModelSlice @Inject constructor( postsCardViewModelSlice.clearValue() activityLogCardViewModelSlice.clearValue() } + + fun trackCardShown(cards: List) { + cards.filterIsInstance().forEach { + dynamicCardsViewModelSlice.trackShown(it.id) + } + cardsTracker.trackShown(cards) + } + + fun resetShownTracker() { + dynamicCardsViewModelSlice.resetShown() + cardsTracker.resetShown() + } } sealed class CardsState { From b17fd0de7347fe5d065d037ab867795d3c2f21d6 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 12:50:59 +0530 Subject: [PATCH 177/250] =?UTF-8?q?=E2=86=92=20Moves:=20the=20logic=20to?= =?UTF-8?q?=20track=20JetpackInstallFullPluginCard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wordpress/android/ui/mysite/MySiteViewModel.kt | 3 --- .../JetpackInstallFullPluginCardViewModelSlice.kt | 11 ++++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 7ee16ddf6b4d..439f27e06702 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -39,7 +39,6 @@ import org.wordpress.android.ui.mysite.cards.DashboardCardsViewModelSlice import org.wordpress.android.ui.mysite.cards.DomainRegistrationCardShownTracker import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardShownTracker -import org.wordpress.android.ui.mysite.cards.jpfullplugininstall.JetpackInstallFullPluginShownTracker import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository import org.wordpress.android.ui.mysite.cards.siteinfo.SiteInfoHeaderCardViewModelSlice import org.wordpress.android.ui.mysite.items.DashboardItemsViewModelSlice @@ -88,7 +87,6 @@ class MySiteViewModel @Inject constructor( private val jetpackFeatureCardShownTracker: JetpackFeatureCardShownTracker, private val jetpackFeatureRemovalUtils: JetpackFeatureRemovalOverlayUtil, private val getShowJetpackFullPluginInstallOnboardingUseCase: GetShowJetpackFullPluginInstallOnboardingUseCase, - private val jetpackInstallFullPluginShownTracker: JetpackInstallFullPluginShownTracker, private val jetpackFeatureRemovalPhaseHelper: JetpackFeatureRemovalPhaseHelper, private val wpJetpackIndividualPluginHelper: WPJetpackIndividualPluginHelper, private val siteInfoHeaderCardViewModelSlice: SiteInfoHeaderCardViewModelSlice, @@ -532,7 +530,6 @@ class MySiteViewModel @Inject constructor( cardsTracker.resetShown() quickStartTracker.resetShown() jetpackFeatureCardShownTracker.resetShown() - jetpackInstallFullPluginShownTracker.resetShown() dashboardCardsViewModelSlice.resetShownTracker() // personalizeCardViewModelSlice.resetShown() // sotw2023NudgeCardViewModelSlice.resetShown() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt index c0ac1b712682..cc8e01c4f3a3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt @@ -19,7 +19,8 @@ import javax.inject.Inject class JetpackInstallFullPluginCardViewModelSlice @Inject constructor( private val appPrefsWrapper: AppPrefsWrapper, private val selectedSiteRepository: SelectedSiteRepository, - private val analyticsTrackerWrapper: AnalyticsTrackerWrapper + private val analyticsTrackerWrapper: AnalyticsTrackerWrapper, + private val jetpackInstallFullPluginShownTracker: JetpackInstallFullPluginShownTracker ) { private val _onOpenJetpackInstallFullPluginOnboarding = SingleLiveEvent>() val onOpenJetpackInstallFullPluginOnboarding = _onOpenJetpackInstallFullPluginOnboarding @@ -73,4 +74,12 @@ class JetpackInstallFullPluginCardViewModelSlice @Inject constructor( fun clearValue() { _uiModel.postValue(null) } + + fun trackShown(card: JetpackInstallFullPluginCard) { + jetpackInstallFullPluginShownTracker.trackShown(card.type) + } + + fun resetShownTracker() { + jetpackInstallFullPluginShownTracker.resetShown() + } } From f9f068a68b4bab9eb791f822f2d529eb8d9617cb Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 12:56:32 +0530 Subject: [PATCH 178/250] =?UTF-8?q?=E2=86=92=20Moves:=20the=20logic=20to?= =?UTF-8?q?=20track=20DomainRegistrationCard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves: the logic to track DomainRegistration card to DomainRegistrationCardViewModelSlice --- .../android/ui/mysite/MySiteViewModel.kt | 7 ------- .../cards/DashboardCardsViewModelSlice.kt | 18 ++++++++++++++---- .../DomainRegistrationCardViewModelSlice.kt | 12 +++++++++++- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 439f27e06702..1aed094d9635 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -36,7 +36,6 @@ import org.wordpress.android.ui.mysite.MySiteUiState.PartialState import org.wordpress.android.ui.mysite.MySiteViewModel.State.NoSites import org.wordpress.android.ui.mysite.MySiteViewModel.State.SiteSelected import org.wordpress.android.ui.mysite.cards.DashboardCardsViewModelSlice -import org.wordpress.android.ui.mysite.cards.DomainRegistrationCardShownTracker import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardShownTracker import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository @@ -79,7 +78,6 @@ class MySiteViewModel @Inject constructor( private val snackbarSequencer: SnackbarSequencer, private val landOnTheEditorFeatureConfig: LandOnTheEditorFeatureConfig, private val cardsTracker: CardsTracker, - private val domainRegistrationCardShownTracker: DomainRegistrationCardShownTracker, private val buildConfigWrapper: BuildConfigWrapper, private val appPrefsWrapper: AppPrefsWrapper, private val quickStartTracker: QuickStartTracker, @@ -502,10 +500,6 @@ class MySiteViewModel @Inject constructor( } private fun trackCardsAndItemsShownIfNeeded() { -// siteSelected.dashboardData.filterIsInstance() -// .forEach { domainRegistrationCardShownTracker.trackShown(it.type) } -// siteSelected.dashboardData.filterIsInstance() -// .let { cardsTracker.trackShown(it) } // siteSelected.dashboardData.filterIsInstance() // .firstOrNull()?.let { quickStartTracker.trackShown(it.type) } // siteSelected.dashboardData.filterIsInstance() @@ -526,7 +520,6 @@ class MySiteViewModel @Inject constructor( } private fun resetShownTrackers() { - domainRegistrationCardShownTracker.resetShown() cardsTracker.resetShown() quickStartTracker.resetShown() jetpackFeatureCardShownTracker.resetShown() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 80b2ea8a0a68..0a73691c8250 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -218,12 +218,22 @@ class DashboardCardsViewModelSlice @Inject constructor( } } + fun trackCardShown(dashboardData: List){ + dashboardData.filterIsInstance().let { + cardViewModelSlice.trackCardShown(it) + } + dashboardData.filterIsInstance() + .forEach { jetpackInstallFullPluginCardViewModelSlice.trackShown(it) } + + dashboardData.filterIsInstance() + .forEach { domainRegistrationCardViewModelSlice.trackShown(it) } + } + fun resetShownTracker() { personalizeCardViewModelSlice.resetShown() -// dynamicCardsViewModelSlice.resetShown() -// domainRegistrationCardShownTracker.resetShown() -// cardsTracker.resetShown() -// quickStartTracker.resetShown() + cardViewModelSlice.resetShownTracker() + jetpackInstallFullPluginCardViewModelSlice.resetShownTracker() + domainRegistrationCardViewModelSlice.resetCardShown() } fun startQuickStart(siteModel: SiteModel) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt index 20ea805c65f5..c12f81bc192e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt @@ -20,6 +20,7 @@ import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.SiteNavigationAction +import org.wordpress.android.ui.mysite.cards.DomainRegistrationCardShownTracker import org.wordpress.android.ui.plans.isDomainCreditAvailable import org.wordpress.android.ui.utils.ListItemInteraction import org.wordpress.android.util.AppLog.T.DOMAIN_REGISTRATION @@ -36,7 +37,8 @@ class DomainRegistrationCardViewModelSlice @Inject constructor( private val selectedSiteRepository: SelectedSiteRepository, private val appLogWrapper: AppLogWrapper, private val siteUtils: SiteUtilsWrapper, - private val domainRegistrationTracker: DomainRegistrationTracker + private val domainRegistrationTracker: DomainRegistrationTracker, + private val domainRegistrationCardShownTracker: DomainRegistrationCardShownTracker ) { private lateinit var scope: CoroutineScope @@ -138,6 +140,14 @@ class DomainRegistrationCardViewModelSlice @Inject constructor( continuations[event.site.id]?.resume(event) continuations[event.site.id] = null } + + fun trackShown(card: MySiteCardAndItem.Card.DomainRegistrationCard) { + domainRegistrationCardShownTracker.trackShown(card.type) + } + + fun resetCardShown() { + domainRegistrationCardShownTracker.resetShown() + } } /* This class is a helper to offset the AppLogWrapper dependency conflict (see AppLogWrapper itself for more info) */ From 5eec174f1f159eb7e8362db10c1b4b155ae54edf Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 13:03:20 +0530 Subject: [PATCH 179/250] =?UTF-8?q?=E2=86=92=20Moves:=20the=20logic=20to?= =?UTF-8?q?=20track=20Personalize=20Card?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves: the logic to track Personalize card to PersonalizeCardViewModelSlice --- .../org/wordpress/android/ui/mysite/MySiteViewModel.kt | 7 +------ .../ui/mysite/cards/DashboardCardsViewModelSlice.kt | 6 +++++- .../cards/personalize/PersonalizeCardViewModelSlice.kt | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 1aed094d9635..2efe3f785904 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -506,11 +506,8 @@ class MySiteViewModel @Inject constructor( // .firstOrNull()?.let { cardsTracker.trackQuickStartCardShown(quickStartRepository.quickStartType) } // siteSelected.dashboardData.filterIsInstance() // .forEach { jetpackFeatureCardShownTracker.trackShown(it.type) } -// siteSelected.dashboardData.filterIsInstance() -// .forEach { jetpackInstallFullPluginShownTracker.trackShown(it.type) } // dashboardCardPlansUtils.trackCardShown(viewModelScope, siteSelected) -//// siteSelected.dashboardData.filterIsInstance() -//// .forEach { personalizeCardViewModelSlice.trackShown(it.type) } + //// siteSelected.dashboardData.filterIsInstance() //// .forEach { noCardsMessageViewModelSlice.trackShown(it.type) } //// siteSelected.dashboardData.filterIsInstance() @@ -524,9 +521,7 @@ class MySiteViewModel @Inject constructor( quickStartTracker.resetShown() jetpackFeatureCardShownTracker.resetShown() dashboardCardsViewModelSlice.resetShownTracker() -// personalizeCardViewModelSlice.resetShown() // sotw2023NudgeCardViewModelSlice.resetShown() -// dynamicCardsViewModelSlice.resetShown() } // FluxC events diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 0a73691c8250..a9bc56035026 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -227,13 +227,17 @@ class DashboardCardsViewModelSlice @Inject constructor( dashboardData.filterIsInstance() .forEach { domainRegistrationCardViewModelSlice.trackShown(it) } + + dashboardData.filterIsInstance().forEach { + personalizeCardViewModelSlice.trackShown(it) + } } fun resetShownTracker() { - personalizeCardViewModelSlice.resetShown() cardViewModelSlice.resetShownTracker() jetpackInstallFullPluginCardViewModelSlice.resetShownTracker() domainRegistrationCardViewModelSlice.resetCardShown() + personalizeCardViewModelSlice.resetShown() } fun startQuickStart(siteModel: SiteModel) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt index 35d32d4c64f6..8d07efd0b8f2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt @@ -44,8 +44,8 @@ class PersonalizeCardViewModelSlice @Inject constructor( _onNavigation.value = Event(OpenDashboardPersonalization) } - fun trackShown(itemType: MySiteCardAndItem.Type) { - personalizeCardShownTracker.trackShown(itemType) + fun trackShown(card: MySiteCardAndItem.Card.PersonalizeCardModel) { + personalizeCardShownTracker.trackShown(card.type) } fun resetShown() { From 7d44ea21dbfa154a4c513477a6f5f53b43da472a Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 13:08:58 +0530 Subject: [PATCH 180/250] =?UTF-8?q?=E2=86=92=20Moves:=20the=20logic=20to?= =?UTF-8?q?=20track=20QuickStart=20Card?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves: the logic to track QuickStart card to QuickStartCardViewModelSlice --- .../org/wordpress/android/ui/mysite/MySiteViewModel.kt | 5 ----- .../ui/mysite/cards/DashboardCardsViewModelSlice.kt | 5 +++++ .../cards/quickstart/QuickStartCardViewModelSlice.kt | 8 ++++++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 2efe3f785904..e00e27acc35b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -500,10 +500,6 @@ class MySiteViewModel @Inject constructor( } private fun trackCardsAndItemsShownIfNeeded() { -// siteSelected.dashboardData.filterIsInstance() -// .firstOrNull()?.let { quickStartTracker.trackShown(it.type) } -// siteSelected.dashboardData.filterIsInstance() -// .firstOrNull()?.let { cardsTracker.trackQuickStartCardShown(quickStartRepository.quickStartType) } // siteSelected.dashboardData.filterIsInstance() // .forEach { jetpackFeatureCardShownTracker.trackShown(it.type) } // dashboardCardPlansUtils.trackCardShown(viewModelScope, siteSelected) @@ -518,7 +514,6 @@ class MySiteViewModel @Inject constructor( private fun resetShownTrackers() { cardsTracker.resetShown() - quickStartTracker.resetShown() jetpackFeatureCardShownTracker.resetShown() dashboardCardsViewModelSlice.resetShownTracker() // sotw2023NudgeCardViewModelSlice.resetShown() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index a9bc56035026..9ee2683654d0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -231,6 +231,10 @@ class DashboardCardsViewModelSlice @Inject constructor( dashboardData.filterIsInstance().forEach { personalizeCardViewModelSlice.trackShown(it) } + + dashboardData.filterIsInstance().forEach { + quickStartCardViewModelSlice.trackShown(it) + } } fun resetShownTracker() { @@ -238,6 +242,7 @@ class DashboardCardsViewModelSlice @Inject constructor( jetpackInstallFullPluginCardViewModelSlice.resetShownTracker() domainRegistrationCardViewModelSlice.resetCardShown() personalizeCardViewModelSlice.resetShown() + quickStartCardViewModelSlice.resetShown() } fun startQuickStart(siteModel: SiteModel) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt index 932ee45809e4..0fea8d042355 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSlice.kt @@ -165,4 +165,12 @@ class QuickStartCardViewModelSlice @Inject constructor( fun clearValue() { _uiModel.postValue(null) } + + fun trackShown(it: MySiteCardAndItem.Card.QuickStartCard) { + quickStartTracker.trackShown(it.type) + } + + fun resetShown() { + quickStartTracker.resetShown() + } } From 4f7fc93f3617f85e34dfea7ff3efbf9d177dbb89 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 13:10:34 +0530 Subject: [PATCH 181/250] =?UTF-8?q?=E2=86=92=20Moves:=20the=20logic=20to?= =?UTF-8?q?=20track=20NoCardsMessage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves: the logic to track NoCardsMessage card to DashboardCardsViewModelSlice --- .../java/org/wordpress/android/ui/mysite/MySiteViewModel.kt | 3 --- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index e00e27acc35b..4d3e13a022c8 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -503,9 +503,6 @@ class MySiteViewModel @Inject constructor( // siteSelected.dashboardData.filterIsInstance() // .forEach { jetpackFeatureCardShownTracker.trackShown(it.type) } // dashboardCardPlansUtils.trackCardShown(viewModelScope, siteSelected) - -//// siteSelected.dashboardData.filterIsInstance() -//// .forEach { noCardsMessageViewModelSlice.trackShown(it.type) } //// siteSelected.dashboardData.filterIsInstance() //// .forEach { _ -> sotw2023NudgeCardViewModelSlice.trackShown() } //// siteSelected.dashboardData.filterIsInstance() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 9ee2683654d0..1710f79d0370 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -235,6 +235,10 @@ class DashboardCardsViewModelSlice @Inject constructor( dashboardData.filterIsInstance().forEach { quickStartCardViewModelSlice.trackShown(it) } + + dashboardData.filterIsInstance().forEach { + noCardsMessageViewModelSlice.trackShown(it.type) + } } fun resetShownTracker() { @@ -243,6 +247,7 @@ class DashboardCardsViewModelSlice @Inject constructor( domainRegistrationCardViewModelSlice.resetCardShown() personalizeCardViewModelSlice.resetShown() quickStartCardViewModelSlice.resetShown() + noCardsMessageViewModelSlice.resetShown() } fun startQuickStart(siteModel: SiteModel) { From c7abcfea849f70f0aad247394667419d5770be21 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 13:47:22 +0530 Subject: [PATCH 182/250] =?UTF-8?q?=E2=86=92=20Moves:=20the=20logic=20to?= =?UTF-8?q?=20track=20PlansCard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves: the logic to track PlansCard card to PlansCardViewModelSlice --- .../android/ui/mysite/MySiteViewModel.kt | 4 - .../cards/DashboardCardsViewModelSlice.kt | 5 + .../cards/dashboard/plans/PlansCardUtils.kt | 93 ++++--------------- .../cards/plans/PlansCardViewModelSlice.kt | 8 ++ 4 files changed, 29 insertions(+), 81 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 4d3e13a022c8..6ce0564f14f3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -265,7 +265,6 @@ class MySiteViewModel @Inject constructor( checkAndShowJetpackFullPluginInstallOnboarding() checkAndShowQuickStartNotice() // bloggingPromptCardViewModelSlice.onResume(uiModel.value as? SiteSelected) -// dashboardCardPlansUtils.onResume(uiModel.value as? SiteSelected) selectedSiteRepository.getSelectedSite()?.let { buildDashboardOrSiteItems(it) } ?: run { @@ -502,11 +501,8 @@ class MySiteViewModel @Inject constructor( private fun trackCardsAndItemsShownIfNeeded() { // siteSelected.dashboardData.filterIsInstance() // .forEach { jetpackFeatureCardShownTracker.trackShown(it.type) } -// dashboardCardPlansUtils.trackCardShown(viewModelScope, siteSelected) //// siteSelected.dashboardData.filterIsInstance() //// .forEach { _ -> sotw2023NudgeCardViewModelSlice.trackShown() } -//// siteSelected.dashboardData.filterIsInstance() -//// .forEach { dynamicCardsViewModelSlice.trackShown(it.id) } } private fun resetShownTrackers() { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 1710f79d0370..dda1c1f57750 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -239,6 +239,10 @@ class DashboardCardsViewModelSlice @Inject constructor( dashboardData.filterIsInstance().forEach { noCardsMessageViewModelSlice.trackShown(it.type) } + + dashboardData.filterIsInstance< MySiteCardAndItem.Card.DashboardPlansCard>().forEachIndexed { index, _ -> + plansCardViewModelSlice.trackShown(index) + } } fun resetShownTracker() { @@ -248,6 +252,7 @@ class DashboardCardsViewModelSlice @Inject constructor( personalizeCardViewModelSlice.resetShown() quickStartCardViewModelSlice.resetShown() noCardsMessageViewModelSlice.resetShown() + plansCardViewModelSlice.resetShown() } fun startQuickStart(siteModel: SiteModel) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/plans/PlansCardUtils.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/plans/PlansCardUtils.kt index 41b13debf770..601b507bd0c0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/plans/PlansCardUtils.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/plans/PlansCardUtils.kt @@ -1,34 +1,19 @@ package org.wordpress.android.ui.mysite.cards.dashboard.plans -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Job -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import org.wordpress.android.analytics.AnalyticsTracker import org.wordpress.android.fluxc.model.SiteModel -import org.wordpress.android.modules.BG_THREAD -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardPlansCard -import org.wordpress.android.ui.mysite.MySiteViewModel.State.SiteSelected +import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.util.BuildConfigWrapper import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper -import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.atomic.AtomicReference import javax.inject.Inject -import javax.inject.Named class PlansCardUtils @Inject constructor( private val appPrefsWrapper: AppPrefsWrapper, private val buildConfigWrapper: BuildConfigWrapper, - private val analyticsTrackerWrapper: AnalyticsTrackerWrapper, - @Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher + private val analyticsTrackerWrapper: AnalyticsTrackerWrapper ) { - private var dashboardUpdateDebounceJob: Job? = null - - private val plansCardVisible = AtomicReference(null) - private val waitingToTrack = AtomicBoolean(false) - private val currentSite = AtomicReference(null) + private val cardsShownTracked = mutableListOf() fun shouldShowCard( siteModel: SiteModel, @@ -45,43 +30,6 @@ class PlansCardUtils @Inject constructor( appPrefsWrapper.setShouldHideDashboardPlansCard(siteId, true) } - fun trackCardShown(scope: CoroutineScope, siteSelected: SiteSelected?) { - // cancel any existing job (debouncing mechanism) - dashboardUpdateDebounceJob?.cancel() - - dashboardUpdateDebounceJob = scope.launch(bgDispatcher) { - val isVisible = siteSelected - ?.dashboardData - ?.any { card -> - card is DashboardPlansCard - } ?: false - - // add a delay (debouncing mechanism) - delay(CARD_VISIBLE_DEBOUNCE) - - plansCardVisible.set(isVisible) - if (isVisible && waitingToTrack.getAndSet(false)) { - trackCardShown(positionIndex(siteSelected)) - } - }.also { - it.invokeOnCompletion { cause -> - // only set the job to null if it wasn't cancelled since cancellation is part of debouncing - if (cause == null) dashboardUpdateDebounceJob = null - } - } - } - - fun onResume(siteSelected: SiteSelected?) { - onDashboardRefreshed(siteSelected) - } - - fun onSiteChanged(siteId: Int?, siteSelected: SiteSelected?) { - if (currentSite.getAndSet(siteId) != siteId) { - plansCardVisible.set(null) - onDashboardRefreshed(siteSelected) - } - } - fun trackCardTapped() { analyticsTrackerWrapper.track( AnalyticsTracker.Stat.DASHBOARD_CARD_PLANS_TAPPED @@ -100,36 +48,27 @@ class PlansCardUtils @Inject constructor( ) } - private fun trackCardShown(positionIndex: Int) { - analyticsTrackerWrapper.track( - AnalyticsTracker.Stat.DASHBOARD_CARD_PLANS_SHOWN, - mapOf(POSITION_INDEX to positionIndex) - ) + fun trackCardShown(positionIndex: Int) { + val cardsShownTrackedPair = MySiteCardAndItem.Type.DASHBOARD_PLANS_CARD + if (!cardsShownTracked.contains(cardsShownTrackedPair)) { + cardsShownTracked.add(cardsShownTrackedPair) + analyticsTrackerWrapper.track( + AnalyticsTracker.Stat.DASHBOARD_CARD_PLANS_SHOWN, + mapOf(POSITION_INDEX to positionIndex) + ) + } } - private fun isCardHiddenByUser(siteId: Long): Boolean { - return appPrefsWrapper.getShouldHideDashboardPlansCard(siteId) + fun resetShown(){ + cardsShownTracked.clear() } - private fun positionIndex(siteSelected: SiteSelected?): Int { - return siteSelected - ?.dashboardData - ?.indexOfFirst { - it is DashboardPlansCard - } ?: -1 + private fun isCardHiddenByUser(siteId: Long): Boolean { + return appPrefsWrapper.getShouldHideDashboardPlansCard(siteId) } - private fun onDashboardRefreshed(siteSelected: SiteSelected?) { - plansCardVisible.get()?.let { isVisible -> - if (isVisible) trackCardShown(positionIndex(siteSelected)) - waitingToTrack.set(false) - } ?: run { - waitingToTrack.set(true) - } - } companion object { const val POSITION_INDEX = "position_index" - private const val CARD_VISIBLE_DEBOUNCE = 500L } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/plans/PlansCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/plans/PlansCardViewModelSlice.kt index 9b545ffcbde0..79490d4099fd 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/plans/PlansCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/plans/PlansCardViewModelSlice.kt @@ -59,4 +59,12 @@ class PlansCardViewModelSlice @Inject constructor( fun clearValue() { _uiModel.postValue(null) } + + fun trackShown(position: Int) { + dashboardCardPlansUtils.trackCardShown(position) + } + + fun resetShown() { + dashboardCardPlansUtils.resetShown() + } } From 15a8e83cd5c4073e22a77b4f9459f43bddfe61a1 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 14:41:51 +0530 Subject: [PATCH 183/250] =?UTF-8?q?=E2=86=92=20Moves:=20the=20logic=20to?= =?UTF-8?q?=20track=20cards=20to=20background?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/ui/mysite/MySiteViewModel.kt | 3 +- .../cards/DashboardCardsViewModelSlice.kt | 43 +++++++++++-------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 6ce0564f14f3..f99a37f02e54 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -159,7 +159,6 @@ class MySiteViewModel @Inject constructor( val state: LiveData = selectedSiteRepository.siteSelected.switchMap { _ -> isSiteSelected = true - resetShownTrackers() val result = MediatorLiveData() // We want to filter out the empty state where we have a site ID but site object is missing. @@ -464,12 +463,12 @@ class MySiteViewModel @Inject constructor( siteInfoHeaderCardViewModelSlice.buildCard(site) dashboardItemsViewModelSlice.clearValue() dashboardCardsViewModelSlice.clearValue() + dashboardCardsViewModelSlice.resetShownTracker() if (shouldShowDashboard(site)) { dashboardCardsViewModelSlice.buildCards(site) } else { dashboardItemsViewModelSlice.buildItems(site) } - } private fun onDashboardErrorRetry() { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index dda1c1f57750..c986e9d2a51b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -124,6 +124,8 @@ class DashboardCardsViewModelSlice @Inject constructor( ) }.distinctUntilChanged() as MutableLiveData> + + @SuppressWarnings("LongParameterList") private fun mergeUiModels( quicklinks: MySiteCardAndItem.Card.QuickLinksItem?, @@ -162,6 +164,7 @@ class DashboardCardsViewModelSlice @Inject constructor( noCardsMessageViewModelSlice.buildNoCardsMessage(cards)?.let { cards.add(it) } cards.add(it) } + if(cards.isNotEmpty()) trackCardShown(cards) return cards.toList() } @@ -218,30 +221,32 @@ class DashboardCardsViewModelSlice @Inject constructor( } } - fun trackCardShown(dashboardData: List){ - dashboardData.filterIsInstance().let { - cardViewModelSlice.trackCardShown(it) - } - dashboardData.filterIsInstance() - .forEach { jetpackInstallFullPluginCardViewModelSlice.trackShown(it) } + private fun trackCardShown(dashboardData: List) = with(dashboardData) { + scope.launch(bgDispatcher) { + filterIsInstance().let { + cardViewModelSlice.trackCardShown(it) + } + filterIsInstance() + .forEach { jetpackInstallFullPluginCardViewModelSlice.trackShown(it) } - dashboardData.filterIsInstance() - .forEach { domainRegistrationCardViewModelSlice.trackShown(it) } + filterIsInstance() + .forEach { domainRegistrationCardViewModelSlice.trackShown(it) } - dashboardData.filterIsInstance().forEach { - personalizeCardViewModelSlice.trackShown(it) - } + filterIsInstance().forEach { + personalizeCardViewModelSlice.trackShown(it) + } - dashboardData.filterIsInstance().forEach { - quickStartCardViewModelSlice.trackShown(it) - } + filterIsInstance().forEach { + quickStartCardViewModelSlice.trackShown(it) + } - dashboardData.filterIsInstance().forEach { - noCardsMessageViewModelSlice.trackShown(it.type) - } + filterIsInstance().forEach { + noCardsMessageViewModelSlice.trackShown(it.type) + } - dashboardData.filterIsInstance< MySiteCardAndItem.Card.DashboardPlansCard>().forEachIndexed { index, _ -> - plansCardViewModelSlice.trackShown(index) + filterIsInstance().forEachIndexed { index, _ -> + plansCardViewModelSlice.trackShown(index) + } } } From 7c4ede01d9677e3cd02bfc7742f623cc851e81e6 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 15:08:28 +0530 Subject: [PATCH 184/250] + Adds: logic for tracking quick links --- .../ui/mysite/cards/dashboard/CardsShownTracker.kt | 9 ++++++++- .../android/ui/mysite/cards/dashboard/CardsTracker.kt | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsShownTracker.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsShownTracker.kt index b44603409753..a8e1fd066c8a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsShownTracker.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsShownTracker.kt @@ -11,8 +11,8 @@ import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.PostCard import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.PostCard.PostCardWithPostItems import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.TodaysStatsCard import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.TodaysStatsCard.TodaysStatsCardWithData -import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.StatsSubtype import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.BlazeSubtype +import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.StatsSubtype import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.Type import org.wordpress.android.ui.quickstart.QuickStartType import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper @@ -108,6 +108,13 @@ class CardsShownTracker @Inject constructor( ) ) + is Card.QuickLinksItem -> trackCardShown( + Pair( + card.type.toTypeValue().label, + Type.QUICK_LINKS.label + ) + ) + else -> {} } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsTracker.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsTracker.kt index 3edb514050f6..1be0c79c980f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsTracker.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsTracker.kt @@ -19,6 +19,7 @@ class CardsTracker @Inject constructor( ) { enum class Type(val label: String) { ERROR("error"), + QUICK_LINKS("quick_links"), QUICK_START("quick_start"), STATS("stats"), POST("post"), @@ -128,6 +129,7 @@ class CardsTracker @Inject constructor( fun MySiteCardAndItem.Type.toTypeValue(): Type { return when (this) { MySiteCardAndItem.Type.ERROR_CARD -> Type.ERROR + MySiteCardAndItem.Type.QUICK_LINK_RIBBON -> Type.QUICK_LINKS MySiteCardAndItem.Type.QUICK_START_CARD -> Type.QUICK_START MySiteCardAndItem.Type.TODAYS_STATS_CARD_ERROR -> Type.ERROR MySiteCardAndItem.Type.TODAYS_STATS_CARD -> Type.STATS From 275b8ee4c4edc2bf689203bc426a676978dae734 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 8 Feb 2024 15:09:11 +0530 Subject: [PATCH 185/250] + Adds: a check for tracking job and cancellation * Fixes: the no cards message being tracked incorrectly --- .idea/codeStyles/Project.xml | 4 +--- .../mysite/cards/DashboardCardsViewModelSlice.kt | 14 ++++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index a145657e502b..5ee4f2b40452 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -35,8 +35,6 @@ - + , sourceB: LiveData, diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt index 4503ccd0a882..8934898748b2 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt @@ -249,7 +249,6 @@ class MySiteViewModelTest : BaseUnitTest() { private val siteName = "Site" private val emailAddress = "test@email.com" private val localHomepageId = 1 - private val bloggingPromptId = 123 private lateinit var site: SiteModel private lateinit var homepage: PageModel private val onSiteChange = MutableLiveData() From eadab98b6276366a4c1448eec1de7ebea427bb89 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 12:57:42 +0530 Subject: [PATCH 200/250] * Fixes: test dependancies --- .../DashboardCardsViewModelSliceTest.kt | 25 ++++++------------- .../DashboardItemsViewModelSliceTest.kt | 12 ++++----- ...InstallFullPluginCardViewModelSliceTest.kt | 12 ++++++--- .../dashboard/CardsViewModelSliceTest.kt | 5 ++++ .../ActivityLogCardViewModelSliceTest.kt | 5 ---- .../pages/PagesCardViewModelSliceTest.kt | 16 ++++++------ .../posts/PostsCardViewModelSliceTest.kt | 5 ---- .../TodaysStatsViewModelSliceTest.kt | 5 ---- ...omainRegistrationCardViewModelSliceTest.kt | 7 +++++- .../PersonalizeCardViewModelSliceTest.kt | 5 ++-- .../SiteInfoHeaderCardViewModelSliceTest.kt | 2 +- .../listitem/SiteItemsViewModelSliceTest.kt | 9 +++---- 12 files changed, 51 insertions(+), 57 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt index 93810fcd93ae..ac4a7976c4ca 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt @@ -30,7 +30,6 @@ import org.wordpress.android.ui.mysite.cards.personalize.PersonalizeCardViewMode import org.wordpress.android.ui.mysite.cards.plans.PlansCardViewModelSlice import org.wordpress.android.ui.mysite.cards.quicklinksitem.QuickLinksItemViewModelSlice import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardViewModelSlice -import org.wordpress.android.util.BuildConfigWrapper @ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) @@ -61,8 +60,6 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { lateinit var plansCardViewModelSlice: PlansCardViewModelSlice @Mock lateinit var selectedSiteRepository: SelectedSiteRepository - @Mock - lateinit var buildConfigWrapper: BuildConfigWrapper private lateinit var dashboardCardsViewModelSlice: DashboardCardsViewModelSlice @@ -81,6 +78,7 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { whenever(plansCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) dashboardCardsViewModelSlice = DashboardCardsViewModelSlice( + testDispatcher(), jpMigrationSuccessCardViewModelSlice, jetpackInstallFullPluginCardViewModelSlice, domainRegistrationCardViewModelSlice, @@ -93,8 +91,7 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { quickLinksItemViewModelSlice, bloganuaryNudgeCardViewModelSlice, plansCardViewModelSlice, - selectedSiteRepository, - buildConfigWrapper + selectedSiteRepository ) } @@ -116,11 +113,10 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { @Test fun `given showDashboardCards is true, when onResume, then should build cards`() = test { val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onResume(mockSite) + dashboardCardsViewModelSlice.buildCards(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() @@ -138,11 +134,10 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { @Test fun `given showDashboardCards is false, when onResume, then should not build cards`() = test { val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onResume(mockSite) + dashboardCardsViewModelSlice.buildCards(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() @@ -160,11 +155,10 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { @Test fun `given showDashboardCards is true, when onRefresh, then should build cards`() = test { val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onRefresh(mockSite) + dashboardCardsViewModelSlice.buildCards(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() @@ -182,11 +176,10 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { @Test fun `given showDashboardCards is false, when onRefresh, then should not build cards`() = test { val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onRefresh(mockSite) + dashboardCardsViewModelSlice.buildCards(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() @@ -204,12 +197,11 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { @Test fun `given showDashboardCards is true, when onSiteChanged, then should build cards`() = test { val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onSiteChanged(mockSite) + dashboardCardsViewModelSlice.buildCards(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() @@ -227,12 +219,11 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { @Test fun `given showDashboardCards is false, when onSiteChanged, then should not build cards`() = test { val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) whenever(mockSite.isUsingWpComRestApi).thenReturn(true) whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.onSiteChanged(mockSite) + dashboardCardsViewModelSlice.buildCards(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt index 1d6ef40a7a11..02ea1c2a482e 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt @@ -70,13 +70,13 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { whenever(sotw2023NudgeCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) dashboardItemsViewModelSlice = DashboardItemsViewModelSlice( + testDispatcher(), jetpackFeatureCardViewModelSlice, jetpackSwitchMenuViewModelSlice, jetpackBadgeViewModelSlice, siteItemsViewModelSlice, sotw2023NudgeCardViewModelSlice, - jetpackFeatureCardHelper, - buildConfigWrapper + jetpackFeatureCardHelper ) navigationActions = mutableListOf() @@ -111,7 +111,7 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { whenever(mockSite.isUsingWpComRestApi).thenReturn(true) dashboardItemsViewModelSlice.initialize(testScope()) - dashboardItemsViewModelSlice.onResume(mockSite) + dashboardItemsViewModelSlice.buildItems(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(siteItemsViewModelSlice, never()).buildSiteItems(any()) @@ -126,7 +126,7 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { dashboardItemsViewModelSlice.initialize(testScope()) - dashboardItemsViewModelSlice.onResume(mockSite) + dashboardItemsViewModelSlice.buildItems(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(siteItemsViewModelSlice, atLeastOnce()).buildSiteItems(any()) @@ -144,7 +144,7 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { whenever(mockSite.isUsingWpComRestApi).thenReturn(true) dashboardItemsViewModelSlice.initialize(testScope()) - dashboardItemsViewModelSlice.onRefresh(mockSite) + dashboardItemsViewModelSlice.buildItems(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(siteItemsViewModelSlice, never()).buildSiteItems(any()) @@ -159,7 +159,7 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { dashboardItemsViewModelSlice.initialize(testScope()) - dashboardItemsViewModelSlice.onRefresh(mockSite) + dashboardItemsViewModelSlice.buildItems(mockSite) verify(selectedSiteRepository).getSelectedSite() verify(siteItemsViewModelSlice, atLeastOnce()).buildSiteItems(any()) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/JetpackInstallFullPluginCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/JetpackInstallFullPluginCardViewModelSliceTest.kt index 6f8efd1aa042..cea94977cc53 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/JetpackInstallFullPluginCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/JetpackInstallFullPluginCardViewModelSliceTest.kt @@ -3,8 +3,6 @@ package org.wordpress.android.ui.mysite.cards import kotlinx.coroutines.ExperimentalCoroutinesApi import org.assertj.core.api.Assertions.assertThat import org.junit.Assert.assertTrue -import org.mockito.kotlin.mock -import org.mockito.kotlin.whenever import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -12,11 +10,14 @@ import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.any import org.mockito.kotlin.doReturn +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.JetpackInstallFullPluginCard import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.cards.jpfullplugininstall.JetpackInstallFullPluginCardViewModelSlice +import org.wordpress.android.ui.mysite.cards.jpfullplugininstall.JetpackInstallFullPluginShownTracker import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper @@ -32,6 +33,10 @@ class JetpackInstallFullPluginCardViewModelSliceTest : BaseUnitTest() { @Mock lateinit var analyticsTrackerWrapper: AnalyticsTrackerWrapper + @Mock + lateinit var jetpackInstallFullPluginShownTracker: JetpackInstallFullPluginShownTracker + + private lateinit var uiModels: MutableList private lateinit var viewModel: JetpackInstallFullPluginCardViewModelSlice @@ -54,7 +59,8 @@ class JetpackInstallFullPluginCardViewModelSliceTest : BaseUnitTest() { viewModel = JetpackInstallFullPluginCardViewModelSlice( appPrefsWrapper, selectedSiteRepository, - analyticsTrackerWrapper + analyticsTrackerWrapper, + jetpackInstallFullPluginShownTracker ) uiModels = mutableListOf() viewModel.uiModel.observeForever { event -> diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt index 1d04f8acd25c..9c0f6b868a47 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt @@ -237,12 +237,16 @@ class CardsViewModelSliceTest : BaseUnitTest() { @Mock lateinit var buildConfigWrapper: BuildConfigWrapper + @Mock lateinit var preferenceUtilsWrapper: PreferenceUtilsWrapper @Mock lateinit var sharedPreferences: SharedPreferences + @Mock + lateinit var cardTracker: CardsTracker + private lateinit var viewModelSlice: CardViewModelSlice private lateinit var defaultFetchCardsPayload: FetchCardsPayload @@ -276,6 +280,7 @@ class CardsViewModelSliceTest : BaseUnitTest() { activityLogCardViewModelSlice, preferenceUtilsWrapper, buildConfigWrapper, + cardTracker ) defaultFetchCardsPayload = FetchCardsPayload( siteModel, diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSliceTest.kt index 5eab4d4b556d..78a9bef02b53 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSliceTest.kt @@ -60,11 +60,6 @@ class ActivityLogCardViewModelSliceTest : BaseUnitTest() { } } refreshEvents = mutableListOf() - activityLogCardViewModelSlice.refresh.observeForever { event -> - event?.getContentIfNotHandled()?.let { - refreshEvents.add(it) - } - } whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSliceTest.kt index cc0432c0c89e..b4ace24de8dd 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/pages/PagesCardViewModelSliceTest.kt @@ -12,6 +12,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.PagesCardBuilderParams.PagesItemClickParams import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.SiteNavigationAction @@ -39,7 +40,7 @@ class PagesCardViewModelSliceTest : BaseUnitTest() { private lateinit var navigationActions: MutableList - private lateinit var refreshEvents: MutableList + private lateinit var uiModels: MutableList private val site = mock() @@ -57,12 +58,13 @@ class PagesCardViewModelSliceTest : BaseUnitTest() { navigationActions.add(it) } } - refreshEvents = mutableListOf() - pagesCardViewModelSlice.refresh.observeForever { event -> - event?.getContentIfNotHandled()?.let { - refreshEvents.add(it) - } + + uiModels = mutableListOf() + + pagesCardViewModelSlice.uiModel.observeForever { + uiModels.add(it) } + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) } @@ -161,6 +163,6 @@ class PagesCardViewModelSliceTest : BaseUnitTest() { CardsTracker.Type.PAGES.label, PagesMenuItemType.HIDE_THIS.label ) - assertThat(refreshEvents).containsOnly(true) + assertThat(uiModels.last()).isNull() } } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSliceTest.kt index 1e3928912836..fbf490438926 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSliceTest.kt @@ -62,11 +62,6 @@ class PostsCardViewModelSliceTest : BaseUnitTest() { } refreshEvents = mutableListOf() - postsCardViewModelSlice.refresh.observeForever { event -> - event?.getContentIfNotHandled()?.let { - refreshEvents.add(it) - } - } whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSliceTest.kt index d08f613bceb5..2a6cccd0128f 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSliceTest.kt @@ -60,11 +60,6 @@ class TodaysStatsViewModelSliceTest : BaseUnitTest() { } } refreshEvents = mutableListOf() - todaysStatsViewModelSlice.refresh.observeForever { event -> - event?.getContentIfNotHandled()?.let { - refreshEvents.add(it) - } - } whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt index e8ce4a919e53..c405a6c97c9f 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt @@ -24,6 +24,7 @@ import org.wordpress.android.fluxc.utils.AppLogWrapper import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.SiteNavigationAction +import org.wordpress.android.ui.mysite.cards.DomainRegistrationCardShownTracker import org.wordpress.android.ui.plans.PlansConstants.PREMIUM_PLAN_ID import org.wordpress.android.util.SiteUtilsWrapper @@ -45,6 +46,9 @@ class DomainRegistrationCardViewModelSliceTest : BaseUnitTest() { @Mock lateinit var domainRegistrationTracker: DomainRegistrationTracker + @Mock + lateinit var domainRegistrationCardTracker: DomainRegistrationCardShownTracker + private val siteLocalId = 1 private val site = SiteModel() private lateinit var result: MutableList @@ -62,7 +66,8 @@ class DomainRegistrationCardViewModelSliceTest : BaseUnitTest() { selectedSiteRepository, appLogWrapper, siteUtils, - domainRegistrationTracker + domainRegistrationTracker, + domainRegistrationCardTracker ) viewModelSlice.initialize(testScope()) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSliceTest.kt index b04a93600c1f..bba630a7b603 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSliceTest.kt @@ -1,12 +1,13 @@ package org.wordpress.android.ui.mysite.cards.personalize import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock -import org.assertj.core.api.Assertions.assertThat import org.mockito.junit.MockitoJUnitRunner +import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.wordpress.android.BaseUnitTest import org.wordpress.android.ui.mysite.MySiteCardAndItem @@ -68,7 +69,7 @@ class PersonalizeCardViewModelSliceTest : BaseUnitTest() { @Test fun `given personalize card, when card shown track requested, then track card shown`() = test { - viewModelSlice.trackShown(MySiteCardAndItem.Type.PERSONALIZE_CARD) + viewModelSlice.trackShown(mock()) verify(personalizeCardShownTracker).trackShown(MySiteCardAndItem.Type.PERSONALIZE_CARD) } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt index 165bb53f6883..6053f6cc03d7 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSliceTest.kt @@ -475,7 +475,7 @@ class SiteInfoHeaderCardViewModelSliceTest : BaseUnitTest() { clearInvocations(siteInfoHeaderCardBuilder) - viewModelSlice.onResume(siteModel) + viewModelSlice.buildCard(siteModel) verify(siteInfoHeaderCardBuilder).buildSiteInfoCard(any()) } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSliceTest.kt index 9c5435d92d55..1a06bdbdbdf5 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSliceTest.kt @@ -50,7 +50,7 @@ class SiteItemsViewModelSliceTest : BaseUnitTest() { private lateinit var snackBarMessages: MutableList - private lateinit var uiModels: MutableList> + private lateinit var uiModels: MutableList?> private val site = SiteModel() @@ -120,7 +120,7 @@ class SiteItemsViewModelSliceTest : BaseUnitTest() { siteItemsViewModelSlice.buildSiteItems(site = site) // Then - assertThat(uiModels.last().find { it?.type == MySiteCardAndItem.Type.PROMOTE_WITH_BLAZE_CARD }).isNotNull + assertThat(uiModels.last()?.find { it.type == MySiteCardAndItem.Type.PROMOTE_WITH_BLAZE_CARD }).isNotNull } @Test @@ -133,7 +133,7 @@ class SiteItemsViewModelSliceTest : BaseUnitTest() { siteItemsViewModelSlice.buildSiteItems(site = site) // Then - assertThat(uiModels.last().find { it?.type == MySiteCardAndItem.Type.PROMOTE_WITH_BLAZE_CARD }).isNull() + assertThat(uiModels.last()?.find { it.type == MySiteCardAndItem.Type.PROMOTE_WITH_BLAZE_CARD }).isNull() } private fun invokeItemClickAction( @@ -141,8 +141,7 @@ class SiteItemsViewModelSliceTest : BaseUnitTest() { ) = test { siteItemsViewModelSlice.buildSiteItems(site) val listItem = - ((uiModels.last()) - .find { it is MySiteCardAndItem.Item.ListItem } as MySiteCardAndItem.Item.ListItem) + ((uiModels.last())?.find { it is MySiteCardAndItem.Item.ListItem } as MySiteCardAndItem.Item.ListItem) .takeIf { it.listItemAction == action } listItem?.onClick?.click() } From 594d7634f7de64cdc602327a09c0fdedec8b913e Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 13:58:13 +0530 Subject: [PATCH 201/250] Fixes: ActivityLogCardViewModelSliceTest --- .../activity/ActivityLogCardViewModelSliceTest.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSliceTest.kt index 78a9bef02b53..421c35460ce2 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/activity/ActivityLogCardViewModelSliceTest.kt @@ -13,6 +13,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.ActivityCardBuilderParams.ActivityCardItemClickParams import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.SiteNavigationAction @@ -38,7 +39,7 @@ class ActivityLogCardViewModelSliceTest : BaseUnitTest() { private lateinit var navigationActions: MutableList - private lateinit var refreshEvents: MutableList + private lateinit var uiModels : MutableList private val site = mock() @@ -59,7 +60,12 @@ class ActivityLogCardViewModelSliceTest : BaseUnitTest() { navigationActions.add(it) } } - refreshEvents = mutableListOf() + + uiModels = mutableListOf() + activityLogCardViewModelSlice.uiModel.observeForever { uiModel -> + uiModels.add(uiModel) + } + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) } @@ -113,11 +119,11 @@ class ActivityLogCardViewModelSliceTest : BaseUnitTest() { params.onHideMenuItemClick() - Assertions.assertThat(refreshEvents).containsOnly(true) verify(cardsTracker).trackCardMoreMenuItemClicked( CardsTracker.Type.ACTIVITY.label, ActivityLogCardViewModelSlice.MenuItemType.HIDE_THIS.label ) verify(appPrefsWrapper).setShouldHideActivityDashboardCard(any(), any()) + Assertions.assertThat(uiModels.last()).isNull() } } From e5766894a6e345cd3c67b3b657d5c25f379db47c Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 15:15:23 +0530 Subject: [PATCH 202/250] - Removes: BlazeCardSourceTest.kt --- .../ui/mysite/cards/dashboard/blaze/BlazeCardSourceTest.kt | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/blaze/BlazeCardSourceTest.kt diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/blaze/BlazeCardSourceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/blaze/BlazeCardSourceTest.kt deleted file mode 100644 index e69de29bb2d1..000000000000 From a2c7a3b64f0aabf1c50059f5262e3fc8c738a9ae Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 15:17:20 +0530 Subject: [PATCH 203/250] * Fixes: TodaysStatsViewModelSliceTest --- .../todaysstats/TodaysStatsViewModelSliceTest.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSliceTest.kt index 2a6cccd0128f..417d24ae3ef3 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/todaysstats/TodaysStatsViewModelSliceTest.kt @@ -13,6 +13,7 @@ import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhaseHelper +import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.SiteNavigationAction import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker @@ -40,7 +41,7 @@ class TodaysStatsViewModelSliceTest : BaseUnitTest() { private lateinit var navigationActions: MutableList - private lateinit var refreshEvents: MutableList + private lateinit var uiModels : MutableList private val site = mock() @@ -59,7 +60,10 @@ class TodaysStatsViewModelSliceTest : BaseUnitTest() { navigationActions.add(it) } } - refreshEvents = mutableListOf() + + uiModels = mutableListOf() + todaysStatsViewModelSlice.uiModel.observeForever { uiModels.add(it) } + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) } @@ -134,6 +138,6 @@ class TodaysStatsViewModelSliceTest : BaseUnitTest() { CardsTracker.Type.STATS.label, TodaysStatsMenuItemType.HIDE_THIS.label ) - assertThat(refreshEvents).containsOnly(true) + assertThat(uiModels.last()).isNull() } } From 168c7c8de43bfb07bfa08fafb8f6c786d34292bb Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 15:25:33 +0530 Subject: [PATCH 204/250] * Fixes: PostsCardViewModelSliceTest --- .../dashboard/posts/PostsCardViewModelSliceTest.kt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSliceTest.kt index fbf490438926..5f4016eb0352 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/posts/PostsCardViewModelSliceTest.kt @@ -12,6 +12,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.SiteNavigationAction @@ -41,7 +42,7 @@ class PostsCardViewModelSliceTest : BaseUnitTest() { private lateinit var navigationActions: MutableList - private lateinit var refreshEvents: MutableList + private lateinit var uiModels : MutableList?> private val postId = 100 @@ -61,7 +62,11 @@ class PostsCardViewModelSliceTest : BaseUnitTest() { } } - refreshEvents = mutableListOf() + uiModels = mutableListOf() + postsCardViewModelSlice.uiModel.observeForever { uiModels.add(it) } + + + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) } @@ -172,7 +177,7 @@ class PostsCardViewModelSliceTest : BaseUnitTest() { verify(appPrefsWrapper).setShouldHidePostDashboardCard(siteId, PostCardType.DRAFT.name, true) - assertThat(refreshEvents).containsOnly(true) + assertThat(uiModels.last()).isNull() } @Test @@ -201,7 +206,7 @@ class PostsCardViewModelSliceTest : BaseUnitTest() { verify(appPrefsWrapper).setShouldHidePostDashboardCard(siteId, PostCardType.SCHEDULED.name, true) - assertThat(refreshEvents).containsOnly(true) + assertThat(uiModels.last()).isNull() } @Test From c3c773c0eb692d13dad1ff16690ce261824e1b60 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 15:51:50 +0530 Subject: [PATCH 205/250] * Fixes: unit tests in PersonalizeCardViewModelSliceTest --- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 2 +- .../mysite/cards/personalize/PersonalizeCardViewModelSlice.kt | 4 ++-- .../cards/personalize/PersonalizeCardViewModelSliceTest.kt | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 7ac52cab62c4..773dc20c1aad 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -238,7 +238,7 @@ class DashboardCardsViewModelSlice @Inject constructor( .forEach { domainRegistrationCardViewModelSlice.trackShown(it) } filterIsInstance().forEach { - personalizeCardViewModelSlice.trackShown(it) + personalizeCardViewModelSlice.trackShown() } filterIsInstance().forEach { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt index 8d07efd0b8f2..a06e51451eb9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSlice.kt @@ -44,8 +44,8 @@ class PersonalizeCardViewModelSlice @Inject constructor( _onNavigation.value = Event(OpenDashboardPersonalization) } - fun trackShown(card: MySiteCardAndItem.Card.PersonalizeCardModel) { - personalizeCardShownTracker.trackShown(card.type) + fun trackShown() { + personalizeCardShownTracker.trackShown(MySiteCardAndItem.Type.PERSONALIZE_CARD) } fun resetShown() { diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSliceTest.kt index bba630a7b603..6fddfc64fb9e 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSliceTest.kt @@ -7,7 +7,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner -import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.wordpress.android.BaseUnitTest import org.wordpress.android.ui.mysite.MySiteCardAndItem @@ -69,7 +68,7 @@ class PersonalizeCardViewModelSliceTest : BaseUnitTest() { @Test fun `given personalize card, when card shown track requested, then track card shown`() = test { - viewModelSlice.trackShown(mock()) + viewModelSlice.trackShown() verify(personalizeCardShownTracker).trackShown(MySiteCardAndItem.Type.PERSONALIZE_CARD) } From f0e1c1c4a211b5eab8980c1f9c3b19bcb7e2728f Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 15:56:26 +0530 Subject: [PATCH 206/250] * Fixes: unit tests in BlazeCardViewModelSliceTest --- .../android/ui/mysite/BlazeCardViewModelSliceTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSliceTest.kt index b6f51ddc7648..36b822c9bf87 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/BlazeCardViewModelSliceTest.kt @@ -135,13 +135,13 @@ class BlazeCardViewModelSliceTest : BaseUnitTest() { whenever(blazeFeatureUtils.shouldShowBlazeCardEntryPoint(any())).thenReturn(true) whenever(blazeFeatureUtils.shouldShowBlazeCampaigns()).thenReturn(true) whenever(networkUtilsWrapper.isNetworkAvailable()).thenReturn(true) - whenever(fetchCampaignListUseCase.execute(any(), any())).thenReturn(mock()) + whenever(fetchCampaignListUseCase.execute(any(), any(), any())).thenReturn(mock()) // When blazeCardViewModelSlice.buildCard(mock()) // Then - verify(fetchCampaignListUseCase).execute(any(), any()) + verify(fetchCampaignListUseCase).execute(any(), any(), any()) } @Test @@ -150,13 +150,13 @@ class BlazeCardViewModelSliceTest : BaseUnitTest() { whenever(blazeFeatureUtils.shouldShowBlazeCardEntryPoint(any())).thenReturn(true) whenever(blazeFeatureUtils.shouldShowBlazeCampaigns()).thenReturn(true) whenever(networkUtilsWrapper.isNetworkAvailable()).thenReturn(true) - whenever(fetchCampaignListUseCase.execute(any(), any())).thenReturn(mock()) + whenever(fetchCampaignListUseCase.execute(any(), any(), any())).thenReturn(mock()) // When blazeCardViewModelSlice.buildCard(mock()) // Then - verify(fetchCampaignListUseCase).execute(any(), any()) + verify(fetchCampaignListUseCase).execute(any(), any(), any()) } @Test From 0bde4e63701e6e7fc8fff9a9877091a9db5fa2fe Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 16:04:19 +0530 Subject: [PATCH 207/250] - Removes: Ignore message in BloganuaryNudgeCardViewModelSliceTest --- .../bloganuary/BloganuaryNudgeCardViewModelSliceTest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloganuary/BloganuaryNudgeCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloganuary/BloganuaryNudgeCardViewModelSliceTest.kt index ed7dca7a9f49..5e77a0d44c67 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloganuary/BloganuaryNudgeCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloganuary/BloganuaryNudgeCardViewModelSliceTest.kt @@ -4,7 +4,6 @@ import android.icu.util.Calendar import kotlinx.coroutines.ExperimentalCoroutinesApi import org.assertj.core.api.Assertions.assertThat import org.junit.Before -import org.junit.Ignore import org.junit.Test import org.mockito.Mock import org.mockito.Mockito @@ -27,7 +26,6 @@ import org.wordpress.android.util.DateTimeUtilsWrapper import org.wordpress.android.util.config.BloganuaryNudgeFeatureConfig @OptIn(ExperimentalCoroutinesApi::class) -@Ignore("Update tests to work with new architecture") class BloganuaryNudgeCardViewModelSliceTest : BaseUnitTest() { @Mock lateinit var bloganuaryNudgeFeatureConfig: BloganuaryNudgeFeatureConfig From 96824dfaf84a6ceaa32a89b625606e877cb4d962 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 16:11:16 +0530 Subject: [PATCH 208/250] * Fixes: Check style issues --- .../BloggingPromptCardViewModelSlice.kt | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index cfa5b331c061..5ffeaf660d5e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -195,18 +195,9 @@ class BloggingPromptCardViewModelSlice @Inject constructor( } } - - /** - * This function is used to make sure the [refresh] information is propagated and processed correctly even though - * the previous status is still the current one. This avoids issues like the loading progress indicator being shown - * indefinitely. - * - * Also, for this card source, this can be used as the error state as we don't have any special error handling at - * this point, so we just show the last available prompt. - */ + // this function is called when there is no change in the data, this just updates the loading state to false private fun postLastState() { _isRefreshing.postValue(false) - //do nothing WIP @ajesh: remove this once this case doesnt occur on the new architecture } private fun postEmptyState() { From 96be2fa3e8f613c6a25b16d465fd0702148d27f2 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 11 Mar 2024 17:33:32 +0530 Subject: [PATCH 209/250] [WIP] Fixes: CardsViewModelSliceTest --- .../cards/dashboard/CardsViewModelSliceTest.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt index 9c0f6b868a47..5208720d6526 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt @@ -1,6 +1,7 @@ package org.wordpress.android.ui.mysite.cards.dashboard import android.content.SharedPreferences +import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.single @@ -11,6 +12,7 @@ import org.junit.Test import org.mockito.Mock import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull +import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest @@ -267,6 +269,13 @@ class CardsViewModelSliceTest : BaseUnitTest() { @Before fun setUp() { + whenever(dynamicCardsViewModelSlice.topDynamicCards).thenReturn(MutableLiveData()) + whenever(dynamicCardsViewModelSlice.bottomDynamicCards).thenReturn(MutableLiveData()) + whenever(todaysStatsViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(pagesCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(postsCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(activityLogCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + viewModelSlice = CardViewModelSlice( cardsStore, dashboardActivityLogCardFeatureUtils, @@ -291,6 +300,7 @@ class CardsViewModelSliceTest : BaseUnitTest() { MARKETING_VERSION_PARAM, PLATFORM_PARAM ) + viewModelSlice.initialize(testScope()) result = emptyList() @@ -455,6 +465,7 @@ class CardsViewModelSliceTest : BaseUnitTest() { val testData = CardsResult(model = listOf(TODAYS_STATS_CARDS_MODEL, POSTS_MODEL)) whenever(cardsStore.getCards(siteModel)).thenReturn(flowOf(CardsResult(model = testData.model))) whenever(cardsStore.fetchCards(defaultFetchCardsPayload)).thenReturn(success).thenReturn(apiError) + whenever(todaysStatsViewModelSlice.uiModel).thenReturn(mock()) viewModelSlice.buildCard(siteModel) @@ -480,8 +491,7 @@ class CardsViewModelSliceTest : BaseUnitTest() { viewModelSlice.buildCard(siteModel) assertThat(isRefreshing.size).isEqualTo(2) - assertThat(isRefreshing.first()).isFalse - assertThat(isRefreshing.last()).isTrue + assertThat(isRefreshing.first()).isTrue() } @Test From 5a5f054dd8fc0988812228eaa11bdcaeb1b09843 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Tue, 12 Mar 2024 11:45:56 +0530 Subject: [PATCH 210/250] Fixes: CardsViewModelSliceTest --- .../dashboard/CardsViewModelSliceTest.kt | 60 ++----------------- 1 file changed, 4 insertions(+), 56 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt index 5208720d6526..90daaad5caaa 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsViewModelSliceTest.kt @@ -12,7 +12,6 @@ import org.junit.Test import org.mockito.Mock import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull -import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest @@ -36,7 +35,6 @@ import org.wordpress.android.fluxc.store.dashboard.CardsStore.CardsErrorType import org.wordpress.android.fluxc.store.dashboard.CardsStore.CardsResult import org.wordpress.android.fluxc.tools.FormattableContent import org.wordpress.android.fluxc.utils.PreferenceUtils.PreferenceUtilsWrapper -import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.CardsUpdate import org.wordpress.android.ui.mysite.cards.dashboard.activity.ActivityLogCardViewModelSlice import org.wordpress.android.ui.mysite.cards.dashboard.activity.DashboardActivityLogCardFeatureUtils import org.wordpress.android.ui.mysite.cards.dashboard.pages.PagesCardViewModelSlice @@ -320,7 +318,6 @@ class CardsViewModelSliceTest : BaseUnitTest() { isTodaysStatsCardHidden: Boolean = false, isDynamicCardsEnabled: Boolean = false, ) { - whenever(siteModel.id).thenReturn(SITE_LOCAL_ID) whenever(dashboardActivityLogCardFeatureUtils.shouldRequestActivityCard(siteModel)) .thenReturn(isDashboardCardActivityLogEnabled) whenever(siteModel.hasCapabilityEditPages).thenReturn(isRequestPages) @@ -417,9 +414,8 @@ class CardsViewModelSliceTest : BaseUnitTest() { } @Test - fun `given error, when build is invoked, then error snackbar with stale message is also shown (network)`() = test { + fun `given error, when build is invoked, then error message is shown (network)`() = test { setUpMocks() - val result = mutableListOf() val testData = CardsResult(model = listOf(TODAYS_STATS_CARDS_MODEL, POSTS_MODEL)) whenever(cardsStore.getCards(siteModel)).thenReturn(flowOf(CardsResult(model = testData.model))) whenever(cardsStore.fetchCards(defaultFetchCardsPayload)).thenReturn(apiError) @@ -430,24 +426,11 @@ class CardsViewModelSliceTest : BaseUnitTest() { advanceUntilIdle() assertThat(result.size).isEqualTo(2) - assertThat(result[0]).isEqualTo( - CardsUpdate( - cards = testData.model, - showSnackbarError = false, - showStaleMessage = false - ) - ) - assertThat(result[1]).isEqualTo( - CardsUpdate( - cards = testData.model, - showSnackbarError = true, - showStaleMessage = true - ) - ) + assertThat(result.last()).isInstanceOf(CardsState.ErrorState::class.java) } @Test - fun `given no error, when refresh is invoked, then data is only loaded from get cards (database)`() = test { + fun `given no error, when build is invoked, then data is only loaded from get cards (database)`() = test { setUpMocks() val filteredData = CardsResult(model = data.model?.filterIsInstance()?.toList()) whenever(cardsStore.getCards(siteModel)).thenReturn(flowOf(CardsResult(model = filteredData.model))) @@ -456,30 +439,7 @@ class CardsViewModelSliceTest : BaseUnitTest() { viewModelSlice.buildCard(siteModel) assertThat(result.size).isEqualTo(1) - assertThat(result.first()).isEqualTo(CardsUpdate(filteredData.model)) - } - - @Test - fun `given error, when refresh is invoked, then error snackbar with stale message also shown (network)`() = test { - setUpMocks() - val testData = CardsResult(model = listOf(TODAYS_STATS_CARDS_MODEL, POSTS_MODEL)) - whenever(cardsStore.getCards(siteModel)).thenReturn(flowOf(CardsResult(model = testData.model))) - whenever(cardsStore.fetchCards(defaultFetchCardsPayload)).thenReturn(success).thenReturn(apiError) - whenever(todaysStatsViewModelSlice.uiModel).thenReturn(mock()) - - viewModelSlice.buildCard(siteModel) - - advanceUntilIdle() - - assertThat(result.size).isEqualTo(2) - assertThat(result.first()).isEqualTo(CardsUpdate(testData.model)) - assertThat(result.last()).isEqualTo( - CardsUpdate( - cards = testData.model, - showSnackbarError = true, - showStaleMessage = true - ) - ) + assertThat(result.first()).isInstanceOf(CardsState.Success::class.java) } /* IS REFRESHING */ @@ -551,18 +511,6 @@ class CardsViewModelSliceTest : BaseUnitTest() { assertThat(result.last()).isInstanceOf(CardsState.ErrorState::class.java) } - @Test - fun `given invalid site, when refresh is invoked, then error card is shown`() = test { - val result = mutableListOf() - viewModelSlice.refresh.observeForever { } - - viewModelSlice.buildCard(siteModel) - - assertThat(result.size).isEqualTo(2) - assertThat(result.first()).isEqualTo(CardsUpdate(showErrorCard = true)) - assertThat(result.last()).isEqualTo(CardsUpdate(showErrorCard = true)) - } - @Test fun `given pages feature enabled + card not hidden, when refresh is invoked, then pages requested from network`() = test { From 9a728de4fa022c4cc1208e89ab2fe82841a6940e Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Tue, 12 Mar 2024 12:37:35 +0530 Subject: [PATCH 211/250] + Adds: clear value function to DomainRegistrationCardViewModelSlice --- .../DomainRegistrationCardViewModelSlice.kt | 8 ++++++-- .../DomainRegistrationCardViewModelSliceTest.kt | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt index c12f81bc192e..bbf3cb08f363 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt @@ -45,8 +45,8 @@ class DomainRegistrationCardViewModelSlice @Inject constructor( private val _isRefreshing = MutableLiveData() val isRefreshing: LiveData = _isRefreshing - private val _uiModel = MutableLiveData() - val uiModel: LiveData = _uiModel + private val _uiModel = MutableLiveData() + val uiModel: MutableLiveData = _uiModel private val _onNavigation = MutableLiveData>() val onNavigation = _onNavigation @@ -148,6 +148,10 @@ class DomainRegistrationCardViewModelSlice @Inject constructor( fun resetCardShown() { domainRegistrationCardShownTracker.resetShown() } + + fun clearValue() { + _uiModel.postValue(null) + } } /* This class is a helper to offset the AppLogWrapper dependency conflict (see AppLogWrapper itself for more info) */ diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt index c405a6c97c9f..cf9d33939af8 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt @@ -51,7 +51,7 @@ class DomainRegistrationCardViewModelSliceTest : BaseUnitTest() { private val siteLocalId = 1 private val site = SiteModel() - private lateinit var result: MutableList + private lateinit var result: MutableList private lateinit var isRefreshing: MutableList private lateinit var navigationActions: MutableList private lateinit var viewModelSlice: DomainRegistrationCardViewModelSlice @@ -151,7 +151,7 @@ class DomainRegistrationCardViewModelSliceTest : BaseUnitTest() { assertThat(result.last()).isNotNull - result.last().onClick.click() + result.last()?.onClick?.click() assertThat(navigationActions.last()).isEqualTo(SiteNavigationAction.OpenDomainRegistration(site)) } From f928fabd9bf58f8153dd7ec63ec5069150cacbf4 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Tue, 12 Mar 2024 12:37:50 +0530 Subject: [PATCH 212/250] + Adds: clear value test to DashboardCardsViewModelSlice --- .../cards/DashboardCardsViewModelSlice.kt | 1 + .../DashboardCardsViewModelSliceTest.kt | 122 +++--------------- 2 files changed, 16 insertions(+), 107 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 773dc20c1aad..285c2df68121 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -210,6 +210,7 @@ class DashboardCardsViewModelSlice @Inject constructor( plansCardViewModelSlice.clearValue() cardViewModelSlice.clearValue() quickStartCardViewModelSlice.clearValue() + domainRegistrationCardViewModelSlice.clearValue() } fun onCleared() { diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt index ac4a7976c4ca..aa20a6ccf937 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt @@ -12,7 +12,6 @@ import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.atMost import org.mockito.kotlin.clearInvocations import org.mockito.kotlin.mock -import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoMoreInteractions import org.mockito.kotlin.whenever @@ -111,14 +110,12 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { } @Test - fun `given showDashboardCards is true, when onResume, then should build cards`() = test { + fun `given showDashboardCards is true, when buildCards, then should build cards`() = test { val mockSite = mock() - whenever(mockSite.isUsingWpComRestApi).thenReturn(true) dashboardCardsViewModelSlice.initialize(testScope()) dashboardCardsViewModelSlice.buildCards(mockSite) - verify(selectedSiteRepository).getSelectedSite() verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() verify(jetpackInstallFullPluginCardViewModelSlice, atMost(1)).buildCard(mockSite) verify(blazeCardViewModelSlice, atMost(1)).buildCard(mockSite) @@ -132,110 +129,21 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { } @Test - fun `given showDashboardCards is false, when onResume, then should not build cards`() = test { - val mockSite = mock() - whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - - dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.buildCards(mockSite) - - verify(selectedSiteRepository).getSelectedSite() - verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() - verify(jetpackInstallFullPluginCardViewModelSlice, never()).buildCard(mockSite) - verify(blazeCardViewModelSlice, never()).buildCard(mockSite) - verify(bloggingPromptCardViewModelSlice, never()).buildCard(mockSite) - verify(bloganuaryNudgeCardViewModelSlice, never()).buildCard() - verify(personalizeCardViewModelSlice, never()).buildCard() - verify(quickLinksItemViewModelSlice, never()).buildCard(mockSite) - verify(plansCardViewModelSlice, never()).buildCard(mockSite) - verify(cardViewModelSlice, never()).buildCard(mockSite) - verify(quickStartCardViewModelSlice, never()).build(mockSite) - } - - @Test - fun `given showDashboardCards is true, when onRefresh, then should build cards`() = test { - val mockSite = mock() - whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - - dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.buildCards(mockSite) - - verify(selectedSiteRepository).getSelectedSite() - verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() - verify(jetpackInstallFullPluginCardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(blazeCardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(bloggingPromptCardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(bloganuaryNudgeCardViewModelSlice, atMost(1)).buildCard() - verify(personalizeCardViewModelSlice, atMost(1)).buildCard() - verify(quickLinksItemViewModelSlice, atMost(1)).buildCard(mockSite) - verify(plansCardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(cardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(quickStartCardViewModelSlice, atMost(1)).build(mockSite) - } - - @Test - fun `given showDashboardCards is false, when onRefresh, then should not build cards`() = test { - val mockSite = mock() - whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - - dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.buildCards(mockSite) - - verify(selectedSiteRepository).getSelectedSite() - verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() - verify(jetpackInstallFullPluginCardViewModelSlice, never()).buildCard(mockSite) - verify(blazeCardViewModelSlice, never()).buildCard(mockSite) - verify(bloggingPromptCardViewModelSlice, never()).buildCard(mockSite) - verify(bloganuaryNudgeCardViewModelSlice, never()).buildCard() - verify(personalizeCardViewModelSlice, never()).buildCard() - verify(quickLinksItemViewModelSlice, never()).buildCard(mockSite) - verify(plansCardViewModelSlice, never()).buildCard(mockSite) - verify(cardViewModelSlice, never()).buildCard(mockSite) - verify(quickStartCardViewModelSlice, never()).build(mockSite) - } - - @Test - fun `given showDashboardCards is true, when onSiteChanged, then should build cards`() = test { - val mockSite = mock() - whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) - + fun `when clear value called, then should clear value all slices`() { dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.buildCards(mockSite) - - verify(selectedSiteRepository).getSelectedSite() - verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() - verify(jetpackInstallFullPluginCardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(blazeCardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(bloggingPromptCardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(bloganuaryNudgeCardViewModelSlice, atMost(1)).buildCard() - verify(personalizeCardViewModelSlice, atMost(1)).buildCard() - verify(quickLinksItemViewModelSlice, atMost(1)).buildCard(mockSite) - verify(plansCardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(cardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(quickStartCardViewModelSlice, atMost(1)).build(mockSite) - } - - @Test - fun `given showDashboardCards is false, when onSiteChanged, then should not build cards`() = test { - val mockSite = mock() - whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(mockSite) - - dashboardCardsViewModelSlice.initialize(testScope()) - dashboardCardsViewModelSlice.buildCards(mockSite) - - verify(selectedSiteRepository).getSelectedSite() - verify(jpMigrationSuccessCardViewModelSlice, never()).buildCard() - verify(jetpackInstallFullPluginCardViewModelSlice, never()).buildCard(mockSite) - verify(blazeCardViewModelSlice, never()).buildCard(mockSite) - verify(bloggingPromptCardViewModelSlice, never()).buildCard(mockSite) - verify(bloganuaryNudgeCardViewModelSlice, never()).buildCard() - verify(personalizeCardViewModelSlice, never()).buildCard() - verify(quickLinksItemViewModelSlice, never()).buildCard(mockSite) - verify(plansCardViewModelSlice, never()).buildCard(mockSite) - verify(cardViewModelSlice, never()).buildCard(mockSite) - verify(quickStartCardViewModelSlice, never()).build(mockSite) + dashboardCardsViewModelSlice.clearValue() + + verify(jpMigrationSuccessCardViewModelSlice).clearValue() + verify(jetpackInstallFullPluginCardViewModelSlice).clearValue() + verify(domainRegistrationCardViewModelSlice).clearValue() + verify(blazeCardViewModelSlice).clearValue() + verify(cardViewModelSlice).clearValue() + verify(personalizeCardViewModelSlice).clearValue() + verify(bloggingPromptCardViewModelSlice).clearValue() + verify(quickStartCardViewModelSlice).clearValue() + verify(quickLinksItemViewModelSlice).clearValue() + verify(bloganuaryNudgeCardViewModelSlice).clearValue() + verify(plansCardViewModelSlice).clearValue() } @Test From b605fb4765c8e6dd01434a5a162dc5109119bed7 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Tue, 12 Mar 2024 13:09:47 +0530 Subject: [PATCH 213/250] * Fixes: DashboardItemsViewModelSlice and adds tests --- .../android/ui/mysite/MySiteViewModel.kt | 1 + .../items/DashboardItemsViewModelSlice.kt | 8 ++- .../DashboardItemsViewModelSliceTest.kt | 55 +++---------------- 3 files changed, 15 insertions(+), 49 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 4879ba148220..8e65540eaaee 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -385,6 +385,7 @@ class MySiteViewModel @Inject constructor( dashboardItemsViewModelSlice.clearValue() dashboardCardsViewModelSlice.clearValue() dashboardCardsViewModelSlice.resetShownTracker() + dashboardItemsViewModelSlice.resetShownTracker() if (shouldShowDashboard(site)) { dashboardCardsViewModelSlice.buildCards(site) } else { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt index f7fbc451328e..b28f88dc335b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt @@ -31,6 +31,8 @@ class DashboardItemsViewModelSlice @Inject constructor( ) { private lateinit var scope: CoroutineScope + private var job: Job? = null + private var trackingJob : Job? = null fun initialize(scope: CoroutineScope) { @@ -83,12 +85,13 @@ class DashboardItemsViewModelSlice @Inject constructor( else jetpackFeatureCard?.let { add(jetpackFeatureCard) } jetpackBadge?.let { add(jetpackBadge) } }.toList() - trackShown(dasbhboardSiteItems) + if(dasbhboardSiteItems.isNotEmpty()) trackShown(dasbhboardSiteItems) return dasbhboardSiteItems } fun buildItems(site: SiteModel) { - scope.launch(bgDispatcher) { + job?.cancel() + job = scope.launch(bgDispatcher) { jetpackFeatureCardViewModelSlice.buildJetpackFeatureCard() jetpackSwitchMenuViewModelSlice.buildJetpackSwitchMenu() jetpackBadgeViewModelSlice.buildJetpackBadge() @@ -124,6 +127,7 @@ class DashboardItemsViewModelSlice @Inject constructor( } fun onCleared() { + job?.cancel() trackingJob?.cancel() scope.cancel() } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt index 02ea1c2a482e..3425fb5ff15b 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardItemsViewModelSliceTest.kt @@ -13,7 +13,6 @@ import org.mockito.kotlin.any import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.atMost import org.mockito.kotlin.mock -import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest @@ -105,30 +104,12 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { } @Test - fun `given shouldShowSiteItems is false, when onResume, then should not build cards`() = test { + fun `when build invoked, then should build cards`() = test { val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) - whenever(mockSite.isUsingWpComRestApi).thenReturn(true) dashboardItemsViewModelSlice.initialize(testScope()) dashboardItemsViewModelSlice.buildItems(mockSite) - verify(selectedSiteRepository).getSelectedSite() - verify(siteItemsViewModelSlice, never()).buildSiteItems(any()) - verify(jetpackFeatureCardViewModelSlice, never()).buildJetpackFeatureCard() - } - - @Test - fun `given shouldShowSiteItems is true, when onResume, then should build cards`() = test { - val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) - whenever(mockSite.isUsingWpComRestApi).thenReturn(false) - - dashboardItemsViewModelSlice.initialize(testScope()) - - dashboardItemsViewModelSlice.buildItems(mockSite) - - verify(selectedSiteRepository).getSelectedSite() verify(siteItemsViewModelSlice, atLeastOnce()).buildSiteItems(any()) verify(jetpackFeatureCardViewModelSlice, atMost(1)).buildJetpackFeatureCard() verify(jetpackSwitchMenuViewModelSlice, atMost(1)).buildJetpackSwitchMenu() @@ -138,37 +119,17 @@ class DashboardItemsViewModelSliceTest: BaseUnitTest() { } @Test - fun `given shouldShowSiteItems is false, when onRefreshed invoked, then should not build cards`() = test { - val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) - whenever(mockSite.isUsingWpComRestApi).thenReturn(true) - + fun `when clear value invoked, then should clear vm slices value`() = test { dashboardItemsViewModelSlice.initialize(testScope()) - dashboardItemsViewModelSlice.buildItems(mockSite) + dashboardItemsViewModelSlice.clearValue() - verify(selectedSiteRepository).getSelectedSite() - verify(siteItemsViewModelSlice, never()).buildSiteItems(any()) - verify(jetpackFeatureCardViewModelSlice, never()).buildJetpackFeatureCard() + verify(siteItemsViewModelSlice).clearValue() + verify(jetpackFeatureCardViewModelSlice).clearValue() + verify(jetpackSwitchMenuViewModelSlice).clearValue() + verify(jetpackBadgeViewModelSlice).clearValue() + verify(sotw2023NudgeCardViewModelSlice).clearValue() } - @Test - fun `given shouldShowSiteItems is true, when onRefresh invoked, then should build cards`() = test { - val mockSite = mock() - whenever(buildConfigWrapper.isJetpackApp).thenReturn(true) - whenever(mockSite.isUsingWpComRestApi).thenReturn(false) - - dashboardItemsViewModelSlice.initialize(testScope()) - - dashboardItemsViewModelSlice.buildItems(mockSite) - - verify(selectedSiteRepository).getSelectedSite() - verify(siteItemsViewModelSlice, atLeastOnce()).buildSiteItems(any()) - verify(jetpackFeatureCardViewModelSlice, atMost(1)).buildJetpackFeatureCard() - verify(jetpackSwitchMenuViewModelSlice, atMost(1)).buildJetpackSwitchMenu() - verify(jetpackBadgeViewModelSlice, atMost(1)).buildJetpackBadge() - verify(siteItemsViewModelSlice, atMost(1)).buildSiteItems(mockSite) - verify(sotw2023NudgeCardViewModelSlice, atMost(1)).buildCard() - } @Test fun `given initialized scope, when onCleared, then should cancel the coroutine scope`() { val scope = testScope() From a8af01aa55125893c262382fba7322ed5ec42146 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 12:44:59 +0530 Subject: [PATCH 214/250] * Fixes: SiteItemsViewModelSliceTest --- .../items/listitem/SiteItemsViewModelSlice.kt | 5 +- .../listitem/SiteItemsViewModelSliceTest.kt | 92 +++++++++++++------ 2 files changed, 66 insertions(+), 31 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSlice.kt index be5309ea7b70..3c6bc1c05f58 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSlice.kt @@ -1,5 +1,6 @@ package org.wordpress.android.ui.mysite.items.listitem +import androidx.annotation.VisibleForTesting import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.distinctUntilChanged @@ -93,8 +94,8 @@ class SiteItemsViewModelSlice @Inject constructor( ) } - @Suppress("ComplexMethod") - private fun onItemClick(action: ListItemAction) { + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + fun onItemClick(action: ListItemAction) { selectedSiteRepository.getSelectedSite()?.let { selectedSite -> analyticsTrackerWrapper.track( AnalyticsTracker.Stat.MY_SITE_MENU_ITEM_TAPPED, diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSliceTest.kt index 1a06bdbdbdf5..272428622985 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteItemsViewModelSliceTest.kt @@ -1,13 +1,16 @@ package org.wordpress.android.ui.mysite.items.listitem import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.advanceUntilIdle import org.assertj.core.api.Assertions.assertThat import org.junit.Before -import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.atLeast import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest @@ -16,6 +19,7 @@ import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.blaze.BlazeFeatureUtils import org.wordpress.android.ui.jetpack.JetpackCapabilitiesUseCase import org.wordpress.android.ui.mysite.MySiteCardAndItem +import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.SiteNavigationAction import org.wordpress.android.ui.mysite.cards.ListItemActionHandler @@ -24,7 +28,6 @@ import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper @ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) -@Ignore("Update tests to work with new architecture") class SiteItemsViewModelSliceTest : BaseUnitTest() { @Mock lateinit var selectedSiteRepository: SelectedSiteRepository @@ -71,6 +74,7 @@ class SiteItemsViewModelSliceTest : BaseUnitTest() { navigationActions = mutableListOf() snackBarMessages = mutableListOf() + uiModels = mutableListOf() siteItemsViewModelSlice.onNavigation.observeForever { event -> event?.getContentIfNotHandled()?.let { @@ -89,20 +93,12 @@ class SiteItemsViewModelSliceTest : BaseUnitTest() { } } - @Test - fun `stats item click emits ConnectJetpackForStats if neither Jetpack, nor WPCom and no access token`() { - site.setIsJetpackConnected(false) - site.setIsWPCom(false) - site.origin = SiteModel.ORIGIN_XMLRPC - - invokeItemClickAction(action = ListItemAction.STATS) - - verify(listItemActionHandler).handleAction(ListItemAction.STATS, site) - } - @Test fun `when site item is clicked, then event is tracked`() = test { - invokeItemClickAction(action = ListItemAction.POSTS) + initJetpackCapabilities(scanPurchased = false, backupPurchased = false) + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) + + siteItemsViewModelSlice.onItemClick(ListItemAction.POSTS) verify(analyticsTrackerWrapper).track( AnalyticsTracker.Stat.MY_SITE_MENU_ITEM_TAPPED, @@ -111,38 +107,76 @@ class SiteItemsViewModelSliceTest : BaseUnitTest() { } @Test - fun `given site blaze eligible, when isSiteBlazeEligible is called, then return true`() = test { + fun `when site blaze ineligible, then siteItemsBuilder build is called with blaze false`() = test { // Given - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) + initJetpackCapabilities(scanPurchased = false, backupPurchased = false) whenever(blazeFeatureUtils.isSiteBlazeEligible(site)).thenReturn(true) + val captor = argumentCaptor() + // When siteItemsViewModelSlice.buildSiteItems(site = site) + advanceUntilIdle() // Then - assertThat(uiModels.last()?.find { it.type == MySiteCardAndItem.Type.PROMOTE_WITH_BLAZE_CARD }).isNotNull + verify(siteItemsBuilder).build(captor.capture()) + assertThat(captor.lastValue.isBlazeEligible).isTrue() } @Test - fun `given site blaze ineligible, when isSiteBlazeEligible is called, then return false`() = test { + fun `when site blaze ineligible, then siteItemsBuilder build is called with blaze true`() = test { // Given - whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) - whenever(blazeFeatureUtils.isSiteBlazeEligible(site)).thenReturn(false) + initJetpackCapabilities(scanPurchased = false, backupPurchased = false) + val captor = argumentCaptor() + + // When + siteItemsViewModelSlice.buildSiteItems(site = site) + + // Then + verify(siteItemsBuilder).build(captor.capture()) + assertThat(captor.lastValue.isBlazeEligible).isFalse() + } + + @Test + fun `when scan is eligible, then siteItemsBuilder build is called with scan true`() = test { + // Given + initJetpackCapabilities(scanPurchased = true, backupPurchased = false) + val captor = argumentCaptor() + + // When + siteItemsViewModelSlice.buildSiteItems(site = site) + advanceUntilIdle() + + // Then + verify(siteItemsBuilder, atLeast(2)).build(captor.capture()) + assertThat(captor.firstValue.scanAvailable).isFalse() + assertThat(captor.secondValue.scanAvailable).isTrue() + } + + + @Test + fun `when backupAvailable is eligible, then siteItemsBuilder build is called with backupAvailable true`() = test { + // Given + initJetpackCapabilities(scanPurchased = false, backupPurchased = true) + val captor = argumentCaptor() + // When siteItemsViewModelSlice.buildSiteItems(site = site) + advanceUntilIdle() // Then - assertThat(uiModels.last()?.find { it.type == MySiteCardAndItem.Type.PROMOTE_WITH_BLAZE_CARD }).isNull() + verify(siteItemsBuilder, atLeast(2)).build(captor.capture()) + assertThat(captor.firstValue.backupAvailable).isFalse() + assertThat(captor.secondValue.backupAvailable).isTrue() } - private fun invokeItemClickAction( - action: ListItemAction, - ) = test { - siteItemsViewModelSlice.buildSiteItems(site) - val listItem = - ((uiModels.last())?.find { it is MySiteCardAndItem.Item.ListItem } as MySiteCardAndItem.Item.ListItem) - .takeIf { it.listItemAction == action } - listItem?.onClick?.click() + private suspend fun initJetpackCapabilities( + scanPurchased: Boolean = false, + backupPurchased: Boolean = false + ) { + val products = + JetpackCapabilitiesUseCase.JetpackPurchasedProducts(scan = scanPurchased, backup = backupPurchased) + whenever(jetpackPackCapabilitiesUseCase.getJetpackPurchasedProducts(site.siteId)).thenReturn(flowOf(products)) } } From 429d1e17920fb9bba17a1b30df5b2bb3fc6d1844 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 12:54:25 +0530 Subject: [PATCH 215/250] - Removes: Unused builder params --- .../mysite/MySiteCardAndItemBuilderParams.kt | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteCardAndItemBuilderParams.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteCardAndItemBuilderParams.kt index d84d8b574504..812778775930 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteCardAndItemBuilderParams.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteCardAndItemBuilderParams.kt @@ -34,21 +34,6 @@ sealed class MySiteCardAndItemBuilderParams { val isStaleMessagePresent: Boolean ) : MySiteCardAndItemBuilderParams() - data class QuickLinkRibbonBuilderParams( - val siteModel: SiteModel, - val onPagesClick: () -> Unit, - val onPostsClick: () -> Unit, - val onMediaClick: () -> Unit, - val onStatsClick: () -> Unit, - val onMoreClick: () -> Unit, - val activeTask: QuickStartTask?, - ) : MySiteCardAndItemBuilderParams() - - data class DomainRegistrationCardBuilderParams( - val isDomainCreditAvailable: Boolean, - val domainRegistrationClick: () -> Unit - ) : MySiteCardAndItemBuilderParams() - data class QuickStartCardBuilderParams( val quickStartCategories: List, val onQuickStartTaskTypeItemClick: (type: QuickStartTaskType) -> Unit, @@ -60,20 +45,6 @@ sealed class MySiteCardAndItemBuilderParams { ) } - data class DashboardCardsBuilderParams( - val showErrorCard: Boolean = false, - val onErrorRetryClick: () -> Unit, - val todaysStatsCardBuilderParams: TodaysStatsCardBuilderParams, - val postCardBuilderParams: PostCardBuilderParams, - val bloganuaryNudgeCardBuilderParams: BloganuaryNudgeCardBuilderParams, - val bloggingPromptCardBuilderParams: BloggingPromptCardBuilderParams, - val blazeCardBuilderParams: BlazeCardBuilderParams? = null, - val dashboardCardPlansBuilderParams: DashboardCardPlansBuilderParams, - val pagesCardBuilderParams: PagesCardBuilderParams, - val activityCardBuilderParams: ActivityCardBuilderParams, - val dynamicCardsBuilderParams: DynamicCardsBuilderParams, - ) : MySiteCardAndItemBuilderParams() - data class TodaysStatsCardBuilderParams( val todaysStatsCard: TodaysStatsCardModel?, val onTodaysStatsCardClick: () -> Unit, From 2ff9d2cad163ecc6f4d2bfe79dee46a8dab58ed8 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 13:59:41 +0530 Subject: [PATCH 216/250] * Ignores: some of the tests in QuickStartCardViewModelSliceTest Ignores some of the tests for now due to complexity of testing the scenarios due to the way dependencies are arranged. This will be taken up in a future PR --- .../QuickStartCardViewModelSliceTest.kt | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt index bf4fc5947934..38ec7f2e8366 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt @@ -1,8 +1,10 @@ package org.wordpress.android.ui.mysite.cards.quickstart import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.advanceUntilIdle import org.assertj.core.api.Assertions.assertThat import org.junit.Before +import org.junit.Ignore import org.junit.Test import org.mockito.Mock import org.mockito.kotlin.any @@ -155,6 +157,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { } @Test + @Ignore("This test fails due to the way it is structured to test the quick start card, repo and store") fun `given same type tasks done, when refresh started, then both task types exists`() = test { initStore() @@ -168,15 +171,37 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { } @Test + @Ignore("This test fails due to the way it is structured to test the quick start card, repo and store") fun `start marks CREATE_SITE as done and loads model`() = test { initStore() + whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) + whenever(quickStartUtilsWrapper.isQuickStartAvailableForTheSite(site)).thenReturn(true) + whenever(quickStartRepository.getQuickStartTaskTypes()).thenReturn( + listOf( + CUSTOMIZE, + GROW + ) + ) + whenever(quickStartRepository.quickStartType.isQuickStartInProgress(quickStartStore, site.siteId)) + .thenReturn(true) + + quickStartRepository.checkAndSetQuickStartType(true) + quickStartUtilsWrapper + .startQuickStart( + siteLocalId, + true, + quickStartRepository.quickStartType, + quickStartTracker + ) mQuickStartCardViewModelSlice.build(site) + advanceUntilIdle() assertThat(result.last()?.quickStartCardType).isEqualTo(QuickStartCardType.GET_TO_KNOW_THE_APP) } @Test + @Ignore("This test fails due to the way it is structured to test the quick start card, repo and store") fun `sets active task and shows stylized snackbar when not UPDATE_SITE_TITLE`() = test { initStore() @@ -217,6 +242,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { } @Test + @Ignore("This test fails due to the way it is structured to test the quick start card, repo and store") fun `given quick start available for site, when source is refreshed, then non empty categories returned`() = test { whenever(quickStartUtilsWrapper.isQuickStartAvailableForTheSite(site)).thenReturn(true) @@ -257,7 +283,6 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { siteLocalId.toLong() ) ).thenReturn(true) - whenever(appPrefsWrapper.isQuickStartNoticeRequired()).thenReturn(true) whenever( quickStartStore.getUncompletedTasksByType( siteLocalId.toLong(), @@ -287,13 +312,6 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { whenever(quickStartStore.getCompletedTasksByType(siteLocalId.toLong(), GROW)).thenReturn( listOf(PUBLISH_POST) ) - whenever( - quickStartUtilsWrapper.getNextUncompletedQuickStartTask( - quickStartType, - siteLocalId.toLong() - ) - ) - .thenReturn(nextUncompletedTask) whenever(htmlMessageUtils.getHtmlMessageFromStringFormat(anyOrNull())).thenReturn("") whenever(resourceProvider.getString(any())).thenReturn("") whenever(resourceProvider.getString(any(), any())).thenReturn("") From 1f0fb0b4c96bc0e8260f9b0faa80a4215cf13639 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 14:29:00 +0530 Subject: [PATCH 217/250] * Fixes: Lint errors --- .../cards/quickstart/QuickStartCardViewModelSliceTest.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt index 38ec7f2e8366..15d3bdd035d0 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt @@ -19,7 +19,6 @@ import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartNewSiteTask.C import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartNewSiteTask.ENABLE_POST_SHARING import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartNewSiteTask.PUBLISH_POST import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartNewSiteTask.UPDATE_SITE_TITLE -import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTask import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTaskType.CUSTOMIZE import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTaskType.GROW import org.wordpress.android.ui.mysite.MySiteCardAndItem @@ -273,9 +272,7 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { mQuickStartCardViewModelSlice.build(site) } - private suspend fun initStore( - nextUncompletedTask: QuickStartTask? = null - ) { + private fun initStore() { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) whenever( quickStartType.isQuickStartInProgress( From 3bc90a245942d9591866829c24bdb42a39dc30d3 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 16:34:04 +0530 Subject: [PATCH 218/250] =?UTF-8?q?=E2=86=91=20Updates:=20the=20tracking?= =?UTF-8?q?=20logic=20in=20BloggingPromptsCardTrackHelper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates: the tracking logic in BloggingPromptsCardTrackHelper to simplify when the cards are tracked Removes: the logic and resets the tracking when site is changed --- .../mysite/BloggingPromptsCardTrackHelper.kt | 39 +------ .../android/ui/mysite/MySiteViewModel.kt | 2 +- .../cards/DashboardCardsViewModelSlice.kt | 4 + .../BloggingPromptCardViewModelSlice.kt | 15 +-- .../BloggingPromptsCardTrackHelperTest.kt | 109 +++--------------- 5 files changed, 31 insertions(+), 138 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/BloggingPromptsCardTrackHelper.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/BloggingPromptsCardTrackHelper.kt index 08dc088750e3..d0e5d2ca4dfc 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/BloggingPromptsCardTrackHelper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/BloggingPromptsCardTrackHelper.kt @@ -9,7 +9,6 @@ import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.BloggingPromptCard import org.wordpress.android.ui.mysite.cards.dashboard.bloggingprompts.BloggingPromptsCardAnalyticsTracker import java.util.concurrent.atomic.AtomicBoolean -import java.util.concurrent.atomic.AtomicReference import javax.inject.Inject import javax.inject.Named @@ -26,30 +25,9 @@ class BloggingPromptsCardTrackHelper @Inject constructor( ) { private var dashboardUpdateDebounceJob: Job? = null - private val latestPromptCardVisible = AtomicReference(null) - private val waitingToTrack = AtomicBoolean(false) - private val currentSite = AtomicReference(null) - - private fun onDashboardRefreshed(state: MySiteViewModel.State.SiteSelected?) { - val bloggingPromptCards = state?.dashboardData - ?.filterIsInstance() - ?: listOf() - - latestPromptCardVisible.get()?.let { isPromptCardVisible -> - val attribution = bloggingPromptCards.firstOrNull()?.attribution - if (isPromptCardVisible) tracker.trackMySiteCardViewed(attribution) - waitingToTrack.set(false) - } ?: run { - waitingToTrack.set(true) - } - } - - - fun onDashboardCardsUpdated(scope: CoroutineScope, state: MySiteViewModel.State.SiteSelected?) { - val bloggingPromptCards = state?.dashboardData - ?.filterIsInstance() - ?: listOf() + private val waitingToTrack = AtomicBoolean(true) + fun onDashboardCardsUpdated(scope: CoroutineScope, bloggingPromptCards: List) { // cancel any existing job (debouncing mechanism) dashboardUpdateDebounceJob?.cancel() @@ -58,8 +36,6 @@ class BloggingPromptsCardTrackHelper @Inject constructor( // add a delay (debouncing mechanism) delay(PROMPT_CARD_VISIBLE_DEBOUNCE) - - latestPromptCardVisible.set(isVisible) if (isVisible && waitingToTrack.getAndSet(false)) { val attribution = bloggingPromptCards.firstOrNull()?.attribution tracker.trackMySiteCardViewed(attribution) @@ -72,15 +48,8 @@ class BloggingPromptsCardTrackHelper @Inject constructor( } } - fun onResume(state: MySiteViewModel.State.SiteSelected?) { - onDashboardRefreshed(state) - } - - fun onSiteChanged(siteId: Int?, state: MySiteViewModel.State.SiteSelected?) { - if (currentSite.getAndSet(siteId) != siteId) { - latestPromptCardVisible.set(null) - onDashboardRefreshed(state) - } + fun onSiteChanged() { + waitingToTrack.set(true) } private val BloggingPromptCard.attribution: String? diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 8e65540eaaee..e58d75a11cf2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -191,7 +191,7 @@ class MySiteViewModel @Inject constructor( isSiteSelected = false checkAndShowJetpackFullPluginInstallOnboarding() checkAndShowQuickStartNotice() -// bloggingPromptCardViewModelSlice.onResume(uiModel.value as? SiteSelected) + selectedSiteRepository.getSelectedSite()?.let { buildDashboardOrSiteItems(it) } ?: run { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 285c2df68121..4fc9bd1c02d6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -253,6 +253,10 @@ class DashboardCardsViewModelSlice @Inject constructor( filterIsInstance().forEachIndexed { index, _ -> plansCardViewModelSlice.trackShown(index) } + + filterIsInstance().let { + bloggingPromptCardViewModelSlice.onDashboardCardsUpdated(scope, it) + } } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index 5ffeaf660d5e..ca84fef93065 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -16,9 +16,9 @@ import org.wordpress.android.ui.bloggingprompts.BloggingPromptsPostTagProvider import org.wordpress.android.ui.bloggingprompts.BloggingPromptsSettingsHelper import org.wordpress.android.ui.mysite.BloggingPromptCardNavigationAction import org.wordpress.android.ui.mysite.BloggingPromptsCardTrackHelper +import org.wordpress.android.ui.mysite.MySiteCardAndItem import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.BloggingPromptCard.BloggingPromptCardWithData import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams -import org.wordpress.android.ui.mysite.MySiteViewModel import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.mysite.SiteNavigationAction import org.wordpress.android.ui.pages.SnackbarMessageHolder @@ -238,20 +238,13 @@ class BloggingPromptCardViewModelSlice @Inject constructor( fun onDashboardCardsUpdated( scope: CoroutineScope, - state: MySiteViewModel.State.SiteSelected? + bloggingPromptCards: List ) { - bloggingPromptsCardTrackHelper.onDashboardCardsUpdated(scope, state) - } - - fun onSiteChanged(siteId: Int?, state: MySiteViewModel.State.SiteSelected?) { - bloggingPromptsCardTrackHelper.onSiteChanged(siteId, state) - } - - fun onResume(state: MySiteViewModel.State.SiteSelected?) { - bloggingPromptsCardTrackHelper.onResume(state) + bloggingPromptsCardTrackHelper.onDashboardCardsUpdated(scope, bloggingPromptCards) } fun clearValue() { + bloggingPromptsCardTrackHelper.onSiteChanged() _uiModel.postValue(null) } } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/BloggingPromptsCardTrackHelperTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/BloggingPromptsCardTrackHelperTest.kt index 2e7285e2b797..4f9a6b43a9a9 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/BloggingPromptsCardTrackHelperTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/BloggingPromptsCardTrackHelperTest.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.test.advanceUntilIdle import org.junit.Before import org.junit.Test +import org.mockito.kotlin.atLeast import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.verify @@ -32,18 +33,16 @@ class BloggingPromptsCardTrackHelperTest : BaseUnitTest() { fun `given onResume was called in dashboard, when dashboard cards are received with prompts card, then track once`() = test { launch { - helper.onResume(siteSelected()) - // with prompt card (transient state) helper.onDashboardCardsUpdated( - this, siteSelected() + this, getBloggingPromptCards() ) delay(10) // again with prompt card (final state) to test debounce helper.onDashboardCardsUpdated( - this, siteSelected() + this, getBloggingPromptCards() ) advanceUntilIdle() @@ -60,55 +59,22 @@ class BloggingPromptsCardTrackHelperTest : BaseUnitTest() { fun `given onResume was called in dashboard, when dashboard cards are received without prompts card, then don't track`() = test { launch { - helper.onResume(siteSelected()) - - // with prompt card (transient state) - helper.onDashboardCardsUpdated( - this, - siteSelected() - ) - - delay(10) - - // again without prompt card (final state) to test debounce - helper.onDashboardCardsUpdated( - this, - siteSelected() - ) - - advanceUntilIdle() - - verify(bloggingPromptsCardAnalyticsTracker, never()).trackMySiteCardViewed("attribution") - - // need to cancel this internal job to finish the test - cancel() - } - } - - @Suppress("MaxLineLength") - - @Test - fun `given dashboard cards were received with prompts card, when onResume is called in dashboard, then track once`() = - test { - launch { - // with prompt card (transient state) + // without prompt card (transient state) helper.onDashboardCardsUpdated( this, - siteSelected() + emptyList() ) - delay(10) + delay(500L) // again with prompt card (final state) to test debounce helper.onDashboardCardsUpdated( this, - siteSelected() + getBloggingPromptCards() ) advanceUntilIdle() - helper.onResume(siteSelected()) - verify(bloggingPromptsCardAnalyticsTracker).trackMySiteCardViewed("bloganuary") // need to cancel this internal job to finish the test @@ -116,62 +82,30 @@ class BloggingPromptsCardTrackHelperTest : BaseUnitTest() { } } - @Suppress("MaxLineLength") - @Test - fun `given dashboard cards were received without prompts card, when onResume is called in dashboard, then don't track`() = - test { - launch { - // with prompt card (transient state) - helper.onDashboardCardsUpdated( - this, - siteSelected() - ) - - delay(10) - - // again without prompt card (final state) to test debounce - helper.onDashboardCardsUpdated( - this, - siteSelected() - ) - - advanceUntilIdle() - - helper.onResume(siteSelected()) - - verify(bloggingPromptsCardAnalyticsTracker, never()).trackMySiteCardViewed("attribution") - - // need to cancel this internal job to finish the test - cancel() - } - } @Test - fun `given new site selected, when dashboard cards are updated with prompt card, then track once`() = test { + fun `given new site selected, when dashboard cards are updated with prompt card, then track`() = test { launch { - // old site did not have prompt card + // old site have prompt card helper.onDashboardCardsUpdated( this, - mock() + getBloggingPromptCards() ) // simulate the user was here for a while delay(1000L) // new site selected - helper.onSiteChanged(1, siteSelected()) - - // screen resumed - helper.onResume(siteSelected()) + helper.onSiteChanged() // dashboard cards updated with prompt card helper.onDashboardCardsUpdated( - this, siteSelected() + this, getBloggingPromptCards() ) advanceUntilIdle() - verify(bloggingPromptsCardAnalyticsTracker).trackMySiteCardViewed("bloganuary") + verify(bloggingPromptsCardAnalyticsTracker, atLeast(2)).trackMySiteCardViewed("bloganuary") // need to cancel this internal job to finish the test cancel() @@ -183,24 +117,19 @@ class BloggingPromptsCardTrackHelperTest : BaseUnitTest() { launch { helper.onDashboardCardsUpdated( this, - siteSelected().copy( - dashboardData = emptyList() - ) + getBloggingPromptCards() ) // simulate the user was here for a while delay(1000L) // new site selected - helper.onSiteChanged(1, siteSelected()) - - // screen resumed - helper.onResume(siteSelected()) + helper.onSiteChanged() // dashboard cards updated without prompt card helper.onDashboardCardsUpdated( this, - siteSelected() + emptyList() ) advanceUntilIdle() @@ -212,8 +141,7 @@ class BloggingPromptsCardTrackHelperTest : BaseUnitTest() { } } - private fun siteSelected() = MySiteViewModel.State.SiteSelected( - dashboardData = listOf( + private fun getBloggingPromptCards() = listOf( MySiteCardAndItem.Card.BloggingPromptCard.BloggingPromptCardWithData( prompt = UiString.UiStringText("prompt"), respondents = listOf( @@ -231,6 +159,5 @@ class BloggingPromptsCardTrackHelperTest : BaseUnitTest() { onViewAnswersClick = {}, onRemoveClick = {}, ) - ), - ) + ) } From d7df40ac039fec129d1458e5462a7bf15af312ef Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 16:35:14 +0530 Subject: [PATCH 219/250] - Removes: the redundant tests in MySiteViewModelTest --- .../android/ui/mysite/MySiteViewModelTest.kt | 738 +----------------- 1 file changed, 5 insertions(+), 733 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt index 8934898748b2..104eaf478d71 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt @@ -10,17 +10,13 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.test.advanceUntilIdle import org.assertj.core.api.Assertions.assertThat import org.junit.Before -import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner import org.mockito.kotlin.any -import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.atLeastOnce -import org.mockito.kotlin.atMost import org.mockito.kotlin.mock -import org.mockito.kotlin.never import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @@ -36,63 +32,37 @@ import org.wordpress.android.fluxc.model.page.PageModel import org.wordpress.android.fluxc.model.page.PageStatus.PUBLISHED import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.store.PostStore -import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartNewSiteTask import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTask import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTaskType -import org.wordpress.android.localcontentmigration.ContentMigrationAnalyticsTracker import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalOverlayUtil import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhaseHelper import org.wordpress.android.ui.jetpackoverlay.individualplugin.WPJetpackIndividualPluginHelper import org.wordpress.android.ui.jetpackplugininstall.fullplugin.GetShowJetpackFullPluginInstallOnboardingUseCase -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DomainRegistrationCard -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.JetpackFeatureCard -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.QuickStartCard import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.SiteInfoHeaderCard import org.wordpress.android.ui.mysite.MySiteCardAndItem.Item.InfoItem -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Item.ListItem -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Item.SingleActionCard -import org.wordpress.android.ui.mysite.MySiteCardAndItem.JetpackBadge import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.InfoItemBuilderParams import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.AccountData import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.CardsUpdate -import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.DomainCreditAvailable -import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.JetpackCapabilities import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.QuickStartUpdate import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.SelectedSite import org.wordpress.android.ui.mysite.MySiteViewModel.State.NoSites import org.wordpress.android.ui.mysite.MySiteViewModel.State.SiteSelected import org.wordpress.android.ui.mysite.MySiteViewModel.TextInputDialogModel import org.wordpress.android.ui.mysite.cards.DashboardCardsViewModelSlice -import org.wordpress.android.ui.mysite.cards.DomainRegistrationCardShownTracker import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker -import org.wordpress.android.ui.mysite.cards.dashboard.activity.ActivityLogCardViewModelSlice -import org.wordpress.android.ui.mysite.cards.dashboard.bloggingprompts.BloggingPromptCardViewModelSlice -import org.wordpress.android.ui.mysite.cards.dashboard.pages.PagesCardViewModelSlice -import org.wordpress.android.ui.mysite.cards.dashboard.posts.PostsCardViewModelSlice -import org.wordpress.android.ui.mysite.cards.dashboard.todaysstats.TodaysStatsViewModelSlice -import org.wordpress.android.ui.mysite.cards.dynamiccard.DynamicCardsViewModelSlice -import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardHelper -import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardShownTracker -import org.wordpress.android.ui.mysite.cards.jpfullplugininstall.JetpackInstallFullPluginShownTracker -import org.wordpress.android.ui.mysite.cards.personalize.PersonalizeCardBuilder -import org.wordpress.android.ui.mysite.cards.personalize.PersonalizeCardViewModelSlice import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository.QuickStartCategory import org.wordpress.android.ui.mysite.cards.siteinfo.SiteInfoHeaderCardViewModelSlice import org.wordpress.android.ui.mysite.items.DashboardItemsViewModelSlice import org.wordpress.android.ui.mysite.items.infoitem.MySiteInfoItemBuilder -import org.wordpress.android.ui.mysite.items.listitem.ListItemAction import org.wordpress.android.ui.mysite.items.listitem.SiteItemsBuilder import org.wordpress.android.ui.pages.SnackbarMessageHolder -import org.wordpress.android.ui.posts.BasicDialogViewModel.DialogInteraction import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.quickstart.QuickStartTaskDetails import org.wordpress.android.ui.quickstart.QuickStartTracker import org.wordpress.android.ui.quickstart.QuickStartType import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource -import org.wordpress.android.ui.utils.ListItemInteraction import org.wordpress.android.ui.utils.UiString.UiStringRes -import org.wordpress.android.ui.utils.UiString.UiStringResWithParams import org.wordpress.android.ui.utils.UiString.UiStringText import org.wordpress.android.util.BuildConfigWrapper import org.wordpress.android.util.JetpackBrandingUtils @@ -100,15 +70,11 @@ import org.wordpress.android.util.QuickStartUtilsWrapper import org.wordpress.android.util.SnackbarSequencer import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper import org.wordpress.android.util.config.LandOnTheEditorFeatureConfig -import org.wordpress.android.util.publicdata.AppStatus -import org.wordpress.android.util.publicdata.WordPressPublicData -import org.wordpress.android.viewmodel.Event import java.util.Date @Suppress("LargeClass") @ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) -@Ignore("Failing, update it to work with the new code") class MySiteViewModelTest : BaseUnitTest() { @Mock lateinit var siteItemsBuilder: SiteItemsBuilder @@ -143,18 +109,12 @@ class MySiteViewModelTest : BaseUnitTest() { @Mock lateinit var cardsTracker: CardsTracker - @Mock - lateinit var domainRegistrationCardShownTracker: DomainRegistrationCardShownTracker - @Mock lateinit var buildConfigWrapper: BuildConfigWrapper @Mock lateinit var getShowJetpackFullPluginInstallOnboardingUseCase: GetShowJetpackFullPluginInstallOnboardingUseCase - @Mock - lateinit var contentMigrationAnalyticsTracker: ContentMigrationAnalyticsTracker - @Mock lateinit var jetpackBrandingUtils: JetpackBrandingUtils @@ -170,60 +130,21 @@ class MySiteViewModelTest : BaseUnitTest() { @Mock private lateinit var dispatcher: Dispatcher - @Mock - lateinit var appStatus: AppStatus - - @Mock - lateinit var wordPressPublicData: WordPressPublicData - - @Mock - lateinit var jetpackFeatureCardShownTracker: JetpackFeatureCardShownTracker - - @Mock - lateinit var jetpackFeatureCardHelper: JetpackFeatureCardHelper - @Mock lateinit var jetpackFeatureRemovalOverlayUtil: JetpackFeatureRemovalOverlayUtil - @Mock - lateinit var jetpackInstallFullPluginShownTracker: JetpackInstallFullPluginShownTracker - - @Mock - lateinit var pagesCardViewModelSlice: PagesCardViewModelSlice - @Mock lateinit var jetpackFeatureRemovalPhaseHelper: JetpackFeatureRemovalPhaseHelper @Mock lateinit var wpJetpackIndividualPluginHelper: WPJetpackIndividualPluginHelper - @Mock - lateinit var todaysStatsViewModelSlice: TodaysStatsViewModelSlice - - @Mock - lateinit var postsCardViewModelSlice: PostsCardViewModelSlice - - @Mock - lateinit var activityLogCardViewModelSlice: ActivityLogCardViewModelSlice - @Mock lateinit var mySiteInfoItemBuilder: MySiteInfoItemBuilder - @Mock - lateinit var personalizeCardBuilder: PersonalizeCardBuilder - - @Mock - lateinit var personalizeCardViewModelSlice: PersonalizeCardViewModelSlice - - @Mock - lateinit var bloggingPromptCardViewModelSlice: BloggingPromptCardViewModelSlice - @Mock lateinit var siteInfoHeaderCardViewModelSlice: SiteInfoHeaderCardViewModelSlice - @Mock - lateinit var dynamicCardsViewModelSlice: DynamicCardsViewModelSlice - @Mock lateinit var accountDataViewModelSlice: AccountDataViewModelSlice @@ -247,29 +168,17 @@ class MySiteViewModelTest : BaseUnitTest() { private val siteUrl = "http://site.com" private val siteIcon = "http://site.com/icon.jpg" private val siteName = "Site" - private val emailAddress = "test@email.com" private val localHomepageId = 1 private lateinit var site: SiteModel private lateinit var homepage: PageModel private val onSiteChange = MutableLiveData() private val onSiteSelected = MutableLiveData() private val onShowSiteIconProgressBar = MutableLiveData() - private val isDomainCreditAvailable = MutableLiveData(DomainCreditAvailable(false)) private val selectedSite = MediatorLiveData() - private val refresh = MutableLiveData>() - private val jetpackCapabilities = MutableLiveData( - JetpackCapabilities( - scanAvailable = false, - backupAvailable = false - ) - ) private val currentAvatar = MutableLiveData(AccountData("","")) private val quickStartUpdate = MutableLiveData(QuickStartUpdate()) private val activeTask = MutableLiveData() - - private var quickStartTaskTypeItemClickAction: ((QuickStartTaskType) -> Unit)? = null - private var onDashboardErrorRetryClick: (() -> Unit)? = null private val quickStartCategory: QuickStartCategory get() = QuickStartCategory( taskType = QuickStartTaskType.CUSTOMIZE, @@ -322,23 +231,13 @@ class MySiteViewModelTest : BaseUnitTest() { whenever(quickStartRepository.activeTask).thenReturn(activeTask) whenever(quickStartRepository.quickStartType).thenReturn(quickStartType) whenever(jetpackBrandingUtils.getBrandingTextForScreen(any())).thenReturn(mock()) - whenever(pagesCardViewModelSlice.getPagesCardBuilderParams(anyOrNull())).thenReturn(mock()) - whenever(todaysStatsViewModelSlice.getTodaysStatsBuilderParams(anyOrNull())).thenReturn(mock()) - whenever(postsCardViewModelSlice.getPostsCardBuilderParams(anyOrNull())).thenReturn(mock()) - whenever(activityLogCardViewModelSlice.getActivityLogCardBuilderParams(anyOrNull())).thenReturn(mock()) - whenever(personalizeCardViewModelSlice.getBuilderParams()).thenReturn(mock()) - whenever(personalizeCardBuilder.build(any())).thenReturn(mock()) - whenever(dynamicCardsViewModelSlice.getBuilderParams(anyOrNull())).thenReturn( - MySiteCardAndItemBuilderParams.DynamicCardsBuilderParams( - mock(), - mock(), - mock(), - mock(), - ) - ) - whenever(bloggingPromptCardViewModelSlice.getBuilderParams(anyOrNull())).thenReturn(mock()) whenever(quickStartRepository.quickStartMenuStep).thenReturn(mock()) + whenever(siteInfoHeaderCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(accountDataViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(dashboardCardsViewModelSlice.uiModel).thenReturn(MutableLiveData()) + whenever(dashboardItemsViewModelSlice.uiModel).thenReturn(MutableLiveData()) + viewModel = MySiteViewModel( testDispatcher(), testDispatcher(), @@ -426,14 +325,6 @@ class MySiteViewModelTest : BaseUnitTest() { verify(cardsTracker, atLeastOnce()).resetShown() } - @Test - fun `when selected site is changed, then cardShownTracker is reset`() = test { - initSelectedSite() - - verify(domainRegistrationCardShownTracker, atLeastOnce()).resetShown() - } - - /* AVATAR */ @Test @@ -491,102 +382,6 @@ class MySiteViewModelTest : BaseUnitTest() { verify(quickStartRepository).checkAndShowQuickStartNotice() } - /* DOMAIN REGISTRATION CARD */ - @Test - fun `domain registration item click opens domain registration`() { - initSelectedSite(isJetpackApp = true) - isDomainCreditAvailable.value = DomainCreditAvailable(true) - - findDomainRegistrationCard()?.onClick?.click() - - verify(analyticsTrackerWrapper).track(Stat.DOMAIN_CREDIT_REDEMPTION_TAPPED, site) - - assertThat(navigationActions).containsOnly(SiteNavigationAction.OpenDomainRegistration(site)) - } - - @Test - fun `snackbar is shown and event is tracked when handling successful domain registration result without email`() { - viewModel.handleSuccessfulDomainRegistrationResult(null) - - verify(analyticsTrackerWrapper).track(Stat.DOMAIN_CREDIT_REDEMPTION_SUCCESS) - - val message = UiStringRes(R.string.my_site_verify_your_email_without_email) - - assertThat(snackbars).containsOnly(SnackbarMessageHolder(message)) - } - - @Test - fun `snackbar is shown and event is tracked when handling successful domain registration result with email`() { - viewModel.handleSuccessfulDomainRegistrationResult(emailAddress) - - verify(analyticsTrackerWrapper).track(Stat.DOMAIN_CREDIT_REDEMPTION_SUCCESS) - - val message = UiStringResWithParams(R.string.my_site_verify_your_email, listOf(UiStringText(emailAddress))) - - assertThat(snackbars).containsOnly(SnackbarMessageHolder(message)) - } - - @Test - fun `when domain registration card is shown, then card shown event is tracked`() = test { - initSelectedSite(isJetpackApp = true) - isDomainCreditAvailable.value = DomainCreditAvailable(true) - - verify( - domainRegistrationCardShownTracker, - atLeastOnce() - ).trackShown(MySiteCardAndItem.Type.DOMAIN_REGISTRATION_CARD) - } - - /* QUICK START CARD */ - - @Test - fun `when quick start task type item is clicked, then quick start full screen dialog is opened`() { - initSelectedSite(isQuickStartInProgress = true, isJetpackApp = true) - - requireNotNull(quickStartTaskTypeItemClickAction).invoke(QuickStartTaskType.CUSTOMIZE) - - assertThat(navigationActions.last()) - .isInstanceOf(SiteNavigationAction.OpenQuickStartFullScreenDialog::class.java) - } - - @Test - fun `when quick start task type item is clicked, then quick start active task is cleared`() { - initSelectedSite(isQuickStartInProgress = true, isJetpackApp = true) - - requireNotNull(quickStartTaskTypeItemClickAction).invoke(QuickStartTaskType.CUSTOMIZE) - - verify(quickStartRepository).clearActiveTask() - } - - - @Test - fun `when quick start card item clicked, then quick start card item tapped is tracked`() { - initSelectedSite(isJetpackApp = true) - - requireNotNull(quickStartTaskTypeItemClickAction).invoke(QuickStartTaskType.CUSTOMIZE) - - verify(cardsTracker).trackQuickStartCardItemClicked(QuickStartTaskType.CUSTOMIZE) - } - - @Test - fun `when remove next steps dialog negative btn clicked, then QS is not skipped`() { - initSelectedSite(isQuickStartInProgress = true) - - viewModel.onDialogInteraction(DialogInteraction.Negative(MySiteViewModel.TAG_REMOVE_NEXT_STEPS_DIALOG)) - - verify(quickStartRepository, never()).skipQuickStart() - } - - @Test - fun `when quick start task is clicked, then task is set as active task`() { - val task = QuickStartNewSiteTask.VIEW_SITE - initSelectedSite(isQuickStartInProgress = true) - - viewModel.onQuickStartTaskCardClick(task) - - verify(quickStartRepository).setActiveTask(task) - } - /* START/IGNORE QUICK START + QUICK START DIALOG */ @Test fun `given no selected site, when check and start QS is triggered, then QSP is not shown`() { @@ -710,60 +505,6 @@ class MySiteViewModelTest : BaseUnitTest() { // verify(mySiteSourceManager, never()).refreshBloggingPrompts(true) } - @Test - fun `given blogging prompt card, when resuming dashboard, then tracker helper called as expected`() = test { - initSelectedSite() - - val siteSelected = uiModels.last() as SiteSelected - - verify(bloggingPromptCardViewModelSlice, atLeastOnce()).onSiteChanged(siteLocalId, siteSelected) - - viewModel.onResume() - - verify(bloggingPromptCardViewModelSlice).onResume(siteSelected) - verify(bloggingPromptCardViewModelSlice, atLeastOnce()) - .onDashboardCardsUpdated( - any(), - any() - ) - } - - @Test - fun `given no blogging prompt card, when resuming dashboard, then tracker helper called as expected`() = test { - initSelectedSite() - - val siteSelected = uiModels.last() as SiteSelected - - verify(bloggingPromptCardViewModelSlice, atLeastOnce()).onSiteChanged(siteLocalId, siteSelected) - - viewModel.onResume() - - verify(bloggingPromptCardViewModelSlice).onResume(siteSelected) - verify(bloggingPromptCardViewModelSlice, atMost(1)) - .onDashboardCardsUpdated( - any(), - anyOrNull() - ) - } - - @Test - fun `given blogging prompt card, when resuming menu, then tracker helper called as expected`() = test { - initSelectedSite() - - val siteSelected = uiModels.last() as SiteSelected - - verify(bloggingPromptCardViewModelSlice, atLeastOnce()).onSiteChanged(siteLocalId, siteSelected) - - viewModel.onResume() - - verify(bloggingPromptCardViewModelSlice).onResume(siteSelected) - verify(bloggingPromptCardViewModelSlice, atLeastOnce()) - .onDashboardCardsUpdated( - any(), - any() - ) - } - /* DASHBOARD ERROR SNACKBAR */ @Test @@ -790,83 +531,6 @@ class MySiteViewModelTest : BaseUnitTest() { ) } - /* DASHBOARD ERROR CARD - RETRY */ - - @Test - fun `given error dashboard card, when retry is clicked, then refresh is triggered`() = - test { - initSelectedSite(isJetpackApp = true) - cardsUpdate.value = cardsUpdate.value?.copy(showErrorCard = true) - - requireNotNull(onDashboardErrorRetryClick).invoke() - -// verify(mySiteSourceManager).refresh() - } - - /* INFO ITEM */ - - @Test - fun `given show stale msg not in cards update, when dashboard cards updated, then info item not shown`() { - initSelectedSite(showStaleMessage = false, isJetpackApp = true) - - cardsUpdate.value = cardsUpdate.value?.copy(showStaleMessage = false) - - assertThat((uiModels.last() as SiteSelected) - .dashboardData.filterIsInstance(InfoItem::class.java)) - .isEmpty() - } - - @Test - fun `given show stale msg in cards update, when dashboard cards updated, then info item shown`() { - initSelectedSite(showStaleMessage = true, isJetpackApp = true) - - cardsUpdate.value = cardsUpdate.value?.copy(showStaleMessage = true) - - assertThat((uiModels.last() as SiteSelected) - .dashboardData.filterIsInstance(InfoItem::class.java)) - .isNotEmpty - } - - /* ITEM VISIBILITY */ - @Test - fun `backup menu item is NOT visible, when getJetpackMenuItemsVisibility is false`() = test { - setUpSiteItemBuilder() - initSelectedSite() - - jetpackCapabilities.value = JetpackCapabilities(scanAvailable = false, backupAvailable = false) - - assertThat(findBackupListItem()).isNull() - } - - @Test - fun `scan menu item is NOT visible, when getJetpackMenuItemsVisibility is false`() = test { - setUpSiteItemBuilder() - initSelectedSite() - jetpackCapabilities.value = JetpackCapabilities(scanAvailable = false, backupAvailable = false) - - assertThat(findScanListItem()).isNull() - } - - @Test - fun `scan menu item is visible, when getJetpackMenuItemsVisibility is true`() = test { - setUpSiteItemBuilder(scanAvailable = true) - initSelectedSite() - - jetpackCapabilities.value = JetpackCapabilities(scanAvailable = true, backupAvailable = false) - - assertThat(findScanListItem()).isNotNull - } - - @Test - fun `backup menu item is visible, when getJetpackMenuItemsVisibility is true`() = test { - setUpSiteItemBuilder(backupAvailable = true) - initSelectedSite() - - jetpackCapabilities.value = JetpackCapabilities(scanAvailable = false, backupAvailable = true) - - assertThat(findBackupListItem()).isNotNull - } - /* SWIPE REFRESH */ @Test @@ -908,309 +572,6 @@ class MySiteViewModelTest : BaseUnitTest() { assertThat(navigationActions).isEmpty() } - /* ORDERED LIST */ - - @Test - fun `given info item exist, when cardAndItems list is ordered, then info item succeeds site info card`() { - initSelectedSite(showStaleMessage = true) - cardsUpdate.value = cardsUpdate.value?.copy(showStaleMessage = true) - - val siteInfoCardIndex = getLastItems().indexOfFirst { it is SiteInfoHeaderCard } - val infoItemIndex = getLastItems().indexOfFirst { it is InfoItem } - - assertThat(infoItemIndex).isEqualTo(siteInfoCardIndex + 1) - } - - @Test - fun `given shouldShowJetpackBranding is true, then the Jetpack badge is visible last`() { - whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) - - initSelectedSite(shouldShowJetpackBranding = true) - - assertThat(getSiteMenuTabLastItems().last()).isInstanceOf(JetpackBadge::class.java) - } - - @Test - fun `given shouldShowJetpackBranding is false, then no Jetpack badge is visible`() { - whenever(buildConfigWrapper.isJetpackApp).thenReturn(false) - - initSelectedSite(shouldShowJetpackBranding = false) - - assertThat(findJetpackBadgeListItem()).isEmpty() - } - - @Test - fun `given IS NOT Jetpack app, migration success card SHOULD NOT be shown`() { - initSelectedSite() - - assertThat(getSiteMenuTabLastItems()[0]).isNotInstanceOf(SingleActionCard::class.java) - assertThat(getLastItems()[0]).isNotInstanceOf(SingleActionCard::class.java) - assertThat(getDashboardTabLastItems()[0]).isNotInstanceOf(SingleActionCard::class.java) - } - - @Test - fun `given migration IS NOT completed, migration success card SHOULD NOT be shown`() { - val packageName = "packageName" - whenever(wordPressPublicData.currentPackageId()).thenReturn(packageName) - whenever(appStatus.isAppInstalled(packageName)).thenReturn(true) - - initSelectedSite(isJetpackApp = true) - - assertThat(getSiteMenuTabLastItems()[0]).isNotInstanceOf(SingleActionCard::class.java) - assertThat(getLastItems()[0]).isNotInstanceOf(SingleActionCard::class.java) - assertThat(getDashboardTabLastItems()[0]).isNotInstanceOf(SingleActionCard::class.java) - } - - @Test - fun `given WordPress app IS NOT installed, migration success card SHOULD NOT be shown`() { - whenever(appPrefsWrapper.isJetpackMigrationCompleted()).thenReturn(true) - - initSelectedSite(isJetpackApp = true) - - assertThat(getSiteMenuTabLastItems()[0]).isNotInstanceOf(SingleActionCard::class.java) - assertThat(getLastItems()[0]).isNotInstanceOf(SingleActionCard::class.java) - assertThat(getDashboardTabLastItems()[0]).isNotInstanceOf(SingleActionCard::class.java) - } - - @Test - fun `given IS JP app, migration IS complete and WP app IS installed, migration success card SHOULD be shown`() { - val packageName = "packageName" - whenever(wordPressPublicData.currentPackageId()).thenReturn(packageName) - whenever(appPrefsWrapper.isJetpackMigrationCompleted()).thenReturn(true) - whenever(appStatus.isAppInstalled(packageName)).thenReturn(true) - - initSelectedSite(isJetpackApp = true) - - assertThat(getDashboardTabLastItems()[1]).isInstanceOf(SingleActionCard::class.java) - } - - @Test - fun `JP migration success card should have the correct text`() { - val packageName = "packageName" - whenever(wordPressPublicData.currentPackageId()).thenReturn(packageName) - whenever(appPrefsWrapper.isJetpackMigrationCompleted()).thenReturn(true) - whenever(appStatus.isAppInstalled(packageName)).thenReturn(true) - initSelectedSite(isJetpackApp = true) - - val expected = R.string.jp_migration_success_card_message - assertThat((getDashboardTabLastItems()[1] as SingleActionCard).textResource).isEqualTo(expected) - } - - @Test - fun `JP migration success card should have the correct image`() { - val packageName = "packageName" - whenever(wordPressPublicData.currentPackageId()).thenReturn(packageName) - whenever(appPrefsWrapper.isJetpackMigrationCompleted()).thenReturn(true) - whenever(appStatus.isAppInstalled(packageName)).thenReturn(true) - initSelectedSite(isJetpackApp = true) - - val expected = R.drawable.ic_wordpress_jetpack_appicon - assertThat((getDashboardTabLastItems()[1] as SingleActionCard).imageResource).isEqualTo(expected) - } - - @Test - fun `JP migration success card click should be tracked`() { - val packageName = "packageName" - whenever(wordPressPublicData.currentPackageId()).thenReturn(packageName) - whenever(appPrefsWrapper.isJetpackMigrationCompleted()).thenReturn(true) - whenever(appStatus.isAppInstalled(packageName)).thenReturn(true) - initSelectedSite(isJetpackApp = true) - - (getDashboardTabLastItems()[1] as SingleActionCard).onActionClick.invoke() - - verify(contentMigrationAnalyticsTracker).trackPleaseDeleteWordPressCardTapped() - } - - /* STATE LISTS */ - @Test - fun `given site select exists, then cardAndItem lists are not empty`() { - initSelectedSite() - - assertThat(getLastItems()).isNotEmpty - assertThat(getDashboardTabLastItems()).isNotEmpty - assertThat(getSiteMenuTabLastItems()).isNotEmpty - } - - @Test - fun `given selected site with tabs disabled, when all cards and items, then qs card exists`() { - initSelectedSite(isJetpackApp = true) - - assertThat(getLastItems().filterIsInstance(QuickStartCard::class.java)).isNotEmpty - } - - @Test - fun `given selected site, when dashboard cards and items, then dashboard cards exists`() { - initSelectedSite(isJetpackApp = true) - - val items = (uiModels.last() as SiteSelected).dashboardData - - assertThat(items.filterIsInstance(MySiteCardAndItem.Card::class.java)).isNotEmpty - } - - @Test - fun `given selected site, when dashboard cards and items, then list items not exist`() { - // setUpSiteItemBuilder() - initSelectedSite() - - val items = (uiModels.last() as SiteSelected).dashboardData - - assertThat(items.filterIsInstance(ListItem::class.java)).isEmpty() - } - - @Test - fun `when dashboard cards items built, then qs card exists`() { - // setUpSiteItemBuilder() - initSelectedSite(isJetpackApp = true) - - val items = (uiModels.last() as SiteSelected).dashboardData - - assertThat(items.filterIsInstance(QuickStartCard::class.java)).isNotEmpty - } - - @Test - fun `given site menu built, when dashboard cards items, then qs card not exists`() { - // setUpSiteItemBuilder(shouldEnableFocusPoint = true) - - initSelectedSite() - - val items = (uiModels.last() as SiteSelected).dashboardData - - assertThat(items.filterIsInstance(QuickStartCard::class.java)).isEmpty() - } - @Test - fun `given selected site, when site menu cards and items, then list items exist`() { - setUpSiteItemBuilder() - initSelectedSite() - - val items = (uiModels.last() as SiteSelected).dashboardData - - assertThat(items.filterIsInstance(ListItem::class.java)).isNotEmpty - } - - @Test - fun `given tabs enabled + dashboard default tab variant, when site menu cards + items, then qs card not exists`() { - // setUpSiteItemBuilder() - - initSelectedSite() - - val items = (uiModels.last() as SiteSelected).dashboardData - - assertThat(items.filterIsInstance(QuickStartCard::class.java)).isEmpty() - } - - @Test - fun `given selected site with domain credit, when dashboard cards + items, then domain reg card exists`() { - initSelectedSite(isJetpackApp = true) - isDomainCreditAvailable.value = DomainCreditAvailable(true) - - val items = (uiModels.last() as SiteSelected).dashboardData - - assertThat(items.filterIsInstance(DomainRegistrationCard::class.java)).isNotEmpty - } - - @Test - fun `given selected site with domain credit, when site menu cards and items, then domain reg card doesn't exist`() { - initSelectedSite() - isDomainCreditAvailable.value = DomainCreditAvailable(true) - - val items = (uiModels.last() as SiteSelected).dashboardData - - assertThat(items.filterIsInstance(DomainRegistrationCard::class.java)).isEmpty() - } - - /* JETPACK FEATURE CARD */ - @Test - fun `when feature card criteria is not met, then items does not contain feature card`() = test { - whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(false) - - initSelectedSite() - - assertThat(getSiteMenuTabLastItems()[0]).isNotInstanceOf(JetpackFeatureCard::class.java) - assertThat(getLastItems()[0]).isNotInstanceOf(JetpackFeatureCard::class.java) - assertThat(getDashboardTabLastItems()[0]).isNotInstanceOf(JetpackFeatureCard::class.java) - } - - @Test - fun `when feature card criteria is met + show at top, then items do contain feature card`() = test { - whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) - whenever(jetpackFeatureCardHelper.shouldShowFeatureCardAtTop()).thenReturn(true) - - initSelectedSite() - - assertThat(getSiteMenuTabLastItems()[1]).isInstanceOf(JetpackFeatureCard::class.java) - assertThat(getMenuItems()[1]).isInstanceOf(JetpackFeatureCard::class.java) - } - - @Test - fun `when feature card criteria is met + show at bottom, then items do contain feature card`() = test { - whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) - whenever(jetpackFeatureCardHelper.shouldShowFeatureCardAtTop()).thenReturn(false) - - initSelectedSite() - - assertThat(getSiteMenuTabLastItems().filterIsInstance(JetpackFeatureCard::class.java)).isNotEmpty - } - - @Test - fun `when jetpack feature card is shown, then jetpack feature card shown is tracked`() = test { - whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) - - initSelectedSite() - - verify(jetpackFeatureCardShownTracker, atLeastOnce()).trackShown(MySiteCardAndItem.Type.JETPACK_FEATURE_CARD) - } - - @Test - fun `when Jetpack feature card is clicked, then jetpack feature card clicked is tracked`() { - whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) - initSelectedSite() - - findJetpackFeatureCard()?.onClick?.click() - - verify(jetpackFeatureCardHelper).track(Stat.REMOVE_FEATURE_CARD_TAPPED) - } - - @Test - fun `when Jetpack feature card learn more is clicked, then learn more is tracked`() { - whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) - whenever(jetpackFeatureCardHelper.getLearnMoreUrl()).thenReturn("https://jetpack.com") - initSelectedSite() - - findJetpackFeatureCard()?.onLearnMoreClick?.click() - - verify(jetpackFeatureCardHelper).track(Stat.REMOVE_FEATURE_CARD_LINK_TAPPED) - } - - @Test - fun `when Jetpack feature card menu is clicked, then menu clicked is tracked`() { - whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) - initSelectedSite() - - findJetpackFeatureCard()?.onMoreMenuClick?.click() - - verify(jetpackFeatureCardHelper).track(Stat.REMOVE_FEATURE_CARD_MENU_ACCESSED) - } - - @Test - fun `when Jetpack feature card hide this is clicked, then hide is tracked`() { - whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) - initSelectedSite() - - findJetpackFeatureCard()?.onHideMenuItemClick?.click() - - verify(jetpackFeatureCardHelper).hideJetpackFeatureCard() - } - - @Test - fun `when Jetpack feature card remind later is clicked, then remind later is tracked`() { - whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) - initSelectedSite() - - findJetpackFeatureCard()?.onRemindMeLaterItemClick?.click() - - verify(jetpackFeatureCardHelper).setJetpackFeatureCardLastShownTimeStamp(any()) - } - @Test fun `when onActionableEmptyViewVisible is invoked then show jetpack individual plugin overlay`() = test { @@ -1233,30 +594,6 @@ class MySiteViewModelTest : BaseUnitTest() { assertThat(viewModel.onShowJetpackIndividualPluginOverlay.value?.peekContent()).isNull() } - - private fun findDomainRegistrationCard() = - getLastItems().find { it is DomainRegistrationCard } as DomainRegistrationCard? - - private fun findJetpackFeatureCard() = - getMenuItems().find { it is JetpackFeatureCard } as JetpackFeatureCard? - - private fun findBackupListItem() = getMenuItems().filterIsInstance(ListItem::class.java) - .firstOrNull { it.primaryText == UiStringRes(R.string.backup) } - - private fun findScanListItem() = getMenuItems().filterIsInstance(ListItem::class.java) - .firstOrNull { it.primaryText == UiStringRes(R.string.scan) } - - - private fun findJetpackBadgeListItem() = getSiteMenuTabLastItems().filterIsInstance(JetpackBadge::class.java) - - private fun getLastItems() = (uiModels.last() as SiteSelected).dashboardData - - private fun getMenuItems() = (uiModels.last() as SiteSelected).dashboardData - - private fun getDashboardTabLastItems() = (uiModels.last() as SiteSelected).dashboardData - - private fun getSiteMenuTabLastItems() = (uiModels.last() as SiteSelected).dashboardData - private fun getSiteInfoHeaderCard() = (uiModels.last() as SiteSelected).dashboardData[0] @Suppress("LongParameterList") @@ -1287,71 +624,6 @@ class MySiteViewModelTest : BaseUnitTest() { selectedSite.value = SelectedSite(site) } - private fun setUpSiteItemBuilder( - backupAvailable: Boolean = false, - scanAvailable: Boolean = false, - shouldEnableFocusPoint: Boolean = false, - activeTask: QuickStartTask? = null - ) { - val siteItemsBuilderParams = MySiteCardAndItemBuilderParams.SiteItemsBuilderParams( - site = site, - activeTask = activeTask, - backupAvailable = backupAvailable, - scanAvailable = scanAvailable, - enableFocusPoints = shouldEnableFocusPoint, - onClick = mock(), - isBlazeEligible = true - ) - - whenever(siteItemsBuilder.build(anyOrNull())).thenReturn(initSiteItems(siteItemsBuilderParams)) - } - - - private fun initSiteItems(params: MySiteCardAndItemBuilderParams.SiteItemsBuilderParams): List { - val items = mutableListOf() - items.add( - ListItem( - 0, - UiStringRes(0), - onClick = ListItemInteraction.create(ListItemAction.POSTS, params.onClick), - listItemAction = ListItemAction.POSTS - ) - ) - if (params.scanAvailable) { - items.add( - ListItem( - 0, - UiStringRes(R.string.scan), - onClick = mock(), - listItemAction = ListItemAction.SCAN - ) - ) - } - if (params.backupAvailable) { - items.add( - ListItem( - 0, - UiStringRes(R.string.backup), - onClick = mock(), - listItemAction = ListItemAction.BACKUP - ) - ) - } - if (params.isBlazeEligible) { - items.add( - ListItem( - 0, - UiStringRes(R.string.blaze_menu_item_label), - onClick = mock(), - disablePrimaryIconTint = true, - listItemAction = ListItemAction.BLAZE - ) - ) - } - - return items - } - fun ViewModel.invokeOnCleared() { val viewModelStore = ViewModelStore() val viewModelProvider = ViewModelProvider(viewModelStore, object : ViewModelProvider.Factory { From 502249a6a69e1cea523fe6db68e86dea00dc0245 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 17:09:56 +0530 Subject: [PATCH 220/250] + Adds: a debounce delay to fix the tracking --- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 4fc9bd1c02d6..4ecfc571b947 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -6,6 +6,7 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.cancel +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.modules.BG_THREAD @@ -229,6 +230,8 @@ class DashboardCardsViewModelSlice @Inject constructor( private fun trackCardShown(dashboardData: List) = with(dashboardData) { trackingJob?.cancel() trackingJob = scope.launch(bgDispatcher) { + delay(TRACKING_JOB_DEBOUNCE_DELAY) + filterIsInstance().let { cardViewModelSlice.trackCardShown(it) } @@ -274,3 +277,5 @@ class DashboardCardsViewModelSlice @Inject constructor( quickStartCardViewModelSlice.build(siteModel) } } + +const val TRACKING_JOB_DEBOUNCE_DELAY = 600L From fbf936272d98d443d449370da179e34a458756a6 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 17:47:01 +0530 Subject: [PATCH 221/250] [WIP] Fixes: Unnecessary stubbings and removes redundant tests --- .../android/ui/mysite/MySiteViewModel.kt | 2 +- .../android/ui/mysite/MySiteViewModelTest.kt | 122 ++---------------- .../QuickStartCardViewModelSliceTest.kt | 5 - 3 files changed, 12 insertions(+), 117 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index e58d75a11cf2..021b1590d3a4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -380,7 +380,7 @@ class MySiteViewModel @Inject constructor( } } - fun onSitePicked(site: SiteModel) { + private fun onSitePicked(site: SiteModel) { siteInfoHeaderCardViewModelSlice.buildCard(site) dashboardItemsViewModelSlice.clearValue() dashboardCardsViewModelSlice.clearValue() diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt index 104eaf478d71..f78c8c03ad6b 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt @@ -14,9 +14,8 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.junit.MockitoJUnitRunner -import org.mockito.kotlin.any import org.mockito.kotlin.atLeastOnce -import org.mockito.kotlin.mock +import org.mockito.kotlin.never import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @@ -26,27 +25,19 @@ import org.wordpress.android.analytics.AnalyticsTracker.Stat import org.wordpress.android.fluxc.Dispatcher import org.wordpress.android.fluxc.model.PostModel import org.wordpress.android.fluxc.model.SiteModel -import org.wordpress.android.fluxc.model.dashboard.CardModel.PostsCardModel -import org.wordpress.android.fluxc.model.dashboard.CardModel.PostsCardModel.PostCardModel import org.wordpress.android.fluxc.model.page.PageModel import org.wordpress.android.fluxc.model.page.PageStatus.PUBLISHED import org.wordpress.android.fluxc.store.AccountStore import org.wordpress.android.fluxc.store.PostStore -import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTask import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTaskType import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalOverlayUtil import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhaseHelper import org.wordpress.android.ui.jetpackoverlay.individualplugin.WPJetpackIndividualPluginHelper import org.wordpress.android.ui.jetpackplugininstall.fullplugin.GetShowJetpackFullPluginInstallOnboardingUseCase -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.SiteInfoHeaderCard -import org.wordpress.android.ui.mysite.MySiteCardAndItem.Item.InfoItem -import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.InfoItemBuilderParams import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.AccountData -import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.CardsUpdate import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.QuickStartUpdate import org.wordpress.android.ui.mysite.MySiteUiState.PartialState.SelectedSite import org.wordpress.android.ui.mysite.MySiteViewModel.State.NoSites -import org.wordpress.android.ui.mysite.MySiteViewModel.State.SiteSelected import org.wordpress.android.ui.mysite.MySiteViewModel.TextInputDialogModel import org.wordpress.android.ui.mysite.cards.DashboardCardsViewModelSlice import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker @@ -54,18 +45,13 @@ import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository.QuickStartCategory import org.wordpress.android.ui.mysite.cards.siteinfo.SiteInfoHeaderCardViewModelSlice import org.wordpress.android.ui.mysite.items.DashboardItemsViewModelSlice -import org.wordpress.android.ui.mysite.items.infoitem.MySiteInfoItemBuilder -import org.wordpress.android.ui.mysite.items.listitem.SiteItemsBuilder import org.wordpress.android.ui.pages.SnackbarMessageHolder import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.quickstart.QuickStartTaskDetails import org.wordpress.android.ui.quickstart.QuickStartTracker import org.wordpress.android.ui.quickstart.QuickStartType import org.wordpress.android.ui.sitecreation.misc.SiteCreationSource -import org.wordpress.android.ui.utils.UiString.UiStringRes -import org.wordpress.android.ui.utils.UiString.UiStringText import org.wordpress.android.util.BuildConfigWrapper -import org.wordpress.android.util.JetpackBrandingUtils import org.wordpress.android.util.QuickStartUtilsWrapper import org.wordpress.android.util.SnackbarSequencer import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper @@ -76,9 +62,6 @@ import java.util.Date @ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) class MySiteViewModelTest : BaseUnitTest() { - @Mock - lateinit var siteItemsBuilder: SiteItemsBuilder - @Mock lateinit var analyticsTrackerWrapper: AnalyticsTrackerWrapper @@ -115,9 +98,6 @@ class MySiteViewModelTest : BaseUnitTest() { @Mock lateinit var getShowJetpackFullPluginInstallOnboardingUseCase: GetShowJetpackFullPluginInstallOnboardingUseCase - @Mock - lateinit var jetpackBrandingUtils: JetpackBrandingUtils - @Mock lateinit var appPrefsWrapper: AppPrefsWrapper @@ -139,9 +119,6 @@ class MySiteViewModelTest : BaseUnitTest() { @Mock lateinit var wpJetpackIndividualPluginHelper: WPJetpackIndividualPluginHelper - @Mock - lateinit var mySiteInfoItemBuilder: MySiteInfoItemBuilder - @Mock lateinit var siteInfoHeaderCardViewModelSlice: SiteInfoHeaderCardViewModelSlice @@ -162,8 +139,6 @@ class MySiteViewModelTest : BaseUnitTest() { private lateinit var dialogModels: MutableList private lateinit var navigationActions: MutableList private lateinit var showSwipeRefreshLayout: MutableList - private val avatarUrl = "https://1.gravatar.com/avatar/1000?s=96&d=identicon" - private val userName = "Username" private val siteLocalId = 1 private val siteUrl = "http://site.com" private val siteIcon = "http://site.com/icon.jpg" @@ -178,7 +153,6 @@ class MySiteViewModelTest : BaseUnitTest() { private val currentAvatar = MutableLiveData(AccountData("","")) private val quickStartUpdate = MutableLiveData(QuickStartUpdate()) - private val activeTask = MutableLiveData() private val quickStartCategory: QuickStartCategory get() = QuickStartCategory( taskType = QuickStartTaskType.CUSTOMIZE, @@ -186,35 +160,6 @@ class MySiteViewModelTest : BaseUnitTest() { completedTasks = emptyList() ) - private val cardsUpdate = MutableLiveData( - CardsUpdate( - cards = listOf( - PostsCardModel( - hasPublished = true, - draft = listOf( - PostCardModel( - id = 1, - title = "draft", - content = "content", - featuredImage = "featuredImage", - date = Date() - ) - ), - scheduled = listOf( - PostCardModel( - id = 2, - title = "scheduled", - content = "", - featuredImage = null, - date = Date() - ) - ) - ) - ) - ) - ) - - @Suppress("LongMethod") @Before fun setUp() { @@ -227,11 +172,7 @@ class MySiteViewModelTest : BaseUnitTest() { onShowSiteIconProgressBar.value = null onSiteSelected.value = null selectedSite.value = null - whenever(selectedSiteRepository.siteSelected).thenReturn(onSiteSelected) - whenever(quickStartRepository.activeTask).thenReturn(activeTask) whenever(quickStartRepository.quickStartType).thenReturn(quickStartType) - whenever(jetpackBrandingUtils.getBrandingTextForScreen(any())).thenReturn(mock()) - whenever(quickStartRepository.quickStartMenuStep).thenReturn(mock()) whenever(siteInfoHeaderCardViewModelSlice.uiModel).thenReturn(MutableLiveData()) whenever(accountDataViewModelSlice.uiModel).thenReturn(MutableLiveData()) @@ -296,7 +237,6 @@ class MySiteViewModelTest : BaseUnitTest() { whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) whenever(homePageDataLoader.loadHomepage(site)).thenReturn(homepage) - whenever(siteInfoHeaderCardViewModelSlice.getParams(site)).thenReturn(mock()) } /* SITE STATE */ @@ -310,28 +250,24 @@ class MySiteViewModelTest : BaseUnitTest() { } @Test - fun `model contains header of selected site`() { + fun `when selected site is changed, then reset shown tracker is called`() = test { initSelectedSite() - assertThat(uiModels.last()).isInstanceOf(SiteSelected::class.java) + viewModel.onSitePicked() - assertThat(getSiteInfoHeaderCard()).isInstanceOf(SiteInfoHeaderCard::class.java) + verify(dashboardCardsViewModelSlice, atLeastOnce()).resetShownTracker() + verify(dashboardItemsViewModelSlice, atLeastOnce()).resetShownTracker() } + @Test - fun `when selected site is changed, then cardTracker is reset`() = test { + fun `when selected site is changed, then clear ui model value is called`() = test { initSelectedSite() - verify(cardsTracker, atLeastOnce()).resetShown() - } - - /* AVATAR */ - - @Test - fun `account avatar url value is emitted and updated from the source`() { - currentAvatar.value = AccountData(avatarUrl,userName) + viewModel.onSitePicked() - assertThat((uiModels.last() as NoSites).avatarUrl).isEqualTo(avatarUrl) + verify(dashboardCardsViewModelSlice, atLeastOnce()).clearValue() + verify(dashboardItemsViewModelSlice, atLeastOnce()).clearValue() } @Test @@ -502,37 +438,9 @@ class MySiteViewModelTest : BaseUnitTest() { viewModel.onPostUploaded(postUploadedEvent) -// verify(mySiteSourceManager, never()).refreshBloggingPrompts(true) + verify(dashboardCardsViewModelSlice, never()).refreshBloggingPrompt() } - /* DASHBOARD ERROR SNACKBAR */ - - @Test - fun `given show snackbar in cards update, when dashboard cards updated, then dashboard snackbar shown`() = - test { - initSelectedSite() - - cardsUpdate.value = cardsUpdate.value?.copy(showSnackbarError = true) - - assertThat(snackbars).containsOnly( - SnackbarMessageHolder(UiStringRes(R.string.my_site_dashboard_update_error)) - ) - } - - @Test - fun `given show snackbar not in cards update, when dashboard cards updated, then dashboard snackbar not shown`() = - test { - initSelectedSite() - - cardsUpdate.value = cardsUpdate.value?.copy(showSnackbarError = false) - - assertThat(snackbars).doesNotContain( - SnackbarMessageHolder(UiStringRes(R.string.my_site_dashboard_update_error)) - ) - } - - /* SWIPE REFRESH */ - @Test fun `given refresh, when not invoked as PTR, then pull-to-refresh request is not tracked`() { initSelectedSite() @@ -594,26 +502,18 @@ class MySiteViewModelTest : BaseUnitTest() { assertThat(viewModel.onShowJetpackIndividualPluginOverlay.value?.peekContent()).isNull() } - private fun getSiteInfoHeaderCard() = (uiModels.last() as SiteSelected).dashboardData[0] - @Suppress("LongParameterList") private fun initSelectedSite( isQuickStartInProgress: Boolean = false, - showStaleMessage: Boolean = false, isSiteUsingWpComRestApi: Boolean = true, - shouldShowJetpackBranding: Boolean = true, isJetpackApp: Boolean = false ) { - whenever( - mySiteInfoItemBuilder.build(InfoItemBuilderParams(isStaleMessagePresent = showStaleMessage)) - ).thenReturn(if (showStaleMessage) InfoItem(title = UiStringText("")) else null) quickStartUpdate.value = QuickStartUpdate( categories = if (isQuickStartInProgress) listOf(quickStartCategory) else emptyList() ) // in order to build the dashboard cards, this value should be true along with isSiteUsingWpComRestApi whenever(buildConfigWrapper.isJetpackApp).thenReturn(isJetpackApp) - whenever(jetpackBrandingUtils.shouldShowJetpackBrandingInDashboard()).thenReturn(shouldShowJetpackBranding) if (isSiteUsingWpComRestApi) { site.setIsWPCom(true) site.setIsJetpackConnected(true) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt index 15d3bdd035d0..01ee12be75dd 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/quickstart/QuickStartCardViewModelSliceTest.kt @@ -8,7 +8,6 @@ import org.junit.Ignore import org.junit.Test import org.mockito.Mock import org.mockito.kotlin.any -import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.wordpress.android.BaseUnitTest @@ -309,9 +308,5 @@ class QuickStartCardViewModelSliceTest : BaseUnitTest() { whenever(quickStartStore.getCompletedTasksByType(siteLocalId.toLong(), GROW)).thenReturn( listOf(PUBLISH_POST) ) - whenever(htmlMessageUtils.getHtmlMessageFromStringFormat(anyOrNull())).thenReturn("") - whenever(resourceProvider.getString(any())).thenReturn("") - whenever(resourceProvider.getString(any(), any())).thenReturn("") - whenever(htmlCompat.fromHtml(any(), any())).thenReturn(" ") } } From 02192d81fdc3bf224e9dbdc9b33a3f1e91bf6538 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 18:07:54 +0530 Subject: [PATCH 222/250] + Adds: OnCleared to the SiteInfoHeaderCardViewModelSlice --- .../wordpress/android/ui/mysite/MySiteViewModel.kt | 1 + .../siteinfo/SiteInfoHeaderCardViewModelSlice.kt | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 021b1590d3a4..fdc59aca6ca6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -272,6 +272,7 @@ class MySiteViewModel @Inject constructor( siteIconUploadHandler.clear() quickStartRepository.clear() dispatcher.unregister(this) + siteInfoHeaderCardViewModelSlice.onCleared() dashboardCardsViewModelSlice.onCleared() dashboardItemsViewModelSlice.onCleared() accountDataViewModelSlice.onCleared() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt index ec2b74ff8365..a3c9c094d0eb 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewModelSlice.kt @@ -9,6 +9,8 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.distinctUntilChanged import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import org.wordpress.android.R import org.wordpress.android.analytics.AnalyticsTracker @@ -79,6 +81,8 @@ class SiteInfoHeaderCardViewModelSlice @Inject constructor( private lateinit var scope: CoroutineScope + private var uploadIconJob: Job? = null + fun initialize(viewModelScope: CoroutineScope) { this.scope = viewModelScope } @@ -266,7 +270,7 @@ class SiteInfoHeaderCardViewModelSlice @Inject constructor( if (success && croppedUri != null) { analyticsTrackerWrapper.track(AnalyticsTracker.Stat.MY_SITE_ICON_CROPPED) selectedSiteRepository.showSiteIconProgressBar(true) - scope.launch(bgDispatcher) { + uploadIconJob = scope.launch(bgDispatcher) { wpMediaUtilsWrapper.fetchMediaToUriWrapper(UriWrapper(croppedUri))?.let { fetchMedia -> mediaUtilsWrapper.getRealPathFromURI(fetchMedia.uri) }?.let { @@ -313,4 +317,9 @@ class SiteInfoHeaderCardViewModelSlice @Inject constructor( val mimeType = contextProvider.getContext().contentResolver.getType(uri) return fluxCUtilsWrapper.mediaModelFromLocalUri(uri, mimeType, site.id) } + + fun onCleared() { + uploadIconJob?.cancel() + scope.cancel() + } } From 42ec262586a2c0890c67aee2062e970e3bfbc1e8 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 18:08:21 +0530 Subject: [PATCH 223/250] [WIP] Updates: the MySiteViewModelTest --- .../android/ui/mysite/MySiteViewModelTest.kt | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt index f78c8c03ad6b..81cccaee595f 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt @@ -404,7 +404,7 @@ class MySiteViewModelTest : BaseUnitTest() { verify(quickStartUtilsWrapper) .startQuickStart(site.id, false, quickStartRepository.quickStartType, quickStartTracker) -// verify(mySiteSourceManager).refreshQuickStart() + verify(dashboardCardsViewModelSlice).startQuickStart(site) } @Test @@ -425,7 +425,7 @@ class MySiteViewModelTest : BaseUnitTest() { viewModel.onPostUploaded(postUploadedEvent) -// verify(mySiteSourceManager).refreshBloggingPrompts(true) + verify(dashboardCardsViewModelSlice).refreshBloggingPrompt() } @Test @@ -450,13 +450,6 @@ class MySiteViewModelTest : BaseUnitTest() { verify(analyticsTrackerWrapper, times(0)).track(Stat.MY_SITE_PULL_TO_REFRESH) } - /* CLEARED */ - @Test - fun `when vm cleared() is invoked, then MySiteSource clear() is invoked`() { - viewModel.invokeOnCleared() - -// verify(mySiteSourceManager).clear() - } /* LAND ON THE EDITOR A/B EXPERIMENT */ @Test @@ -502,6 +495,17 @@ class MySiteViewModelTest : BaseUnitTest() { assertThat(viewModel.onShowJetpackIndividualPluginOverlay.value?.peekContent()).isNull() } + + @Test + fun `when onCleared is called, then clears all the vm slices`() { + viewModel.invokeOnCleared() + + verify(siteInfoHeaderCardViewModelSlice).onCleared() + verify(accountDataViewModelSlice).onCleared() + verify(dashboardCardsViewModelSlice).onCleared() + verify(dashboardItemsViewModelSlice).onCleared() + } + @Suppress("LongParameterList") private fun initSelectedSite( isQuickStartInProgress: Boolean = false, From b7e9d2d54c968c7cf168f95eb3bf60c7828ba9db Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 18:15:15 +0530 Subject: [PATCH 224/250] [WIP] + Adds: tests for MySiteViewModel --- .../android/ui/mysite/MySiteViewModelTest.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt index 81cccaee595f..57c7a5b9cff0 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt @@ -270,6 +270,24 @@ class MySiteViewModelTest : BaseUnitTest() { verify(dashboardItemsViewModelSlice, atLeastOnce()).clearValue() } + @Test + fun `given jp app, when selected site is changed, then dashboard cards are fetched`() = test { + initSelectedSite(isJetpackApp = true) + + viewModel.onSitePicked() + + verify(dashboardCardsViewModelSlice, atLeastOnce()).buildCards(site) + } + + @Test + fun `given not jp app, when selected site is changed, then site items are fetched`() = test { + initSelectedSite() + + viewModel.onSitePicked() + + verify(dashboardItemsViewModelSlice, atLeastOnce()).buildItems(site) + } + @Test fun `avatar press opens me screen`() { viewModel.onAvatarPressed() From 2bf875b6bebdfc59129e45f94d978566599ed56f Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 19:16:41 +0530 Subject: [PATCH 225/250] + Adds: Tests for refresh scenario in MySiteViewModel --- .../android/ui/mysite/MySiteViewModel.kt | 2 +- .../android/ui/mysite/MySiteViewModelTest.kt | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index fdc59aca6ca6..b93abb618add 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -370,7 +370,7 @@ class MySiteViewModel @Inject constructor( quickStartTracker.track(Stat.QUICK_START_REQUEST_DIALOG_NEGATIVE_TAPPED) } - fun buildDashboardOrSiteItems(site: SiteModel) { + private fun buildDashboardOrSiteItems(site: SiteModel) { siteInfoHeaderCardViewModelSlice.buildCard(site) if (shouldShowDashboard(site)) { dashboardCardsViewModelSlice.buildCards(site) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt index 57c7a5b9cff0..e0ce53e6d6d8 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt @@ -469,6 +469,29 @@ class MySiteViewModelTest : BaseUnitTest() { } + + @Test + fun `given jp app, when refresh invoked, then dashboard cards are refreshed`() { + initSelectedSite(isJetpackApp = true) + + viewModel.refresh() + + verify(dashboardCardsViewModelSlice).buildCards(site) + verify(dashboardItemsViewModelSlice).clearValue() + } + + @Test + fun `given wp app, when refresh invoked, then site items are refreshed`() { + initSelectedSite(isJetpackApp = false) + + viewModel.refresh() + + verify(dashboardItemsViewModelSlice).buildItems(site) + verify(dashboardCardsViewModelSlice).clearValue() + } + + + /* LAND ON THE EDITOR A/B EXPERIMENT */ @Test fun `given the land on the editor feature is enabled, then the home page editor is shown`() = test { From 9b192367748480d2573b914b6388d0498b0880b0 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 19:18:52 +0530 Subject: [PATCH 226/250] + Adds: tests for MySiteViewModel on Resume scenario --- .../android/ui/mysite/MySiteViewModelTest.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt index e0ce53e6d6d8..cd1b24821aec 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/MySiteViewModelTest.kt @@ -468,6 +468,26 @@ class MySiteViewModelTest : BaseUnitTest() { verify(analyticsTrackerWrapper, times(0)).track(Stat.MY_SITE_PULL_TO_REFRESH) } + @Test + fun `given jp app, when onResume invoked, then dashboard cards are fetched`() { + initSelectedSite(isJetpackApp = true) + + viewModel.onResume() + + verify(dashboardCardsViewModelSlice).buildCards(site) + verify(dashboardItemsViewModelSlice).clearValue() + } + + @Test + fun `given wp app, when onResume invoked, then site items are fetched`() { + initSelectedSite(isJetpackApp = false) + + viewModel.refresh() + + verify(dashboardItemsViewModelSlice).buildItems(site) + verify(dashboardCardsViewModelSlice).clearValue() + } + @Test From 96ccf6340b0958e22c42f34875c35ecbb2754568 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 19:32:27 +0530 Subject: [PATCH 227/250] + Adds: test for JetpackSwitchMenuViewModelSlice --- .../JetpackSwitchMenuViewModelSliceTest.kt | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSliceTest.kt diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSliceTest.kt new file mode 100644 index 000000000000..275744d2dfcf --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSliceTest.kt @@ -0,0 +1,144 @@ +package org.wordpress.android.ui.mysite.items.jetpackSwitchmenu + +import junit.framework.TestCase.assertNull +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.mockito.kotlin.any +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever +import org.wordpress.android.BaseUnitTest +import org.wordpress.android.analytics.AnalyticsTracker +import org.wordpress.android.ui.mysite.MySiteCardAndItem +import org.wordpress.android.ui.mysite.SiteNavigationAction +import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardHelper +import org.wordpress.android.ui.prefs.AppPrefsWrapper +import kotlin.test.Test +import kotlin.test.assertNotNull + +@ExperimentalCoroutinesApi +@RunWith(MockitoJUnitRunner::class) +class JetpackSwitchMenuViewModelSliceTest: BaseUnitTest(){ + @Mock + lateinit var appPrefsWrapper: AppPrefsWrapper + + @Mock + lateinit var jetpackFeatureCardHelper: JetpackFeatureCardHelper + + private lateinit var viewModelSlice: JetpackSwitchMenuViewModelSlice + + private lateinit var uiModels: MutableList + + private lateinit var navigationEvents: MutableList + + @Before + fun setUp() { + viewModelSlice = JetpackSwitchMenuViewModelSlice( + jetpackFeatureCardHelper, + appPrefsWrapper + ) + + uiModels = mutableListOf() + viewModelSlice.uiModel.observeForever { + uiModels.add(it) + } + + navigationEvents = mutableListOf() + viewModelSlice.onNavigation.observeForever { + it?.let { navigationEvents.add(it.peekContent()) } + } + } + + @Test +fun `given jetpack feature card should not be shown, ui model is null`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowSwitchToJetpackMenuCard()).thenReturn(false) + + // when + viewModelSlice.buildJetpackSwitchMenu() + advanceUntilIdle() + + // then + assertNull(uiModels[0]) + } + + @Test + fun `given jetpack feature card should be shown, ui model is not null`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowSwitchToJetpackMenuCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackSwitchMenu() + advanceUntilIdle() + + // then + assertNotNull(uiModels[0]) + } + + @Test + fun `given card shown, when clicked, then navigation event is emitted`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowSwitchToJetpackMenuCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackSwitchMenu() + advanceUntilIdle() + uiModels[0]?.onClick?.click() + advanceUntilIdle() + + // then + verify(jetpackFeatureCardHelper).track(AnalyticsTracker.Stat.REMOVE_FEATURE_CARD_TAPPED) + assertThat(navigationEvents[0]).isInstanceOf(SiteNavigationAction.OpenJetpackFeatureOverlay::class.java) + } + + @Test + fun `given card shown, when remind me later clicked, then ui model is null`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowSwitchToJetpackMenuCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackSwitchMenu() + advanceUntilIdle() + uiModels[0]?.onRemindMeLaterItemClick?.click() + advanceUntilIdle() + + // then + verify(jetpackFeatureCardHelper).track(AnalyticsTracker.Stat.REMOVE_FEATURE_CARD_REMIND_LATER_TAPPED) + verify(appPrefsWrapper).setSwitchToJetpackMenuCardLastShownTimestamp(any()) + assertNull(uiModels[1]) + } + + @Test + fun `given card shown, when hide menu item clicked, then ui model is null`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowSwitchToJetpackMenuCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackSwitchMenu() + advanceUntilIdle() + uiModels[0]?.onHideMenuItemClick?.click() + advanceUntilIdle() + + // then + verify(jetpackFeatureCardHelper).hideSwitchToJetpackMenuCard() + assertNull(uiModels[1]) + } + + @Test + fun `given card shown, when more menu clicked, then analytics is tracked`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowSwitchToJetpackMenuCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackSwitchMenu() + advanceUntilIdle() + uiModels[0]?.onMoreMenuClick?.click() + advanceUntilIdle() + + // then + verify(jetpackFeatureCardHelper).track(AnalyticsTracker.Stat.REMOVE_FEATURE_CARD_MENU_ACCESSED) + } +} From b45d38b2428828ee47a75ddad4f2969e41de1992 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 20:39:20 +0530 Subject: [PATCH 228/250] + Adds: test for JetpackFeatureCardViewModelSlice --- .../JetpackFeatureCardViewModelSlice.kt | 5 +- .../JetpackFeatureCardViewModelSliceTest.kt | 172 ++++++++++++++++++ 2 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSliceTest.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSlice.kt index e654bff1c54a..920f28554e71 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSlice.kt @@ -23,7 +23,10 @@ class JetpackFeatureCardViewModelSlice @Inject constructor( val uiModel = _uiModel.distinctUntilChanged() suspend fun buildJetpackFeatureCard() { - if (!jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()) _uiModel.postValue(null) + if (!jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()){ + _uiModel.postValue(null) + return + } _uiModel.postValue( MySiteCardAndItem.Card.JetpackFeatureCard( content = jetpackFeatureCardHelper.getCardContent(), diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSliceTest.kt new file mode 100644 index 000000000000..5cf0317c2eb1 --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSliceTest.kt @@ -0,0 +1,172 @@ +package org.wordpress.android.ui.mysite.items.jetpackfeaturecard + +import junit.framework.TestCase.assertNull +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnitRunner +import org.mockito.kotlin.any +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever +import org.wordpress.android.BaseUnitTest +import org.wordpress.android.analytics.AnalyticsTracker +import org.wordpress.android.ui.mysite.MySiteCardAndItem +import org.wordpress.android.ui.mysite.SiteNavigationAction +import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardHelper +import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardShownTracker +import kotlin.test.Test +import kotlin.test.assertNotNull + + +@ExperimentalCoroutinesApi +@RunWith(MockitoJUnitRunner::class) +class JetpackFeatureCardViewModelSliceTest: BaseUnitTest() { + @Mock + lateinit var jetpackFeatureCardHelper: JetpackFeatureCardHelper + + @Mock + lateinit var jetpackFeatureCardShownTracker: JetpackFeatureCardShownTracker + + private lateinit var viewModelSlice: JetpackFeatureCardViewModelSlice + + private lateinit var uiModels: MutableList + + private lateinit var navigationEvents: MutableList + + @Before + fun setUp() { + viewModelSlice = JetpackFeatureCardViewModelSlice( + jetpackFeatureCardHelper, + jetpackFeatureCardShownTracker + ) + + uiModels = mutableListOf() + viewModelSlice.uiModel.observeForever { + uiModels.add(it) + } + + navigationEvents = mutableListOf() + viewModelSlice.onNavigation.observeForever { + it?.let { navigationEvents.add(it.peekContent()) } + } + } + + @Test + fun `given jetpack feature card should not be shown, ui model is null`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(false) + + // when + viewModelSlice.buildJetpackFeatureCard() + + // then + assertNull(uiModels.last()) + } + + @Test + fun `given jetpack feature card should be shown, ui model is not null`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackFeatureCard() + + // then + assertNotNull(uiModels.last()) + } + + @Test + fun `given jetpack feature card should be shown, onJetpackFeatureCardClick is called`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackFeatureCard() + uiModels.last()?.onClick?.click() + advanceUntilIdle() + + // then + verify(jetpackFeatureCardHelper).track(AnalyticsTracker.Stat.REMOVE_FEATURE_CARD_TAPPED) + assertThat(navigationEvents.last()).isInstanceOf(SiteNavigationAction.OpenJetpackFeatureOverlay::class.java) + } + + @Test + fun `given jetpack feature card should be shown, onJetpackFeatureCardHideMenuItemClick is called`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackFeatureCard() + uiModels.last()?.onHideMenuItemClick?.click() + advanceUntilIdle() + + // then + verify(jetpackFeatureCardHelper).hideJetpackFeatureCard() + assertNull(uiModels.last()) + } + + @Test + fun `given jetpack feature card should be shown, onJetpackFeatureCardLearnMoreClick is called`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackFeatureCard() + uiModels.last()?.onLearnMoreClick?.click() + advanceUntilIdle() + + // then + verify(jetpackFeatureCardHelper).track(AnalyticsTracker.Stat.REMOVE_FEATURE_CARD_LINK_TAPPED) + assertThat(navigationEvents.last()).isInstanceOf(SiteNavigationAction.OpenJetpackFeatureOverlay::class.java) + } + + @Test + fun `given jetpack feature card should be shown, onJetpackFeatureCardRemindMeLaterClick is called`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackFeatureCard() + uiModels.last()?.onRemindMeLaterItemClick?.click() + advanceUntilIdle() + + // then + verify(jetpackFeatureCardHelper).setJetpackFeatureCardLastShownTimeStamp(any()) + assertNull(uiModels.last()) + } + + @Test + fun `given jetpack feature card should be shown, onJetpackFeatureCardMoreMenuClick is called`() = test { + // given + whenever(jetpackFeatureCardHelper.shouldShowJetpackFeatureCard()).thenReturn(true) + + // when + viewModelSlice.buildJetpackFeatureCard() + uiModels.last()?.onMoreMenuClick?.click() + advanceUntilIdle() + + // then + verify(jetpackFeatureCardHelper).track(AnalyticsTracker.Stat.REMOVE_FEATURE_CARD_MENU_ACCESSED) + } + + @Test + fun `when trackshown is called, then jetpackFeatureCardShownTracker is called`() = test { + // when + viewModelSlice.trackShown(mock()) + + // then + verify(jetpackFeatureCardShownTracker).trackShown(any()) + } + + @Test + fun `when clearValue is called, then ui model is null`() = test { + // when + viewModelSlice.clearValue() + + // then + assertNull(uiModels.last()) + } +} From 7757259eb22405b6c6bf96c444990bd34b4f273c Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Wed, 13 Mar 2024 20:49:41 +0530 Subject: [PATCH 229/250] * Fixes: detekt issue --- .../jetpackfeaturecard/JetpackFeatureCardViewModelSliceTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSliceTest.kt index 5cf0317c2eb1..715f077fd356 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/jetpackfeaturecard/JetpackFeatureCardViewModelSliceTest.kt @@ -20,7 +20,6 @@ import org.wordpress.android.ui.mysite.cards.jetpackfeature.JetpackFeatureCardSh import kotlin.test.Test import kotlin.test.assertNotNull - @ExperimentalCoroutinesApi @RunWith(MockitoJUnitRunner::class) class JetpackFeatureCardViewModelSliceTest: BaseUnitTest() { From 4f236d630450647523eea163f80ee0977b660464 Mon Sep 17 00:00:00 2001 From: Pantelis Stampoulis Date: Thu, 14 Mar 2024 11:58:02 +0200 Subject: [PATCH 230/250] Fixes: Site icon refresh issue --- .../java/org/wordpress/android/ui/mysite/MySiteAdapter.kt | 6 +++--- .../java/org/wordpress/android/ui/mysite/MySiteViewModel.kt | 2 +- .../wordpress/android/ui/mysite/SiteIconUploadHandler.kt | 2 -- ...derCardViewholder.kt => SiteInfoHeaderCardViewHolder.kt} | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) rename WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/{SiteInfoHeaderCardViewholder.kt => SiteInfoHeaderCardViewHolder.kt} (98%) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteAdapter.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteAdapter.kt index 98d44e0f55fc..718905d79376 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteAdapter.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteAdapter.kt @@ -53,7 +53,7 @@ import org.wordpress.android.ui.mysite.cards.nocards.NoCardsMessageViewHolder import org.wordpress.android.ui.mysite.cards.personalize.PersonalizeCardViewHolder import org.wordpress.android.ui.mysite.cards.quicklinksitem.QuickLinkRibbonViewHolder import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartCardViewHolder -import org.wordpress.android.ui.mysite.cards.siteinfo.SiteInfoHeaderCardViewholder +import org.wordpress.android.ui.mysite.cards.siteinfo.SiteInfoHeaderCardViewHolder import org.wordpress.android.ui.mysite.cards.sotw2023.WpSotw2023NudgeCardViewHolder import org.wordpress.android.ui.mysite.items.categoryheader.MySiteCategoryItemEmptyViewHolder import org.wordpress.android.ui.mysite.items.categoryheader.MySiteCategoryItemViewHolder @@ -80,7 +80,7 @@ class MySiteAdapter( @Suppress("ComplexMethod") override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MySiteCardAndItemViewHolder<*> { return when (viewType) { - MySiteCardAndItem.Type.SITE_INFO_CARD.ordinal -> SiteInfoHeaderCardViewholder(parent, imageManager) + MySiteCardAndItem.Type.SITE_INFO_CARD.ordinal -> SiteInfoHeaderCardViewHolder(parent, imageManager) MySiteCardAndItem.Type.QUICK_LINK_RIBBON.ordinal -> QuickLinkRibbonViewHolder(parent) MySiteCardAndItem.Type.DOMAIN_REGISTRATION_CARD.ordinal -> DomainRegistrationViewHolder(parent) MySiteCardAndItem.Type.QUICK_START_CARD.ordinal -> QuickStartCardViewHolder(parent, uiHelpers) @@ -136,7 +136,7 @@ class MySiteAdapter( @Suppress("ComplexMethod") override fun onBindViewHolder(holder: MySiteCardAndItemViewHolder<*>, position: Int) { when (holder) { - is SiteInfoHeaderCardViewholder -> holder.bind(getItem(position) as SiteInfoHeaderCard) + is SiteInfoHeaderCardViewHolder -> holder.bind(getItem(position) as SiteInfoHeaderCard) is QuickLinkRibbonViewHolder -> holder.bind(getItem(position) as QuickLinksItem) is DomainRegistrationViewHolder -> holder.bind(getItem(position) as DomainRegistrationCard) is QuickStartCardViewHolder -> holder.bind(getItem(position) as QuickStartCard) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index b93abb618add..7195ff2f7224 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -191,7 +191,7 @@ class MySiteViewModel @Inject constructor( isSiteSelected = false checkAndShowJetpackFullPluginInstallOnboarding() checkAndShowQuickStartNotice() - + selectedSiteRepository.updateSiteSettingsIfNecessary() selectedSiteRepository.getSelectedSite()?.let { buildDashboardOrSiteItems(it) } ?: run { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteIconUploadHandler.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteIconUploadHandler.kt index a24603ba15d6..dc049b346f46 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteIconUploadHandler.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteIconUploadHandler.kt @@ -74,8 +74,6 @@ class SiteIconUploadHandler if (event.mediaModelList.size > 0) { val media = event.mediaModelList[0] selectedSiteRepository.updateSiteIconMediaId(media.mediaId.toInt(), true) - selectedSiteRepository.showSiteIconProgressBar(false) - selectedSiteRepository.refresh() } else { AppLog.w( MAIN, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewholder.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewHolder.kt similarity index 98% rename from WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewholder.kt rename to WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewHolder.kt index 474a83a5be2c..47418ee9d774 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewholder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/siteinfo/SiteInfoHeaderCardViewHolder.kt @@ -9,7 +9,7 @@ import org.wordpress.android.util.extensions.viewBinding import org.wordpress.android.util.image.ImageManager import org.wordpress.android.util.image.ImageType.BLAVATAR -class SiteInfoHeaderCardViewholder( +class SiteInfoHeaderCardViewHolder( parent: ViewGroup, private val imageManager: ImageManager ) : MySiteCardAndItemViewHolder(parent.viewBinding(MySiteInfoHeaderCardBinding::inflate)) { From ff5c0c88badf48a59994057803849807f08fab39 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 14 Mar 2024 16:08:18 +0530 Subject: [PATCH 231/250] * Fixes: the position of migration success card --- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 4ecfc571b947..3faf0dc44bee 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -143,6 +143,7 @@ class DashboardCardsViewModelSlice @Inject constructor( domainRegistrationCard: MySiteCardAndItem.Card.DomainRegistrationCard?, ): List { val cards = mutableListOf() + migrationSuccessCard?.let { cards.add(it) } quicklinks?.let { cards.add(it) } quickStart?.let { cards.add(it) } domainRegistrationCard?.let { cards.add(it) } @@ -155,7 +156,6 @@ class DashboardCardsViewModelSlice @Inject constructor( is CardsState.ErrorState -> cards.add(cardsState.error) } } - migrationSuccessCard?.let { cards.add(it) } plansCard?.let { cards.add(it) } jpFullInstallFullPlugin?.let { cards.add(it) } // when clearing the values of all child VM Slices, From 20329d7bee65960091a959c4775e932574f44a86 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 11:32:12 +0530 Subject: [PATCH 232/250] * Fixes: the order of the dashboard cards Fixes: the order of plans card, posts card and pages card --- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 2 +- .../android/ui/mysite/cards/dashboard/CardViewModelSlice.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 3faf0dc44bee..91b6c4494683 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -146,6 +146,7 @@ class DashboardCardsViewModelSlice @Inject constructor( migrationSuccessCard?.let { cards.add(it) } quicklinks?.let { cards.add(it) } quickStart?.let { cards.add(it) } + plansCard?.let { cards.add(it) } domainRegistrationCard?.let { cards.add(it) } bloganuaryNudgeCard?.let { cards.add(it) } bloggingPromptCard?.let { cards.add(it) } @@ -156,7 +157,6 @@ class DashboardCardsViewModelSlice @Inject constructor( is CardsState.ErrorState -> cards.add(cardsState.error) } } - plansCard?.let { cards.add(it) } jpFullInstallFullPlugin?.let { cards.add(it) } // when clearing the values of all child VM Slices, // the no cards message will still be shown and hence we need to check if the personalize card diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt index f068121d9f56..e6f1e0e4c74a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt @@ -91,8 +91,8 @@ class CardViewModelSlice @Inject constructor( val cards = mutableListOf() topDynamicCards?.let { cards.addAll(topDynamicCards) } todaysStatsCard?.let { cards.add(todaysStatsCard) } - pagesCard?.let { cards.add(pagesCard) } postsCard?.let { cards.addAll(postsCard) } + pagesCard?.let { cards.add(pagesCard) } activityCard?.let { cards.add(activityCard) } bottomDynamicCards?.let { cards.addAll(bottomDynamicCards) } return CardsState.Success(cards) From 7f581508f657f6f3c003c9336ea6933819f2871a Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 14:36:17 +0530 Subject: [PATCH 233/250] * Fixes: Jetpack switch menu shown on jetpack app --- .../mysite/cards/jetpackfeature/JetpackFeatureCardHelper.kt | 5 +++-- .../jetpackSwitchmenu/JetpackSwitchMenuViewModelSlice.kt | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jetpackfeature/JetpackFeatureCardHelper.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jetpackfeature/JetpackFeatureCardHelper.kt index 39fdb6acac30..facdd574a1c9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jetpackfeature/JetpackFeatureCardHelper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jetpackfeature/JetpackFeatureCardHelper.kt @@ -3,9 +3,9 @@ package org.wordpress.android.ui.mysite.cards.jetpackfeature import org.wordpress.android.R import org.wordpress.android.analytics.AnalyticsTracker.Stat import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase -import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase.PhaseThree import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase.PhaseNewUsers import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase.PhaseSelfHostedUsers +import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhase.PhaseThree import org.wordpress.android.ui.jetpackoverlay.JetpackFeatureRemovalPhaseHelper import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.utils.UiString @@ -110,7 +110,8 @@ class JetpackFeatureCardHelper @Inject constructor( } fun shouldShowSwitchToJetpackMenuCard(): Boolean { - return shouldShowSwitchToJetpackMenuCardInCurrentPhase() && + return !buildConfigWrapper.isJetpackApp && + shouldShowSwitchToJetpackMenuCardInCurrentPhase() && exceedsShowFrequencyAndResetSwitchToJetpackMenuLastShownTimestampIfNeeded() && !isSwitchToJetpackMenuCardHiddenByUser() } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSlice.kt index 375a2babe948..3cf34e9013d0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/jetpackSwitchmenu/JetpackSwitchMenuViewModelSlice.kt @@ -23,7 +23,10 @@ class JetpackSwitchMenuViewModelSlice @Inject constructor( val uiModel = _uiModel.distinctUntilChanged() suspend fun buildJetpackSwitchMenu() { - if (!jetpackFeatureCardHelper.shouldShowSwitchToJetpackMenuCard()) _uiModel.postValue(null) + if (!jetpackFeatureCardHelper.shouldShowSwitchToJetpackMenuCard()) { + _uiModel.postValue(null) + return + } _uiModel.postValue( MySiteCardAndItem.Card.JetpackSwitchMenu( onClick = ListItemInteraction.create(this::onJetpackFeatureCardClick), From fd87dca7e169af5b7e222dcebb88985c5a5fb19a Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 14:37:46 +0530 Subject: [PATCH 234/250] * Fixes: Refreshing indicator shown in site items Fixes: the scenario in which refreshing indicator was shown in the site items without dismissal --- .../java/org/wordpress/android/ui/mysite/MySiteViewModel.kt | 1 + .../android/ui/mysite/items/DashboardItemsViewModelSlice.kt | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt index 7195ff2f7224..6dcea39fc7a2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteViewModel.kt @@ -126,6 +126,7 @@ class MySiteViewModel @Inject constructor( val isRefreshingOrLoading = merge( dashboardCardsViewModelSlice.isRefreshing, + dashboardItemsViewModelSlice.isRefreshing, accountDataViewModelSlice.isRefreshing ) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt index b28f88dc335b..6e3f7b9cb5af 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/DashboardItemsViewModelSlice.kt @@ -68,6 +68,9 @@ class DashboardItemsViewModelSlice @Inject constructor( siteItemsViewModelSlice.onSnackbarMessage, ) + private val _isRefreshing = MutableLiveData() + val isRefreshing = _isRefreshing.distinctUntilChanged() + private fun mergeUiModels( jetpackFeatureCard: MySiteCardAndItem.Card.JetpackFeatureCard?, jetpackSwitchMenu: MySiteCardAndItem.Card.JetpackSwitchMenu?, @@ -92,11 +95,13 @@ class DashboardItemsViewModelSlice @Inject constructor( fun buildItems(site: SiteModel) { job?.cancel() job = scope.launch(bgDispatcher) { + _isRefreshing.postValue(true) jetpackFeatureCardViewModelSlice.buildJetpackFeatureCard() jetpackSwitchMenuViewModelSlice.buildJetpackSwitchMenu() jetpackBadgeViewModelSlice.buildJetpackBadge() siteItemsViewModelSlice.buildSiteItems(site) sotw2023NudgeCardViewModelSlice.buildCard() + _isRefreshing.postValue(false) } } From 3cbea9fdd7c4a87e07953d5daf2d3c5360773d93 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 14:39:32 +0530 Subject: [PATCH 235/250] Reverts: Local env changes --- .idea/checkstyle-idea.xml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml index 346b0de8ea1b..7f921dc3495d 100644 --- a/.idea/checkstyle-idea.xml +++ b/.idea/checkstyle-idea.xml @@ -1,18 +1,18 @@ - - 8.2 - AllSourcesWithTests - - \ No newline at end of file + From 16fa6dd858e28b56297f3d3ce728e87205e22442 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 15:41:37 +0530 Subject: [PATCH 236/250] * Fixes: Blogging prompt card not shown --- .../cards/DashboardCardsViewModelSlice.kt | 1 + .../BloggingPromptCardViewModelSlice.kt | 69 ++++++++----------- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 91b6c4494683..087bff094389 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -216,6 +216,7 @@ class DashboardCardsViewModelSlice @Inject constructor( fun onCleared() { quickLinksItemViewModelSlice.onCleared() + bloggingPromptCardViewModelSlice.onCleared() job?.cancel() trackingJob?.cancel() scope.cancel() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index ca84fef93065..ff5ae3268336 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.distinctUntilChanged import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import org.wordpress.android.R @@ -66,56 +67,42 @@ class BloggingPromptCardViewModelSlice @Inject constructor( fun buildCard( siteModel: SiteModel ) { - if (bloggingPromptsFeature.isEnabled()) { - scope.launch(bgDispatcher) { - if (bloggingPromptsSettingsHelper.shouldShowPromptsFeature()) { - promptsStore.getPrompts(siteModel) - .map { it.model?.filter { prompt -> isSameDay(prompt.date, Date()) } } - .collect { result -> - postState(result?.firstOrNull()) - } - refreshData(siteModel) - } else { - postEmptyState() - } + scope.launch(bgDispatcher) { + if (bloggingPromptsFeature.isEnabled() && + bloggingPromptsSettingsHelper.shouldShowPromptsFeature() + ) { + refreshData(siteModel) + promptsStore.getPrompts(siteModel) + .map { it.model?.filter { prompt -> isSameDay(prompt.date, Date()) } } + .collect { result -> + postState(result?.firstOrNull()) + } + } else { + postEmptyState() } - } else { - postLastState() } } - fun refreshData( + suspend fun refreshData( siteModel: SiteModel, isSinglePromptRefresh: Boolean = false ) { - if (bloggingPromptsFeature.isEnabled()) { - scope.launch(bgDispatcher) { - if (bloggingPromptsSettingsHelper.shouldShowPromptsFeature()) { - fetchPromptsAndPostErrorIfAvailable(siteModel, isSinglePromptRefresh) - } else { - postEmptyState() - } - } - } else { - postEmptyState() - } + fetchPromptsAndPostErrorIfAvailable(siteModel, isSinglePromptRefresh) } - private fun fetchPromptsAndPostErrorIfAvailable( + private suspend fun fetchPromptsAndPostErrorIfAvailable( selectedSite: SiteModel, isSinglePromptRefresh: Boolean = false ) { - scope.launch(bgDispatcher) { - val numOfPromptsToFetch = if (isSinglePromptRefresh) 1 else NUM_PROMPTS_TO_REQUEST - val result = promptsStore.fetchPrompts(selectedSite, numOfPromptsToFetch, Date()) - when { - result.isError -> postLastState() - else -> { - result.model - ?.firstOrNull { prompt -> isSameDay(prompt.date, Date()) } - ?.let { prompt -> postState(prompt) } - ?: postLastState() - } + val numOfPromptsToFetch = if (isSinglePromptRefresh) 1 else NUM_PROMPTS_TO_REQUEST + val result = promptsStore.fetchPrompts(selectedSite, numOfPromptsToFetch, Date()) + when { + result.isError -> postLastState() + else -> { + result.model + ?.firstOrNull { prompt -> isSameDay(prompt.date, Date()) } + ?.let { prompt -> postState(prompt) } + ?: postLastState() } } } @@ -211,7 +198,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( buildCard(bloggingPrompt)?.let { card -> _uiModel.postValue(card) } - }?: _uiModel.postValue(null) + } ?: _uiModel.postValue(null) } private fun isSameDay(date1: Date, date2: Date): Boolean { @@ -247,4 +234,8 @@ class BloggingPromptCardViewModelSlice @Inject constructor( bloggingPromptsCardTrackHelper.onSiteChanged() _uiModel.postValue(null) } + + fun onCleared() { + scope.cancel() + } } From 65926a3baca50d1bafed67c6ff7bc1ed33dec566 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 15:45:15 +0530 Subject: [PATCH 237/250] =?UTF-8?q?=E2=86=91=20Updates:=20the=20blogging?= =?UTF-8?q?=20prompt=20card=20feature=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bloggingprompts/BloggingPromptCardViewModelSlice.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index ff5ae3268336..f454489785ba 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -68,9 +68,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( siteModel: SiteModel ) { scope.launch(bgDispatcher) { - if (bloggingPromptsFeature.isEnabled() && - bloggingPromptsSettingsHelper.shouldShowPromptsFeature() - ) { + if (bloggingPromptsSettingsHelper.shouldShowPromptsFeature()) { refreshData(siteModel) promptsStore.getPrompts(siteModel) .map { it.model?.filter { prompt -> isSameDay(prompt.date, Date()) } } From 26355630472a30eb3c16c99f0d8b7646e3463395 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 16:07:23 +0530 Subject: [PATCH 238/250] * Fixes: DomainRegistrationCard not being shown --- .../ui/mysite/cards/DashboardCardsViewModelSlice.kt | 1 + .../DomainRegistrationCardViewModelSlice.kt | 7 +++---- .../DomainRegistrationCardViewModelSliceTest.kt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 087bff094389..06cffc4c2605 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -196,6 +196,7 @@ class DashboardCardsViewModelSlice @Inject constructor( plansCardViewModelSlice.buildCard(site) cardViewModelSlice.buildCard(site) quickStartCardViewModelSlice.build(site) + domainRegistrationCardViewModelSlice.buildCard(site) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt index bbf3cb08f363..de5891974473 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSlice.kt @@ -66,14 +66,13 @@ class DomainRegistrationCardViewModelSlice @Inject constructor( } fun buildCard( - siteLocalId: Int, - selectedSite: SiteModel? + selectedSite: SiteModel ) { _isRefreshing.postValue(true) - if (selectedSite == null || selectedSite.id != siteLocalId || !shouldFetchPlans(selectedSite)) { + if (!shouldFetchPlans(selectedSite)) { postState(false) } else { - fetchPlansAndRefreshData(siteLocalId, selectedSite) + fetchPlansAndRefreshData(selectedSite.id, selectedSite) } } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt index cf9d33939af8..a41dfc7953cd 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/domainregistration/DomainRegistrationCardViewModelSliceTest.kt @@ -84,7 +84,7 @@ class DomainRegistrationCardViewModelSliceTest : BaseUnitTest() { @Test fun `when getData is invoked, then refresh is true`() = test { - viewModelSlice.buildCard(siteLocalId, site) + viewModelSlice.buildCard(site) assertThat(isRefreshing.last()).isTrue } @@ -165,7 +165,7 @@ class DomainRegistrationCardViewModelSliceTest : BaseUnitTest() { buildOnPlansFetchedEvent(site, currentPlan, error)?.let { event -> whenever(dispatcher.dispatch(any())).then { viewModelSlice.onPlansFetched(event) } } - viewModelSlice.buildCard(siteLocalId,site) + viewModelSlice.buildCard(site) } private fun buildOnPlansFetchedEvent( From 8f5322676f6c8c52c3562bcc46fb85e3f2430bfa Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 16:32:47 +0530 Subject: [PATCH 239/250] * Fixes: Register domain card not shown --- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 06cffc4c2605..396f2a53dbb3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -181,6 +181,7 @@ class DashboardCardsViewModelSlice @Inject constructor( quickLinksItemViewModelSlice.initialization(scope) cardViewModelSlice.initialize(scope) quickStartCardViewModelSlice.initialize(scope) + domainRegistrationCardViewModelSlice.initialize(scope) } fun buildCards(site: SiteModel) { From 79ffbb97a91b6e79cc58fc6bdb90897cd5534c53 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 16:37:03 +0530 Subject: [PATCH 240/250] Moves: the order of the blaze card to the top of plans card --- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 396f2a53dbb3..8b83cc3cd8da 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -146,11 +146,11 @@ class DashboardCardsViewModelSlice @Inject constructor( migrationSuccessCard?.let { cards.add(it) } quicklinks?.let { cards.add(it) } quickStart?.let { cards.add(it) } + blazeCard?.let { cards.add(it) } plansCard?.let { cards.add(it) } domainRegistrationCard?.let { cards.add(it) } bloganuaryNudgeCard?.let { cards.add(it) } bloggingPromptCard?.let { cards.add(it) } - blazeCard?.let { cards.add(it) } cardsState?.let { when (cardsState) { is CardsState.Success -> cards.addAll(cardsState.cards) From 14fda30b7466b18f185b164cb260d049b6d2239c Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 17:13:22 +0530 Subject: [PATCH 241/250] - Removes: unused parameter --- .../bloggingprompts/BloggingPromptCardViewModelSlice.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index f454489785ba..ac9219340ad5 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -25,7 +25,6 @@ import org.wordpress.android.ui.mysite.SiteNavigationAction import org.wordpress.android.ui.pages.SnackbarMessageHolder import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.utils.UiString -import org.wordpress.android.util.config.BloggingPromptsFeature import org.wordpress.android.viewmodel.Event import java.time.LocalDate import java.time.ZoneId @@ -44,8 +43,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( private val bloggingPromptsCardTrackHelper: BloggingPromptsCardTrackHelper, private val bloggingPromptsPostTagProvider: BloggingPromptsPostTagProvider, private val bloggingPromptCardBuilder: BloggingPromptCardBuilder, - private val promptsStore: BloggingPromptsStore, - private val bloggingPromptsFeature: BloggingPromptsFeature + private val promptsStore: BloggingPromptsStore ) { private val _onSnackbarMessage = MutableLiveData>() val onSnackbarMessage = _onSnackbarMessage as LiveData> From 1a797a06dee6d649e59fa26b2f17119fe6527406 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 18 Mar 2024 18:44:09 +0530 Subject: [PATCH 242/250] * Fixes: BloggingPromptCardViewModelSliceTest --- .../BloggingPromptCardViewModelSliceTest.kt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSliceTest.kt index 9a082e0c7275..4103820b3e7a 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSliceTest.kt @@ -29,7 +29,6 @@ import org.wordpress.android.ui.mysite.SiteNavigationAction import org.wordpress.android.ui.pages.SnackbarMessageHolder import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.utils.UiString -import org.wordpress.android.util.config.BloggingPromptsFeature @Suppress("LargeClass") @ExperimentalCoroutinesApi @@ -59,9 +58,6 @@ class BloggingPromptCardViewModelSliceTest : BaseUnitTest() { @Mock lateinit var promptsStore: BloggingPromptsStore - @Mock - lateinit var bloggingPromptsFeature: BloggingPromptsFeature - private lateinit var viewModelSlice: BloggingPromptCardViewModelSlice private lateinit var navigationActions: MutableList @@ -87,8 +83,7 @@ class BloggingPromptCardViewModelSliceTest : BaseUnitTest() { bloggingPromptsCardTrackHelper, bloggingPromptsPostTagProvider, bloggingPromptCardBuilder, - promptsStore, - bloggingPromptsFeature + promptsStore ) whenever(selectedSiteRepository.getSelectedSite()).thenReturn(site) From f4235e3df2af7cb1a9a879e2278a9ce47970fda8 Mon Sep 17 00:00:00 2001 From: Pantelis Stampoulis Date: Tue, 19 Mar 2024 13:16:27 +0200 Subject: [PATCH 243/250] Fixes: site menu icon colour --- WordPress/src/main/res/drawable/ic_globe_white_24dp.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/res/drawable/ic_globe_white_24dp.xml b/WordPress/src/main/res/drawable/ic_globe_white_24dp.xml index c4ebbfffdfd2..40b7be665e77 100644 --- a/WordPress/src/main/res/drawable/ic_globe_white_24dp.xml +++ b/WordPress/src/main/res/drawable/ic_globe_white_24dp.xml @@ -5,5 +5,5 @@ android:viewportHeight="24"> + android:fillColor="@color/white"/> From dd0f35f7e8812a5c47d39e94cc8b62ad34e803a7 Mon Sep 17 00:00:00 2001 From: Antonis Lilis Date: Wed, 20 Mar 2024 19:31:43 +0200 Subject: [PATCH 244/250] Separates the dynamic cards so that they could be displayed at the top and bottom of the dashboard --- .../mysite/cards/DashboardCardsViewModelSlice.kt | 10 ++++++++++ .../mysite/cards/dashboard/CardViewModelSlice.kt | 14 ++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 8b83cc3cd8da..f9990200f203 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -146,6 +146,11 @@ class DashboardCardsViewModelSlice @Inject constructor( migrationSuccessCard?.let { cards.add(it) } quicklinks?.let { cards.add(it) } quickStart?.let { cards.add(it) } + cardsState?.let { + if (cardsState is CardsState.Success) { + cards.addAll(cardsState.topCards) + } + } blazeCard?.let { cards.add(it) } plansCard?.let { cards.add(it) } domainRegistrationCard?.let { cards.add(it) } @@ -158,6 +163,11 @@ class DashboardCardsViewModelSlice @Inject constructor( } } jpFullInstallFullPlugin?.let { cards.add(it) } + cardsState?.let { + if (cardsState is CardsState.Success) { + cards.addAll(cardsState.bottomCards) + } + } // when clearing the values of all child VM Slices, // the no cards message will still be shown and hence we need to check if the personalize card // is shown or not, if the personalize card is not shown, then it means that diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt index e6f1e0e4c74a..da77b60fb3dc 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt @@ -89,13 +89,11 @@ class CardViewModelSlice @Inject constructor( bottomDynamicCards: List? ): CardsState { val cards = mutableListOf() - topDynamicCards?.let { cards.addAll(topDynamicCards) } todaysStatsCard?.let { cards.add(todaysStatsCard) } postsCard?.let { cards.addAll(postsCard) } pagesCard?.let { cards.add(pagesCard) } activityCard?.let { cards.add(activityCard) } - bottomDynamicCards?.let { cards.addAll(bottomDynamicCards) } - return CardsState.Success(cards) + return CardsState.Success(topDynamicCards ?: emptyList(), cards, bottomDynamicCards ?: emptyList()) } private val _onNavigation = MutableLiveData>() @@ -224,7 +222,7 @@ class CardViewModelSlice @Inject constructor( fun postState(cards: List?) { _isRefreshing.postValue(false) if (cards.isNullOrEmpty()) { - uiModel.postValue(CardsState.Success(emptyList())) + uiModel.postValue(CardsState.Success(emptyList(), emptyList(), emptyList())) return } scope.launch(bgDispatcher) { @@ -256,7 +254,7 @@ class CardViewModelSlice @Inject constructor( } fun clearValue() { - uiModel.postValue(CardsState.Success(emptyList())) + uiModel.postValue(CardsState.Success(emptyList(), emptyList(), emptyList())) collectJob?.cancel() fetchJob?.cancel() dynamicCardsViewModelSlice.clearValue() @@ -280,6 +278,10 @@ class CardViewModelSlice @Inject constructor( } sealed class CardsState { - data class Success(val cards: List) : CardsState() + data class Success( + val topCards: List, + val cards: List, + val bottomCards: List + ) : CardsState() data class ErrorState(val error: MySiteCardAndItem) : CardsState() } From 81090f6f2e749aeb7874ba83feb15013d153ebd7 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 21 Mar 2024 09:50:32 +0530 Subject: [PATCH 245/250] =?UTF-8?q?=E2=86=91=20Updates:=20the=20check=20fo?= =?UTF-8?q?r=20whether=20the=20ui=20model=20is=20empty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/ui/mysite/cards/dashboard/CardViewModelSlice.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt index da77b60fb3dc..37b39f4e2479 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/CardViewModelSlice.kt @@ -212,7 +212,10 @@ class CardViewModelSlice @Inject constructor( } private fun isUiModelEmpty(): Boolean { - return (uiModel.value is CardsState.Success) && (uiModel.value as CardsState.Success).cards.isEmpty() + return (uiModel.value is CardsState.Success) + && (uiModel.value as CardsState.Success).topCards.isEmpty() + && (uiModel.value as CardsState.Success).cards.isEmpty() + && (uiModel.value as CardsState.Success).bottomCards.isEmpty() } private fun onDashboardErrorRetry() { From daa26aa13760e421b6833fd45437187aa8300f7c Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Thu, 21 Mar 2024 10:53:44 +0530 Subject: [PATCH 246/250] * Fixes: the order of the cards in viewmodel --- .../cards/DashboardCardsViewModelSlice.kt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index f9990200f203..fc53b7deb3e7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -144,6 +144,8 @@ class DashboardCardsViewModelSlice @Inject constructor( ): List { val cards = mutableListOf() migrationSuccessCard?.let { cards.add(it) } + jpFullInstallFullPlugin?.let { cards.add(it) } + domainRegistrationCard?.let { cards.add(it) } quicklinks?.let { cards.add(it) } quickStart?.let { cards.add(it) } cardsState?.let { @@ -151,23 +153,19 @@ class DashboardCardsViewModelSlice @Inject constructor( cards.addAll(cardsState.topCards) } } - blazeCard?.let { cards.add(it) } - plansCard?.let { cards.add(it) } - domainRegistrationCard?.let { cards.add(it) } bloganuaryNudgeCard?.let { cards.add(it) } bloggingPromptCard?.let { cards.add(it) } + blazeCard?.let { cards.add(it) } + plansCard?.let { cards.add(it) } cardsState?.let { when (cardsState) { - is CardsState.Success -> cards.addAll(cardsState.cards) + is CardsState.Success -> { + cards.addAll(cardsState.cards) + cards.addAll(cardsState.bottomCards) + } is CardsState.ErrorState -> cards.add(cardsState.error) } } - jpFullInstallFullPlugin?.let { cards.add(it) } - cardsState?.let { - if (cardsState is CardsState.Success) { - cards.addAll(cardsState.bottomCards) - } - } // when clearing the values of all child VM Slices, // the no cards message will still be shown and hence we need to check if the personalize card // is shown or not, if the personalize card is not shown, then it means that From 3f43efa84fe541d07e4e5726c850d5216243305a Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Fri, 22 Mar 2024 15:00:29 +0530 Subject: [PATCH 247/250] * Fixes: the visibility of refresh function --- .../bloggingprompts/BloggingPromptCardViewModelSlice.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index ac9219340ad5..a03b069dd0e3 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -79,7 +79,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( } } - suspend fun refreshData( + private suspend fun refreshData( siteModel: SiteModel, isSinglePromptRefresh: Boolean = false ) { From 23f9e5a0d6e73e2902f5cd363b5c4e32d2bd746e Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Fri, 22 Mar 2024 15:00:57 +0530 Subject: [PATCH 248/250] * Fixes: the visibility of build function --- .../bloggingprompts/BloggingPromptCardViewModelSlice.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index a03b069dd0e3..9512f75b7ff2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -107,7 +107,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( this.scope = scope } - fun buildCard(bloggingPromptUpdate: BloggingPromptModel): BloggingPromptCardWithData? { + private fun buildCard(bloggingPromptUpdate: BloggingPromptModel): BloggingPromptCardWithData? { return bloggingPromptCardBuilder.build(getBuilderParams(bloggingPromptUpdate)) } From b73b46dc4f5c5623a1d709371200f56d7b9b3fc1 Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Fri, 22 Mar 2024 15:02:04 +0530 Subject: [PATCH 249/250] =?UTF-8?q?=E2=86=91=20Updates:=20the=20naming=20o?= =?UTF-8?q?f=20the=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/ui/mysite/cards/DashboardCardsViewModelSlice.kt | 4 ++-- .../bloggingprompts/BloggingPromptCardViewModelSlice.kt | 6 +++--- .../android/ui/mysite/DashboardCardsViewModelSliceTest.kt | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt index 8b83cc3cd8da..f86b8de9af89 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/DashboardCardsViewModelSlice.kt @@ -190,7 +190,7 @@ class DashboardCardsViewModelSlice @Inject constructor( jpMigrationSuccessCardViewModelSlice.buildCard() jetpackInstallFullPluginCardViewModelSlice.buildCard(site) blazeCardViewModelSlice.buildCard(site) - bloggingPromptCardViewModelSlice.buildCard(site) + bloggingPromptCardViewModelSlice.fetchBloggingPrompt(site) bloganuaryNudgeCardViewModelSlice.buildCard() personalizeCardViewModelSlice.buildCard() quickLinksItemViewModelSlice.buildCard(site) @@ -226,7 +226,7 @@ class DashboardCardsViewModelSlice @Inject constructor( fun refreshBloggingPrompt() { selectedSiteRepository.getSelectedSite()?.let { - bloggingPromptCardViewModelSlice.buildCard(it) + bloggingPromptCardViewModelSlice.fetchBloggingPrompt(it) } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt index 9512f75b7ff2..da6e61de3fa1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/dashboard/bloggingprompts/BloggingPromptCardViewModelSlice.kt @@ -62,7 +62,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( private lateinit var scope: CoroutineScope - fun buildCard( + fun fetchBloggingPrompt( siteModel: SiteModel ) { scope.launch(bgDispatcher) { @@ -107,7 +107,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( this.scope = scope } - private fun buildCard(bloggingPromptUpdate: BloggingPromptModel): BloggingPromptCardWithData? { + private fun fetchBloggingPrompt(bloggingPromptUpdate: BloggingPromptModel): BloggingPromptCardWithData? { return bloggingPromptCardBuilder.build(getBuilderParams(bloggingPromptUpdate)) } @@ -191,7 +191,7 @@ class BloggingPromptCardViewModelSlice @Inject constructor( private fun postState(bloggingPrompt: BloggingPromptModel?) { _isRefreshing.postValue(false) bloggingPrompt?.let { - buildCard(bloggingPrompt)?.let { card -> + fetchBloggingPrompt(bloggingPrompt)?.let { card -> _uiModel.postValue(card) } } ?: _uiModel.postValue(null) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt index aa20a6ccf937..5ee11706eb38 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/DashboardCardsViewModelSliceTest.kt @@ -119,7 +119,7 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { verify(jpMigrationSuccessCardViewModelSlice, atMost(1)).buildCard() verify(jetpackInstallFullPluginCardViewModelSlice, atMost(1)).buildCard(mockSite) verify(blazeCardViewModelSlice, atMost(1)).buildCard(mockSite) - verify(bloggingPromptCardViewModelSlice, atMost(1)).buildCard(mockSite) + verify(bloggingPromptCardViewModelSlice, atMost(1)).fetchBloggingPrompt(mockSite) verify(bloganuaryNudgeCardViewModelSlice, atMost(1)).buildCard() verify(personalizeCardViewModelSlice, atMost(1)).buildCard() verify(quickLinksItemViewModelSlice, atMost(1)).buildCard(mockSite) @@ -168,7 +168,7 @@ class DashboardCardsViewModelSliceTest: BaseUnitTest() { dashboardCardsViewModelSlice.refreshBloggingPrompt() - verify(bloggingPromptCardViewModelSlice).buildCard(mockSite) + verify(bloggingPromptCardViewModelSlice).fetchBloggingPrompt(mockSite) } @Test From cbee896918af8ad0ed53ff6bb6c8324186ab2d1d Mon Sep 17 00:00:00 2001 From: Ajesh R Pai Date: Mon, 25 Mar 2024 13:25:50 +0530 Subject: [PATCH 250/250] - Removes: Redundant JetpackInstallFullPluginCardBuilderParams --- .../mysite/MySiteCardAndItemBuilderParams.kt | 6 ----- ...packInstallFullPluginCardViewModelSlice.kt | 25 ++++++------------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteCardAndItemBuilderParams.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteCardAndItemBuilderParams.kt index 812778775930..d84bec2a64d9 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteCardAndItemBuilderParams.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/MySiteCardAndItemBuilderParams.kt @@ -185,12 +185,6 @@ sealed class MySiteCardAndItemBuilderParams { val onActionClick: () -> Unit ) - data class JetpackInstallFullPluginCardBuilderParams( - val site: SiteModel, - val onLearnMoreClick: () -> Unit, - val onHideMenuItemClick: () -> Unit, - ) - data class PersonalizeCardBuilderParams( val onClick: () -> Unit ) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt index cc8e01c4f3a3..46ee1eb053cd 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/jpfullplugininstall/JetpackInstallFullPluginCardViewModelSlice.kt @@ -5,7 +5,6 @@ import androidx.lifecycle.distinctUntilChanged import org.wordpress.android.analytics.AnalyticsTracker import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.JetpackInstallFullPluginCard -import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.JetpackInstallFullPluginCardBuilderParams import org.wordpress.android.ui.mysite.SelectedSiteRepository import org.wordpress.android.ui.prefs.AppPrefsWrapper import org.wordpress.android.ui.utils.ListItemInteraction @@ -41,26 +40,16 @@ class JetpackInstallFullPluginCardViewModelSlice @Inject constructor( _onOpenJetpackInstallFullPluginOnboarding.postValue(Event(Unit)) } - fun buildCard(site: SiteModel) { - build( - JetpackInstallFullPluginCardBuilderParams( - site = site, - onLearnMoreClick = this::onJetpackInstallFullPluginLearnMoreClick, - onHideMenuItemClick = this::onJetpackInstallFullPluginHideMenuItemClick - ) - ) - } - - fun build( - params: JetpackInstallFullPluginCardBuilderParams + fun buildCard( + site: SiteModel ) { - if (shouldShowCard(params.site)) { + if (shouldShowCard(site)) { _uiModel.postValue( JetpackInstallFullPluginCard( - siteName = params.site.name, - pluginNames = params.site.activeIndividualJetpackPluginNames().orEmpty(), - onLearnMoreClick = ListItemInteraction.create(params.onLearnMoreClick), - onHideMenuItemClick = ListItemInteraction.create(params.onHideMenuItemClick), + siteName = site.name, + pluginNames = site.activeIndividualJetpackPluginNames().orEmpty(), + onLearnMoreClick = ListItemInteraction.create(this::onJetpackInstallFullPluginLearnMoreClick), + onHideMenuItemClick = ListItemInteraction.create(this::onJetpackInstallFullPluginHideMenuItemClick), ) ) } else _uiModel.postValue(null)