Dashboard Personalization: Post cards more menu tracking

Closes #18945 & #18946

This PR adds track events for the more menu actions of the Scheduled and Draft post cards. This PR also removes post card footer action tracking events.

**Merge Instructions**
- Ensure #19075, #19089, and #19090 have been merged
- Ensure the parent branch is set to `feature/dashboard-personalization`
- Remove the Not Ready for Merge label
- Merge as normal
-
## To Test
- Login to the app
- Select a site in which that has both drafts and scheduled posts
- Enable log collection

**Draft Post Tracking**
- Go to Draft Posts Card > Tap on more menu
- ✅ Verify the log contains 🔵 Tracked: my_site_dashboard_contextual_menu_accessed, Properties: {"card":"draft_posts"}
- Tap on the " View all drafts" menu item
- ✅  Verify the log contains  🔵 Tracked: my_site_dashboard_card_menu_item_tapped, Properties: {"card":"draft_posts","item":"view_all_drafts"}
- Navigate back to dashboard
- Go to Draft Posts Card > Tap on more menu
- Tap on the Hide this item
- ✅  Verify the log contains 🔵 Tracked: my_site_dashboard_card_menu_item_tapped, Properties: {"card":"draft_posts","item":"hide_this"}

**Scheduled Posts Tracking**
- Go to Scheduled Posts Card > Tap on more menu
- ✅ Verify the log contains 🔵 Tracked: my_site_dashboard_contextual_menu_accessed, Properties: {"card":"scheduled_posts"}
- Tap on the " View all drafts" menu item
- ✅  Verify the log contains  🔵 Tracked: my_site_dashboard_card_menu_item_tapped, Properties: {"card":"scheduled_posts","item":"view_all_scheduled_posts"}
- Navigate back to dashboard
- Go to Draft Card > Tap on more menu
- Tap on the Hide this item
- ✅  Verify the log contains 🔵 Tracked: my_site_dashboard_card_menu_item_tapped, Properties: {"card":"scheduled_posts","item":"hide_this"}

## Regression Notes
1. Potential unintended areas of impact
Events are not tracked

2. What I did to test those areas of impact (or what existing automated tests I relied on)
Manual and unit tests

3. What automated tests I added (or what prevented me from doing so)

PR submission checklist:

- [x] I have completed the Regression Notes.
- [x] I have considered adding accessibility improvements for my changes.
- [x] I have considered if this change warrants user-facing release notes and have added them to `RELEASE-NOTES.txt` if necessary.

UI Changes testing checklist: N/A

Dashboard Personalization: Add more menu to Draft Posts card
Draft Posts card

```[tasklist]
### Tasks
- [x] Add more menu with options **View all drafts** and **Hide this**
- [x] Implement action for Hide This -> Turn the draft posts preference to hide
- [x] Implement action for View All Drafts -> navigate to drafts tab of posts list view
- [x] Remove Go-to footer
- [x] Add track events (see below)
- [x] Remove tracking events for footer CTA (if needed)
- [x] Create viewModelSlice (overlaps with scheduled posts card)
```

**Tracking Events**
<div>

Action | Event | Property
-- | -- | --
Tap More | my_site_dashboard_contextual_menu_accessed | card: draft_posts
Tap More > View all drafts | my_site_dashboard_card_menu_item_tapped | card: draft_posts item:view_all_drafts
Tap > Hide This | my_site_dashboard_card_menu_item_tapped | card: draft_posts item:hide_this

</div>

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 4516b1ae3f27..6fa114b0d9c0 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
@@ -72,14 +72,6 @@ class CardsTracker @Inject constructor(
         trackCardItemClicked(Type.QUICK_START.label, quickStartTaskType.toSubtypeValue().label)
     }

-    fun trackPostCardFooterLinkClicked(postCardType: PostCardType) {
-        trackCardFooterLinkClicked(Type.POST.label, postCardType.toSubtypeValue().label)
-    }
-
-    fun trackPostItemClicked(postCardType: PostCardType) {
-        trackCardItemClicked(Type.POST.label, postCardType.toSubtypeValue().label)
-    }
-
     fun trackActivityCardItemClicked() {
         trackCardItemClicked(Type.ACTIVITY.label, ActivityLogSubtype.ACTIVITY_LOG.label)
     }
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 f9aa84e99e96..7f537705dd9f 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,12 +1,12 @@
 package org.wordpress.android.ui.mysite.cards.dashboard.posts

-import android.util.Log
 import androidx.lifecycle.MutableLiveData
 import org.wordpress.android.fluxc.model.dashboard.CardModel.PostsCardModel
 import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.PostCardBuilderParams
 import org.wordpress.android.ui.mysite.SelectedSiteRepository
 import org.wordpress.android.ui.mysite.SiteNavigationAction
 import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker
+import org.wordpress.android.ui.mysite.cards.dashboard.toSubtypeValue
 import org.wordpress.android.ui.prefs.AppPrefsWrapper
 import org.wordpress.android.viewmodel.Event
 import javax.inject.Inject
@@ -35,12 +35,14 @@ class PostsCardViewModelSlice @Inject constructor(
     }

     private fun onMoreMenuClick(postCardType: PostCardType) {
-        // todo: annmarie implement cards tracker
-        Log.i(javaClass.simpleName, "***=> onMoreMenuClick $postCardType")
+        cardsTracker.trackCardMoreMenuClicked(postCardType.toPostMenuCardValue().label)
     }

     private fun onHideThisMenuItemClick(postCardType: PostCardType) {
-        // todo: annmarie implement cards tracker
+        cardsTracker.trackCardMoreMenuItemClicked(
+            postCardType.toPostMenuCardValue().label,
+            PostMenuItemType.HIDE_THIS.label
+        )
         appPrefsWrapper.setShouldHidePostDashboardCard(
             selectedSiteRepository.getSelectedSite()!!.siteId,
             postCardType.name,
@@ -50,13 +52,19 @@ class PostsCardViewModelSlice @Inject constructor(
     }

     private fun onViewPostsMenuItemClick(postCardType: PostCardType) {
+        cardsTracker.trackCardMoreMenuItemClicked(
+            card = postCardType.toPostMenuCardValue().label,
+            item = when (postCardType) {
+                PostCardType.DRAFT -> PostMenuItemType.VIEW_ALL_DRAFTS.label
+                PostCardType.SCHEDULED -> PostMenuItemType.VIEW_ALL_SCHEDULED_POSTS.label
+            }
+        )
         onPostCardViewAllClick(postCardType)
-        // todo: annmarie implement cards tracker
     }

     private fun onPostItemClick(params: PostCardBuilderParams.PostItemClickParams) {
         selectedSiteRepository.getSelectedSite()?.let { site ->
-            cardsTracker.trackPostItemClicked(params.postCardType)
+            trackPostItemClicked(params.postCardType)
             when (params.postCardType) {
                 PostCardType.DRAFT -> _onNavigation.value =
                     Event(SiteNavigationAction.EditDraftPost(site, params.postId))
@@ -69,11 +77,32 @@ class PostsCardViewModelSlice @Inject constructor(

     private fun onPostCardViewAllClick(postCardType: PostCardType) {
         selectedSiteRepository.getSelectedSite()?.let { site ->
-           // todo: annmarie implement tracking cardsTracker.trackPostCardFooterLinkClicked(postCardType)
             _onNavigation.value = when (postCardType) {
                 PostCardType.DRAFT -> Event(SiteNavigationAction.OpenDraftsPosts(site))
                 PostCardType.SCHEDULED -> Event(SiteNavigationAction.OpenScheduledPosts(site))
             }
         }
     }
+
+    private fun trackPostItemClicked(postCardType: PostCardType) {
+        cardsTracker.trackCardItemClicked(CardsTracker.Type.POST.label, postCardType.toSubtypeValue().label)
+    }
+
+    enum class PostMenuItemType(val label: String) {
+        VIEW_ALL_DRAFTS("view_all_drafts"),
+        VIEW_ALL_SCHEDULED_POSTS("view_all_scheduled_posts"),
+        HIDE_THIS("hide_this")
+    }
+
+    enum class PostMenuCard(val label: String) {
+        DRAFT_POSTS("draft_posts"),
+        SCHEDULED_POSTS("scheduled_posts")
+    }
+
+    private fun PostCardType.toPostMenuCardValue(): PostMenuCard {
+        return when (this) {
+            PostCardType.DRAFT -> PostMenuCard.DRAFT_POSTS
+            PostCardType.SCHEDULED -> PostMenuCard.SCHEDULED_POSTS
+        }
+    }
 }

diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsTrackerTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsTrackerTest.kt
index e6522f993f3f..cd7987188d0e 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsTrackerTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/dashboard/CardsTrackerTest.kt
@@ -10,10 +10,8 @@ import org.wordpress.android.analytics.AnalyticsTracker.Stat
 import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTaskType
 import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.ActivityLogSubtype
 import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.MenuItemType
-import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.PostSubtype
 import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.QuickStartSubtype
 import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker.Type
-import org.wordpress.android.ui.mysite.cards.dashboard.posts.PostCardType
 import org.wordpress.android.ui.quickstart.QuickStartTracker
 import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper

@@ -55,35 +53,6 @@ class CardsTrackerTest {
         verifyQuickStartCardItemClickedTracked(QuickStartSubtype.CUSTOMIZE.label)
     }

-    /* POST CARDS */
-    @Test
-    fun `when post draft footer link is clicked, then post draft event is tracked`() {
-        cardsTracker.trackPostCardFooterLinkClicked(PostCardType.DRAFT)
-
-        verifyFooterLinkClickedTracked(Type.POST, PostSubtype.DRAFT.label)
-    }
-
-    @Test
-    fun `when post scheduled footer link is clicked, then post scheduled event is tracked`() {
-        cardsTracker.trackPostCardFooterLinkClicked(PostCardType.SCHEDULED)
-
-        verifyFooterLinkClickedTracked(Type.POST, PostSubtype.SCHEDULED.label)
-    }
-
-    @Test
-    fun `when post draft item is clicked, then post item event is tracked`() {
-        cardsTracker.trackPostItemClicked(PostCardType.DRAFT)
-
-        verifyCardItemClickedTracked(Type.POST, PostSubtype.DRAFT.label)
-    }
-
-    @Test
-    fun `when post scheduled item is clicked, then post item event is tracked`() {
-        cardsTracker.trackPostItemClicked(PostCardType.SCHEDULED)
-
-        verifyCardItemClickedTracked(Type.POST, PostSubtype.SCHEDULED.label)
-    }
-
     @Test
     fun `when activity log item is clicked, then activity card item event is tracked`() {
         cardsTracker.trackActivityCardItemClicked()
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 440392eb3f71..ac985a8ccc17 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
@@ -17,6 +17,8 @@ import org.wordpress.android.ui.mysite.SelectedSiteRepository
 import org.wordpress.android.ui.mysite.SiteNavigationAction
 import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker
 import org.wordpress.android.ui.prefs.AppPrefsWrapper
+import org.wordpress.android.ui.mysite.cards.dashboard.posts.PostsCardViewModelSlice.PostMenuItemType
+import org.wordpress.android.ui.mysite.cards.dashboard.posts.PostsCardViewModelSlice.PostMenuCard

 @ExperimentalCoroutinesApi
 @RunWith(MockitoJUnitRunner::class)
@@ -77,6 +79,10 @@ class PostsCardViewModelSliceTest : BaseUnitTest() {
             )

             assertThat(navigationActions).containsOnly(SiteNavigationAction.EditDraftPost(site, postId))
+            verify(cardsTracker).trackCardItemClicked(
+                CardsTracker.Type.POST.label,
+                CardsTracker.PostSubtype.DRAFT.label
+            )
         }

     @Test
@@ -92,6 +98,10 @@ class PostsCardViewModelSliceTest : BaseUnitTest() {
             )

             assertThat(navigationActions).containsOnly(SiteNavigationAction.EditScheduledPost(site, postId))
+            verify(cardsTracker).trackCardItemClicked(
+                CardsTracker.Type.POST.label,
+                CardsTracker.PostSubtype.SCHEDULED.label
+            )
         }

     @Test
@@ -105,7 +115,10 @@ class PostsCardViewModelSliceTest : BaseUnitTest() {
             )
         )

-        verify(cardsTracker).trackPostItemClicked(PostCardType.SCHEDULED)
+        verify(cardsTracker).trackCardItemClicked(
+            CardsTracker.Type.POST.label,
+            CardsTracker.PostSubtype.SCHEDULED.label
+        )
     }

     @Test
@@ -119,7 +132,7 @@ class PostsCardViewModelSliceTest : BaseUnitTest() {
             )
         )

-        verify(cardsTracker).trackPostItemClicked(PostCardType.DRAFT)
+        verify(cardsTracker).trackCardItemClicked(CardsTracker.Type.POST.label, CardsTracker.PostSubtype.DRAFT.label)
     }

     @Test
@@ -129,7 +142,10 @@ class PostsCardViewModelSliceTest : BaseUnitTest() {
         params.moreMenuClickParams.onViewPostsMenuItemClick(PostCardType.DRAFT)

         assertThat(navigationActions).containsOnly(SiteNavigationAction.OpenDraftsPosts(site))
-        //  verify(cardsTracker).trackPostCardFooterLinkClicked(PostCardType.DRAFT)
+        verify(cardsTracker).trackCardMoreMenuItemClicked(
+            PostMenuCard.DRAFT_POSTS.label,
+            PostMenuItemType.VIEW_ALL_DRAFTS.label
+        )
     }

     @Test
@@ -140,6 +156,10 @@ class PostsCardViewModelSliceTest : BaseUnitTest() {
             params.moreMenuClickParams.onViewPostsMenuItemClick(PostCardType.SCHEDULED)

             assertThat(navigationActions).containsOnly(SiteNavigationAction.OpenScheduledPosts(site))
+            verify(cardsTracker).trackCardMoreMenuItemClicked(
+                PostMenuCard.SCHEDULED_POSTS.label,
+                PostMenuItemType.VIEW_ALL_SCHEDULED_POSTS.label
+            )
         }

     @Test
@@ -156,6 +176,21 @@ class PostsCardViewModelSliceTest : BaseUnitTest() {
         assertThat(refreshEvents).containsOnly(true)
     }

+    @Test
+    fun `given drafts post card, when more menu item hide this is accessed, then hide card is tracked`() = test {
+        val siteId = 1L
+        whenever(selectedSiteRepository.getSelectedSite()?.siteId).thenReturn(siteId)
+
+        val params = postsCardViewModelSlice.getPostsCardBuilderParams(mock())
+
+        params.moreMenuClickParams.onHideThisMenuItemClick.invoke(PostCardType.DRAFT)
+
+        verify(cardsTracker).trackCardMoreMenuItemClicked(
+            PostMenuCard.DRAFT_POSTS.label,
+            PostMenuItemType.HIDE_THIS.label
+        )
+    }
+
     @Test
     fun `given scheduled post card, when more menu item hide this is accessed, then hide card is invoked`() = test {
         val siteId = 1L
@@ -169,4 +204,19 @@ class PostsCardViewModelSliceTest : BaseUnitTest() {

         assertThat(refreshEvents).containsOnly(true)
     }
+
+    @Test
+    fun `given scheduled post card, when more menu item hide this is accessed, then hide card is tracked`() = test {
+        val siteId = 1L
+        whenever(selectedSiteRepository.getSelectedSite()?.siteId).thenReturn(siteId)
+
+        val params = postsCardViewModelSlice.getPostsCardBuilderParams(mock())
+
+        params.moreMenuClickParams.onHideThisMenuItemClick.invoke(PostCardType.SCHEDULED)
+
+        verify(cardsTracker).trackCardMoreMenuItemClicked(
+            PostMenuCard.SCHEDULED_POSTS.label,
+            PostMenuItemType.HIDE_THIS.label
+        )
+    }
 }


Fixes: My site dashboard menu items tracking

Fixes #19114

## Description
This PR implements the tracking on clicking menu items in MySiteDashboard

## To test:
1. Login to the app
2. Go to Menu
3. Tap on menu item posts|stats
4. Verify that the tracking is present
5. 🔵 Tracked: my_site_menu_item_tapped, Properties: {"type":"posts|stats"}
5. Tap on any other item
6. Verify that following tracking is present
7. 🔵 Tracked: my_site_menu_item_tapped, Properties: {"type":"MENU_LABEL"}

## Regression Notes
1. Potential unintended areas of impact
Incorrect tracking

2. What I did to test those areas of impact (or what existing automated tests I relied on)
Manual testing and Unit testing

3. What automated tests I added (or what prevented me from doing so)
Unit tests

PR submission checklist:
- [x] I have completed the Regression Notes.
- [x] I have considered adding accessibility improvements for my changes.
- [x] I have considered if this change warrants user-facing release notes and have added them to `RELEASE-NOTES.txt` if necessary.

UI Changes testing checklist:
- [x] Portrait and landscape orientations.
- [x] Light and dark modes.
- [x] Fonts: Larger, smaller and bold text.
- [x] High contrast.
- [x] Talkback.
- [x] Languages with large words or with letters/accents not frequently used in English.
- [x] Right-to-left languages. (Even if translation isn’t complete, formatting should still respect the right-to-left layout)
- [x] Large and small screen sizes. (Tablet and smaller phones)
- [x] Multi-tasking: Split screen and Pop-up view. (Android 10 or higher)

Missing tracking of Menu items in MySiteDashboard
### Expected behavior
On clicking menu items in MySiteDashboard the following event should be triggered for all the items
-  🔵 Tracked: my_site_menu_item_tapped, Properties: {"type":"MENU_ITEM_LABEL"}

### Actual behavior
The tracking is present only for Posts and Stats Menu item

### Steps to reproduce the behavior
1. Login to the app
2. Go to Menu
3. Tap on menu item posts|stats
4. Verify that the tracking is present
5. Tap on any other item
6. Notice that no tracking is present

##### Tested on [device], Android [version], JPAndroid / WPAndroid [version]
Pixel 6, Android 13, version 23.1

./gradlew :WordPress:testWordpressVanillaDebugUnitTest --tests "org.wordpress.android.ui.mysite.MySiteViewModelTest" --tests "org.wordpress.android.ui.mysite.items.SiteItemsTrackerTest"

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 00af915c6a45..75d903da827c 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
@@ -106,7 +106,6 @@ import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository.Qui
 import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository.QuickStartTabStep
 import org.wordpress.android.ui.mysite.cards.siteinfo.SiteInfoHeaderCardBuilder
 import org.wordpress.android.ui.mysite.items.SiteItemsBuilder
-import org.wordpress.android.ui.mysite.items.SiteItemsTracker
 import org.wordpress.android.ui.mysite.items.listitem.ListItemAction
 import org.wordpress.android.ui.mysite.tabs.MySiteTabType
 import org.wordpress.android.ui.pages.SnackbarMessageHolder
@@ -181,7 +180,6 @@ class MySiteViewModel @Inject constructor(
     private val landOnTheEditorFeatureConfig: LandOnTheEditorFeatureConfig,
     private val mySiteSourceManager: MySiteSourceManager,
     private val cardsTracker: CardsTracker,
-    private val siteItemsTracker: SiteItemsTracker,
     private val domainRegistrationCardShownTracker: DomainRegistrationCardShownTracker,
     private val buildConfigWrapper: BuildConfigWrapper,
     mySiteDashboardTabsFeatureConfig: MySiteDashboardTabsFeatureConfig,
@@ -914,7 +912,7 @@ class MySiteViewModel @Inject constructor(
     @Suppress("ComplexMethod")
     private fun onItemClick(action: ListItemAction) {
         selectedSiteRepository.getSelectedSite()?.let { selectedSite ->
-            siteItemsTracker.trackSiteItemClicked(action)
+            analyticsTrackerWrapper.track(Stat.MY_SITE_MENU_ITEM_TAPPED, mapOf(TYPE to action.trackingLabel))
             val navigationAction = when (action) {
                 ListItemAction.ACTIVITY_LOG -> SiteNavigationAction.OpenActivityLog(selectedSite)
                 ListItemAction.BACKUP -> SiteNavigationAction.OpenBackup(selectedSite)
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/SiteItemsTracker.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/SiteItemsTracker.kt
deleted file mode 100644
index 552b676db0d1..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/SiteItemsTracker.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.wordpress.android.ui.mysite.items
-
-import org.wordpress.android.analytics.AnalyticsTracker.Stat
-import org.wordpress.android.ui.mysite.items.listitem.ListItemAction
-import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
-import javax.inject.Inject
-
-class SiteItemsTracker @Inject constructor(
-    private val analyticsTrackerWrapper: AnalyticsTrackerWrapper
-) {
-    enum class Type(val label: String) {
-        POSTS("posts"),
-        STATS("stats")
-    }
-
-    fun trackSiteItemClicked(listItemAction: ListItemAction) = trackSiteItemClicked(listItemAction.toTypeValue())
-
-    private fun trackSiteItemClicked(type: Type?) {
-        type?.let {
-            analyticsTrackerWrapper.track(Stat.MY_SITE_MENU_ITEM_TAPPED, mapOf(TYPE to it.label))
-        }
-    }
-
-    private fun ListItemAction.toTypeValue(): Type? {
-        return when (this) {
-            ListItemAction.POSTS -> Type.POSTS
-            ListItemAction.STATS -> Type.STATS
-            else -> null
-        }
-    }
-
-    companion object {
-        private const val TYPE = "type"
-    }
-}
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/ListItemAction.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/ListItemAction.kt
index 1cf63b3dd10d..b56aa26bc32f 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/ListItemAction.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/ListItemAction.kt
@@ -1,24 +1,24 @@
 package org.wordpress.android.ui.mysite.items.listitem

-enum class ListItemAction {
-    ACTIVITY_LOG,
-    BACKUP,
-    SCAN,
-    JETPACK_SETTINGS,
-    PLAN,
-    POSTS,
-    PAGES,
-    ADMIN,
-    PEOPLE,
-    SHARING,
-    DOMAINS,
-    SITE_SETTINGS,
-    THEMES,
-    PLUGINS,
-    STATS,
-    MEDIA,
-    COMMENTS,
-    VIEW_SITE,
-    BLAZE,
-    ME
+enum class ListItemAction (val trackingLabel: String) {
+    ACTIVITY_LOG("activity_log"),
+    BACKUP("backup"),
+    SCAN("scan"),
+    JETPACK_SETTINGS("jetpack_settings"),
+    PLAN("plan"),
+    POSTS("posts"),
+    PAGES("pages"),
+    ADMIN("admin"),
+    PEOPLE("people"),
+    SHARING("sharing"),
+    DOMAINS("domains"),
+    SITE_SETTINGS("site_settings"),
+    THEMES("themes"),
+    PLUGINS("plugins"),
+    STATS("stats"),
+    MEDIA("media"),
+    COMMENTS("comments"),
+    VIEW_SITE("view_site"),
+    BLAZE("blaze"),
+    ME("me"),
 }

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 55323820a635..9b529e23026a 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
@@ -126,7 +126,6 @@ import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository.Qui
 import org.wordpress.android.ui.mysite.cards.quickstart.QuickStartRepository.QuickStartTabStep
 import org.wordpress.android.ui.mysite.cards.siteinfo.SiteInfoHeaderCardBuilder
 import org.wordpress.android.ui.mysite.items.SiteItemsBuilder
-import org.wordpress.android.ui.mysite.items.SiteItemsTracker
 import org.wordpress.android.ui.mysite.items.listitem.ListItemAction
 import org.wordpress.android.ui.mysite.tabs.MySiteTabType
 import org.wordpress.android.ui.pages.SnackbarMessageHolder
@@ -232,9 +231,6 @@ class MySiteViewModelTest : BaseUnitTest() {
     @Mock
     lateinit var cardsTracker: CardsTracker

-    @Mock
-    lateinit var siteItemsTracker: SiteItemsTracker
-
     @Mock
     lateinit var domainRegistrationCardShownTracker: DomainRegistrationCardShownTracker

@@ -523,7 +519,6 @@ class MySiteViewModelTest : BaseUnitTest() {
             landOnTheEditorFeatureConfig,
             mySiteSourceManager,
             cardsTracker,
-            siteItemsTracker,
             domainRegistrationCardShownTracker,
             buildConfigWrapper,
             mySiteDashboardTabsFeatureConfig,
@@ -2342,7 +2337,10 @@ class MySiteViewModelTest : BaseUnitTest() {
     fun `when site item is clicked, then event is tracked`() = test {
         invokeItemClickAction(ListItemAction.POSTS)

-        verify(siteItemsTracker).trackSiteItemClicked(ListItemAction.POSTS)
+        verify(analyticsTrackerWrapper).track(
+            Stat.MY_SITE_MENU_ITEM_TAPPED,
+            mapOf("type" to ListItemAction.POSTS.trackingLabel)
+        )
     }

     @Test
diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/SiteItemsTrackerTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/SiteItemsTrackerTest.kt
deleted file mode 100644
index 45611d887247..000000000000
--- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/SiteItemsTrackerTest.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.wordpress.android.ui.mysite.items
-
-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.times
-import org.mockito.kotlin.verify
-import org.wordpress.android.analytics.AnalyticsTracker.Stat
-import org.wordpress.android.ui.mysite.items.SiteItemsTracker.Type
-import org.wordpress.android.ui.mysite.items.listitem.ListItemAction
-import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
-
-private const val TYPE = "type"
-
-@RunWith(MockitoJUnitRunner::class)
-class SiteItemsTrackerTest {
-    @Mock
-    lateinit var analyticsTracker: AnalyticsTrackerWrapper
-    private lateinit var siteItemsTracker: SiteItemsTracker
-
-    @Before
-    fun setUp() {
-        siteItemsTracker = SiteItemsTracker(analyticsTracker)
-    }
-
-    @Test
-    fun `when site item posts is clicked, then menu item tapped posts is tracked`() {
-        siteItemsTracker.trackSiteItemClicked(ListItemAction.POSTS)
-
-        verifySiteItemClickedTracked(Type.POSTS)
-    }
-
-    @Test
-    fun `when site item stats is clicked, then menu item tapped stats is tracked`() {
-        siteItemsTracker.trackSiteItemClicked(ListItemAction.STATS)
-
-        verifySiteItemClickedTracked(Type.STATS)
-    }
-
-    @Test
-    fun `given not tracking site item, when site item is clicked, then click is not tracked`() {
-        siteItemsTracker.trackSiteItemClicked(ListItemAction.VIEW_SITE)
-
-        verify(analyticsTracker, times(0)).track(any())
-    }
-
-    private fun verifySiteItemClickedTracked(typeValue: Type) {
-        verify(analyticsTracker).track(Stat.MY_SITE_MENU_ITEM_TAPPED, mapOf(TYPE to typeValue.label))
-    }
-}


Dashboard Personalization: Personalize card navigation, tracking and unit testing

Closes #18937

This PR adds the following for the personalize card
- Navigation event for onclick
- Tracking for card shown and tapped
- Add unit tests

**To test:**
- Install the app and login
- Navigate to Me > Debug Settings > enable `dashboard_personalization` and restart the app
- Navigate to the My Site tab
- ✅ Verify log contains: 🔵 Tracked: my_site_dashboard_card_shown, Properties: {"type":"personalize","subtype":"personalize"}
- Tap on the personalize card
- ✅ Verify log contains: 🔵 Tracked: my_site_dashboard_card_item_tapped, Properties: {"type":"personalize","subtype":"personalize"}

## Regression Notes
1. Potential unintended areas of impact
Personalize card tracking and events do not work correctly

2. What I did to test those areas of impact (or what existing automated tests I relied on)
Manual testing and new unit tests `PersonalizeCardViewModelSliceTest` and `PersonalizeCardBuilderTest`

3. What automated tests I added (or what prevented me from doing so) N/A

PR submission checklist:

- [x] I have completed the Regression Notes.
- [x] I have considered adding accessibility improvements for my changes.
- [x] I have considered if this change warrants user-facing release notes and have added them to `RELEASE-NOTES.txt` if necessary.

UI Changes testing checklist: N/A

Dashboard Personalization: Create Personalize Your Home Tab Card
Create the **Personalize Home Tab** card

![Image](https://github.com/wordpress-mobile/WordPress-Android/assets/506707/5624c751-af13-40bb-9100-f02a14d6c0de)

```[tasklist]
### Tasks
- [x] Guard with `dashboard_personalization` feature flag
- [x] Create compose UI, viewmodel, builder, etc
- [x] Slot as last card on the dashboard
- [x] On card tap: navigate to Personalize Home Tab View (Add new navigation event)
- [x] On card tap: track `my_site_dashboard_card_item_tapped` with property `type:personalize`
- [x] On card shown: track `my_site_dashboard_card_shown` with property `type:personalize`
```

diff --git a/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt b/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt
index 16406fd9a874..d6aa4ad91098 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/ActivityNavigator.kt
@@ -11,6 +11,7 @@ import org.wordpress.android.ui.blaze.blazecampaigns.campaignlisting.CampaignLis
 import org.wordpress.android.ui.blaze.blazepromote.ARG_BLAZE_FLOW_SOURCE
 import org.wordpress.android.ui.blaze.blazepromote.ARG_BLAZE_SHOULD_SHOW_OVERLAY
 import org.wordpress.android.ui.blaze.blazepromote.BlazePromoteParentActivity
+import org.wordpress.android.ui.mysite.personalisation.PersonalisationActivity
 import javax.inject.Inject
 import javax.inject.Singleton

@@ -59,4 +60,8 @@ class ActivityNavigator @Inject constructor() {
     ) {
         WPWebViewActivity.openUrlByUsingGlobalWPCOMCredentials(context, url)
     }
+
+    fun openDashboardPersonalization(context: Context) {
+        context.startActivity(Intent(context, PersonalisationActivity::class.java))
+    }
 }
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 fa8e2107a96e..1cfcf073ea66 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
@@ -282,7 +282,8 @@ class MySiteViewModel @Inject constructor(
         postsCardViewModelSlice.onNavigation,
         activityLogCardViewModelSlice.onNavigation,
         siteItemsViewModelSlice.onNavigation,
-        bloggingPromptCardViewModelSlice.onNavigation
+        bloggingPromptCardViewModelSlice.onNavigation,
+        personalizeCardViewModelSlice.onNavigation
     )
     val onMediaUpload = _onMediaUpload as LiveData<Event<MediaModel>>
     val onUploadedItem = siteIconUploadHandler.onUploadedItem
@@ -1364,6 +1365,8 @@ class MySiteViewModel @Inject constructor(
         siteSelected.cardAndItems.filterIsInstance<JetpackInstallFullPluginCard>()
             .forEach { jetpackInstallFullPluginShownTracker.trackShown(it.type, quickStartRepository.currentTab) }
         dashboardCardPlansUtils.trackCardShown(viewModelScope, siteSelected)
+        siteSelected.dashboardCardsAndItems.filterIsInstance<MySiteCardAndItem.Card.PersonalizeCardModel>()
+            .forEach { personalizeCardViewModelSlice.trackShown(it.type) }
     }

     private fun resetShownTrackers() {
@@ -1372,6 +1375,7 @@ class MySiteViewModel @Inject constructor(
         quickStartTracker.resetShown()
         jetpackFeatureCardShownTracker.resetShown()
         jetpackInstallFullPluginShownTracker.resetShown()
+        personalizeCardViewModelSlice.resetShown()
     }

     private fun trackTabChanged(isSiteMenu: Boolean) {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteNavigationAction.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteNavigationAction.kt
index 6ca47cf0eb8a..10fed8d798d3 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteNavigationAction.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/SiteNavigationAction.kt
@@ -104,6 +104,7 @@ sealed class SiteNavigationAction {
         SiteNavigationAction()

     data class OpenDomainTransferPage(val url: String) : SiteNavigationAction()
+    object OpenDashboardPersonalization : SiteNavigationAction()
 }

 sealed class BloggingPromptCardNavigationAction: SiteNavigationAction() {
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 41fe5f1eda5e..80ce6b0a7f39 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
@@ -30,6 +30,7 @@ class CardsTracker @Inject constructor(
         ACTIVITY("activity_log"),
         DASHBOARD_CARD_PLANS("dashboard_card_plans"),
         DASHBOARD_CARD_DOMAIN_TRANSFER("dashboard_card_domain_transfer"),
+        PERSONALIZE_CARD("personalize")
     }

     enum class QuickStartSubtype(val label: String) {
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardShownTracker.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardShownTracker.kt
new file mode 100644
index 000000000000..cf94d65d7e28
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardShownTracker.kt
@@ -0,0 +1,32 @@
+package org.wordpress.android.ui.mysite.cards.personalize
+
+import org.wordpress.android.analytics.AnalyticsTracker
+import org.wordpress.android.ui.mysite.MySiteCardAndItem
+import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker
+import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
+import javax.inject.Inject
+
+class PersonalizeCardShownTracker @Inject constructor(
+    private val analyticsTrackerWrapper: AnalyticsTrackerWrapper
+) {
+    private val cardsShownTracked = mutableListOf<MySiteCardAndItem.Type>()
+
+    fun resetShown() {
+        cardsShownTracked.clear()
+    }
+
+    fun trackShown(itemType: MySiteCardAndItem.Type) {
+        if (itemType == MySiteCardAndItem.Type.PERSONALIZE_CARD) {
+            if (!cardsShownTracked.contains(itemType)) {
+                cardsShownTracked.add(itemType)
+                analyticsTrackerWrapper.track(
+                    AnalyticsTracker.Stat.MY_SITE_DASHBOARD_CARD_SHOWN,
+                    mapOf(
+                        CardsTracker.TYPE to CardsTracker.Type.PERSONALIZE_CARD.label,
+                        CardsTracker.SUBTYPE to CardsTracker.Type.PERSONALIZE_CARD.label
+                    )
+                )
+            }
+        }
+    }
+}
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 beabb56b3fe8..8936960986b2 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
@@ -1,15 +1,37 @@
 package org.wordpress.android.ui.mysite.cards.personalize

+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import org.wordpress.android.ui.mysite.MySiteCardAndItem
+import org.wordpress.android.ui.mysite.SiteNavigationAction.OpenDashboardPersonalization
 import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.PersonalizeCardBuilderParams
+import org.wordpress.android.ui.mysite.SiteNavigationAction
+import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker
+import org.wordpress.android.viewmodel.Event
 import javax.inject.Inject
-import javax.inject.Singleton

-@Singleton
-class PersonalizeCardViewModelSlice@Inject constructor(
+class PersonalizeCardViewModelSlice @Inject constructor(
+    private val cardsTracker: CardsTracker,
+    private val personalizeCardShownTracker: PersonalizeCardShownTracker
 )  {
+    private val _onNavigation = MutableLiveData<Event<SiteNavigationAction>>()
+    val onNavigation = _onNavigation as LiveData<Event<SiteNavigationAction>>
+
     fun getBuilderParams() = PersonalizeCardBuilderParams(onClick = this::onCardClick)

     fun onCardClick() {
-        // todo: implement
+        cardsTracker.trackCardItemClicked(
+            CardsTracker.Type.PERSONALIZE_CARD.label,
+            CardsTracker.Type.PERSONALIZE_CARD.label
+        )
+        _onNavigation.value = Event(OpenDashboardPersonalization)
+    }
+
+    fun trackShown(itemType: MySiteCardAndItem.Type) {
+        personalizeCardShownTracker.trackShown(itemType)
+    }
+
+    fun resetShown() {
+        personalizeCardShownTracker.resetShown()
     }
 }
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/personalisation/PersonalisationActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/personalisation/PersonalisationActivity.kt
index 851a93f591c3..ab8b14e5d88c 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/personalisation/PersonalisationActivity.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/personalisation/PersonalisationActivity.kt
@@ -28,11 +28,13 @@ import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.lifecycle.LiveData
+import dagger.hilt.android.AndroidEntryPoint
 import org.wordpress.android.R
 import org.wordpress.android.ui.compose.components.MainTopAppBar
 import org.wordpress.android.ui.compose.components.NavigationIcons
 import org.wordpress.android.ui.compose.theme.AppTheme

+@AndroidEntryPoint
 class PersonalisationActivity : ComponentActivity() {
     private val viewModel: PersonalisationViewModel by viewModels()

diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/tabs/MySiteTabFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/tabs/MySiteTabFragment.kt
index 9068667cf5c1..c3d0611f2ca4 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/tabs/MySiteTabFragment.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/tabs/MySiteTabFragment.kt
@@ -437,6 +437,10 @@ class MySiteTabFragment : Fragment(R.layout.my_site_tab_fragment),
         )

         is BloggingPromptCardNavigationAction -> handleNavigation(action)
+
+        is SiteNavigationAction.OpenDashboardPersonalization -> activityNavigator.openDashboardPersonalization(
+            requireActivity()
+        )
     }

     private fun handleNavigation(action: BloggingPromptCardNavigationAction) {

diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardBuilderTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardBuilderTest.kt
new file mode 100644
index 000000000000..1c24cd8b2cbe
--- /dev/null
+++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardBuilderTest.kt
@@ -0,0 +1,46 @@
+package org.wordpress.android.ui.mysite.cards.personalize
+
+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.mock
+import org.mockito.kotlin.whenever
+import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams
+import org.wordpress.android.util.config.DashboardPersonalizationFeatureConfig
+
+@RunWith(MockitoJUnitRunner::class)
+class PersonalizeCardBuilderTest {
+    @Mock
+    lateinit var featureConfig: DashboardPersonalizationFeatureConfig
+
+    private lateinit var builder: PersonalizeCardBuilder
+
+    @Before
+    fun setUp() {
+        builder = PersonalizeCardBuilder(featureConfig)
+    }
+
+    @Test
+    fun `given flag is enabled, when build requested, then model is built`() {
+        whenever(featureConfig.isEnabled()).thenReturn(true)
+
+        val result = builder.build(getParams())
+
+        assertThat(result).isNotNull
+    }
+
+    @Test
+    fun `given flag is disabled, when build requested, then model is not built`() {
+        whenever(featureConfig.isEnabled()).thenReturn(false)
+
+        val result = builder.build(getParams())
+
+        assertThat(result).isNull()
+    }
+
+    private fun getParams() =
+         MySiteCardAndItemBuilderParams.PersonalizeCardBuilderParams(mock())
+}
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
new file mode 100644
index 000000000000..19798dea39a8
--- /dev/null
+++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/cards/personalize/PersonalizeCardViewModelSliceTest.kt
@@ -0,0 +1,79 @@
+package org.wordpress.android.ui.mysite.cards.personalize
+
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+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.verify
+import org.wordpress.android.BaseUnitTest
+import org.wordpress.android.ui.mysite.MySiteCardAndItem
+import org.wordpress.android.ui.mysite.SiteNavigationAction
+import org.wordpress.android.ui.mysite.cards.dashboard.CardsTracker
+
+@ExperimentalCoroutinesApi
+@RunWith(MockitoJUnitRunner::class)
+class PersonalizeCardViewModelSliceTest : BaseUnitTest() {
+    @Mock
+    lateinit var cardsTracker: CardsTracker
+
+    @Mock
+    lateinit var personalizeCardShownTracker: PersonalizeCardShownTracker
+
+    private lateinit var viewModelSlice: PersonalizeCardViewModelSlice
+
+    private lateinit var navigationActions: MutableList<SiteNavigationAction>
+
+    @Before
+    fun setUp() {
+        viewModelSlice = PersonalizeCardViewModelSlice(
+            cardsTracker,
+            personalizeCardShownTracker
+        )
+        navigationActions = mutableListOf()
+        viewModelSlice.onNavigation.observeForever { event ->
+            event?.getContentIfNotHandled()?.let {
+                navigationActions.add(it)
+            }
+        }
+    }
+
+    @Test
+    fun `given personalize card, when card item is clicked, then event is tracked`() =
+        test {
+            val params = viewModelSlice.getBuilderParams()
+
+            params.onClick()
+
+            verify(cardsTracker).trackCardItemClicked(
+                CardsTracker.Type.PERSONALIZE_CARD.label, CardsTracker.Type.PERSONALIZE_CARD.label)
+        }
+
+    @Test
+    fun `given personalize card, when card item is clicked, then open personalize event is raised`() =
+        test {
+            val params = viewModelSlice.getBuilderParams()
+
+            params.onClick()
+
+            assertThat(navigationActions).containsOnly(SiteNavigationAction.OpenDashboardPersonalization)
+        }
+
+    @Test
+    fun `given personalize card, when card shown track requested, then track card shown`() =
+        test {
+            viewModelSlice.trackShown(MySiteCardAndItem.Type.PERSONALIZE_CARD)
+
+            verify(personalizeCardShownTracker).trackShown(MySiteCardAndItem.Type.PERSONALIZE_CARD)
+        }
+
+    @Test
+    fun `given personalize card, when reset shown tracker requested, then track card shown is reset`() =
+        test {
+            viewModelSlice.resetShown()
+
+            verify(personalizeCardShownTracker).resetShown()
+        }
+}


Plans in site creation: Remove site domains feature flag

Fixes #19252

Removing the site domains feature flag as it a stable feature

<img width=320 src="https://github.com/wordpress-mobile/WordPress-Android/assets/990349/7d89184a-c3ea-4a94-9be5-542632c4e8bc" />

To test:

- Launch JP app
- `Go` to Debug settings (Me -> Debug settings)
- `Verify` `site_domains_remote_field` as shown above is not present
- `Switch` to  `Menu` tab on `My Site`
- `Verify` menu item `Domains` is present under Manage
- `Tap` on `Domains`
- `Verify` it opens domains screen

## Regression Notes
1. Potential unintended areas of impact
None

2. What I did to test those areas of impact (or what existing automated tests I relied on)
Manual testing

3. What automated tests I added (or what prevented me from doing so)
Updated unit tests

PR submission checklist:

- [x] I have completed the Regression Notes.
- [x] I have considered adding accessibility improvements for my changes.
- [x] I have considered if this change warrants user-facing release notes and have added them to `RELEASE-NOTES.txt` if necessary.

Plans in Site Creation: Remove SITE_DOMAINS Feature Flag
There's an old site domains feature flag done almost two years ago that needs to be removed

      Fails

      :no_entry_sign:

  Please add a type label to this issue. e.g. '[Type] Enhancement'

  Generated by :no_entry_sign: dangerJS

diff --git a/WordPress/build.gradle b/WordPress/build.gradle
index a2656512789b..a5e47e4cf5f1 100644
--- a/WordPress/build.gradle
+++ b/WordPress/build.gradle
@@ -108,7 +108,6 @@ android {
         buildConfigField "boolean", "MANAGE_CATEGORIES", "false"
         buildConfigField "boolean", "GLOBAL_STYLE_SUPPORT", "true"
         buildConfigField "boolean", "QUICK_START_DYNAMIC_CARDS", "false"
-        buildConfigField "boolean", "SITE_DOMAINS", "false"
         buildConfigField "boolean", "RECOMMEND_THE_APP", "false"
         buildConfigField "boolean", "UNIFIED_COMMENTS_COMMENT_EDIT", "false"
         buildConfigField "boolean", "MY_SITE_DASHBOARD_TABS", "false"
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModel.kt
index 951ff2a23d6d..1b8e9d52b93e 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModel.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModel.kt
@@ -24,7 +24,6 @@ import org.wordpress.android.ui.domains.usecases.CreateCartUseCase
 import org.wordpress.android.util.AppLog
 import org.wordpress.android.util.AppLog.T
 import org.wordpress.android.util.SiteUtils
-import org.wordpress.android.util.config.SiteDomainsFeatureConfig
 import org.wordpress.android.util.extensions.isOnSale
 import org.wordpress.android.util.helpers.Debouncer
 import org.wordpress.android.viewmodel.Event
@@ -39,7 +38,6 @@ class DomainSuggestionsViewModel @Inject constructor(
     private val domainsRegistrationTracker: DomainsRegistrationTracker,
     private val dispatcher: Dispatcher,
     private val debouncer: Debouncer,
-    private val siteDomainsFeatureConfig: SiteDomainsFeatureConfig,
     private val createCartUseCase: CreateCartUseCase,
     @Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher
 ) : ScopedViewModel(bgDispatcher) {
@@ -197,7 +195,7 @@ class DomainSuggestionsViewModel @Inject constructor(
                     vendor = it.vendor,
                     relevance = it.relevance,
                     isSelected = _selectedSuggestion.value?.domainName == it.domain_name,
-                    isCostVisible = siteDomainsFeatureConfig.isEnabled(),
+                    isCostVisible = true,
                     isFreeWithCredits = domainRegistrationPurpose(),
                     isEnabled = true
                 )
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteListItemBuilder.kt b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteListItemBuilder.kt
index b3e24887f2ec..0b5a532f7ac5 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteListItemBuilder.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/mysite/items/listitem/SiteListItemBuilder.kt
@@ -29,7 +29,6 @@ import org.wordpress.android.ui.utils.UiString.UiStringText
 import org.wordpress.android.util.BuildConfigWrapper
 import org.wordpress.android.util.DateTimeUtils
 import org.wordpress.android.util.SiteUtilsWrapper
-import org.wordpress.android.util.config.SiteDomainsFeatureConfig
 import java.util.GregorianCalendar
 import java.util.TimeZone
 import javax.inject.Inject
@@ -40,7 +39,6 @@ class SiteListItemBuilder @Inject constructor(
     private val siteUtilsWrapper: SiteUtilsWrapper,
     private val buildConfigWrapper: BuildConfigWrapper,
     private val themeBrowserUtils: ThemeBrowserUtils,
-    private val siteDomainsFeatureConfig: SiteDomainsFeatureConfig,
     private val jetpackFeatureRemovalPhaseHelper: JetpackFeatureRemovalPhaseHelper
 ) {
     fun buildActivityLogItemIfAvailable(site: SiteModel, onClick: (ListItemAction) -> Unit): ListItem? {
@@ -162,7 +160,6 @@ class SiteListItemBuilder @Inject constructor(
     fun buildDomainsItemIfAvailable(site: SiteModel, onClick: (ListItemAction) -> Unit): ListItem? {
         return if (
             buildConfigWrapper.isJetpackApp &&
-            siteDomainsFeatureConfig.isEnabled() &&
             site.hasCapabilityManageOptions
         ) {
             ListItem(
diff --git a/WordPress/src/main/java/org/wordpress/android/util/config/SiteDomainsFeatureConfig.kt b/WordPress/src/main/java/org/wordpress/android/util/config/SiteDomainsFeatureConfig.kt
deleted file mode 100644
index 40b710d34a6a..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/util/config/SiteDomainsFeatureConfig.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.wordpress.android.util.config
-
-import org.wordpress.android.BuildConfig
-import org.wordpress.android.annotation.Feature
-import javax.inject.Inject
-
-@Feature(SiteDomainsFeatureConfig.SITE_DOMAINS_REMOTE_FIELD, true)
-class SiteDomainsFeatureConfig
-@Inject constructor(appConfig: AppConfig) : FeatureConfig(
-    appConfig,
-    BuildConfig.SITE_DOMAINS,
-    SITE_DOMAINS_REMOTE_FIELD
-) {
-    companion object {
-        const val SITE_DOMAINS_REMOTE_FIELD = "site_domains_remote_field"
-    }
-}

diff --git a/WordPress/src/test/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModelTest.kt
index fea1061fe04e..d968c4ac9dfd 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModelTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/domains/DomainSuggestionsViewModelTest.kt
@@ -31,7 +31,6 @@ import org.wordpress.android.ui.domains.DomainRegistrationActivity.DomainRegistr
 import org.wordpress.android.ui.domains.DomainRegistrationActivity.DomainRegistrationPurpose.DOMAIN_PURCHASE
 import org.wordpress.android.ui.domains.usecases.CreateCartUseCase
 import org.wordpress.android.ui.plans.PlansConstants
-import org.wordpress.android.util.config.SiteDomainsFeatureConfig
 import org.wordpress.android.util.helpers.Debouncer

 @ExperimentalCoroutinesApi
@@ -45,9 +44,6 @@ class DomainSuggestionsViewModelTest : BaseUnitTest() {
     @Mock
     lateinit var tracker: DomainsRegistrationTracker

-    @Mock
-    lateinit var siteDomainsFeatureConfig: SiteDomainsFeatureConfig
-
     @Mock
     lateinit var createCartUseCase: CreateCartUseCase

@@ -66,7 +62,6 @@ class DomainSuggestionsViewModelTest : BaseUnitTest() {
             tracker,
             dispatcher,
             debouncer,
-            siteDomainsFeatureConfig,
             createCartUseCase,
             testDispatcher()
         )
diff --git a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteListItemBuilderTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteListItemBuilderTest.kt
index c31b22b6842f..12f5777b438a 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteListItemBuilderTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/mysite/items/listitem/SiteListItemBuilderTest.kt
@@ -28,7 +28,6 @@ import org.wordpress.android.ui.plugins.PluginUtilsWrapper
 import org.wordpress.android.ui.themes.ThemeBrowserUtils
 import org.wordpress.android.util.BuildConfigWrapper
 import org.wordpress.android.util.SiteUtilsWrapper
-import org.wordpress.android.util.config.SiteDomainsFeatureConfig

 @RunWith(MockitoJUnitRunner::class)
 class SiteListItemBuilderTest {
@@ -53,8 +52,6 @@ class SiteListItemBuilderTest {
     @Mock
     lateinit var jetpackFeatureRemovalPhaseHelper: JetpackFeatureRemovalPhaseHelper

-    @Mock
-    lateinit var siteDomainsFeatureConfig: SiteDomainsFeatureConfig
     private lateinit var siteListItemBuilder: SiteListItemBuilder

     @Before
@@ -65,7 +62,6 @@ class SiteListItemBuilderTest {
             siteUtilsWrapper,
             buildConfigWrapper,
             themeBrowserUtils,
-            siteDomainsFeatureConfig,
             jetpackFeatureRemovalPhaseHelper
         )
     }


Plans in site creation: Remove domain purchasing feature flag

Fixes #19230

This PR removes domain purchasing in site creation feature flag, and replaces it with plans in site creation feature flag.

To test:

Test 1

- `Launch` JP app
- `Go` to Me-> Debug settings
- `Switch` to `Features in Development` tab
- `Verify` there's no `SiteCreationDomainPurchasing` feature flag is listed there
- `Switch` to `Remote Feature` tab, find `plans_in_site_creation` and enable it

Test 2

- `Go` to **My Site** tab
- `Tap` the down arrow to the right of the site name on the My Site screen
- `Tap` the + icon at the top right on the Site picker screen
- `Select` ⊕ **Create WordPress.com site** on the modal dialog
- `Tap` Skip at top right on the first step (topic screen)
- `Tap` Skip at top right on the next step (theme screen)
- `Enter` a search query (whatever you want here)
- `Verify` that result domains have either `Free` or `Price are no prices or "free" listed next to the domains on the right side

>**Note**
> Selecting a custom domain (with price) will launch, site assembly followed by checkout
> Selecting a free domain will launch site assembly an done

## Regression Notes
1. Potential unintended areas of impact
N/A

2. What I did to test those areas of impact (or what existing automated tests I relied on)
Manual and unit tests

3. What automated tests I added (or what prevented me from doing so)
Update existing unit tests

PR submission checklist:

- [x] I have completed the Regression Notes.
- [x] I have considered adding accessibility improvements for my changes.
- [x] I have considered if this change warrants user-facing release notes and have added them to `RELEASE-NOTES.txt` if necessary.

Plans in Site Creation: Remove DOMAIN_PURCHASING feature flag
There is a local only feature flag for domain purchasing in the site creation feature. Since we bind domain purchasing feature into "Plans in Site Creation" project, we should remove [SiteCreationDomainPurchasing](https://github.com/wordpress-mobile/WordPress-Android/blob/trunk/WordPress/src/main/java/org/wordpress/android/util/config/SiteCreationDomainPurchasingFeatureConfig.kt) flag.

diff --git a/WordPress/build.gradle b/WordPress/build.gradle
index 0036a3717d78..23921af71fd4 100644
--- a/WordPress/build.gradle
+++ b/WordPress/build.gradle
@@ -158,7 +158,6 @@ android {
         buildConfigField "boolean", "ENABLE_MY_SITE_DASHBOARD_TABS", "true"
         buildConfigField "boolean", "ENABLE_QRCODE_AUTH_FLOW", "true"
         buildConfigField "boolean", "ENABLE_OPEN_WEB_LINKS_WITH_JP_FLOW", "true"
-        buildConfigField "boolean", "ENABLE_SITE_CREATION_DOMAIN_PURCHASING", "false"
         buildConfigField "boolean", "BLAZE_MANAGE_CAMPAIGNS", "false"
         buildConfigField "boolean", "DASHBOARD_PERSONALIZATION", "false"

@@ -187,7 +186,6 @@ android {
             buildConfigField "String", "PUSH_NOTIFICATIONS_APP_KEY", '"org.wordpress.android"'
             buildConfigField "boolean", "ENABLE_QRCODE_AUTH_FLOW", "false"
             buildConfigField "boolean", "ENABLE_OPEN_WEB_LINKS_WITH_JP_FLOW", "true"
-            buildConfigField "boolean", "ENABLE_SITE_CREATION_DOMAIN_PURCHASING", "false"

             manifestPlaceholders = [magicLinkScheme:"wordpress"]
         }
@@ -209,7 +207,6 @@ android {
             buildConfigField "String", "PUSH_NOTIFICATIONS_APP_KEY", '"com.jetpack.android"'
             buildConfigField "boolean", "ENABLE_QRCODE_AUTH_FLOW", "true"
             buildConfigField "boolean", "ENABLE_OPEN_WEB_LINKS_WITH_JP_FLOW", "false"
-            buildConfigField "boolean", "ENABLE_SITE_CREATION_DOMAIN_PURCHASING", "false"

             manifestPlaceholders = [magicLinkScheme:"jetpack"]

diff --git a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainsRegistrationTracker.kt b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainsRegistrationTracker.kt
index a65e18a75ccf..a246a5d2d2ff 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainsRegistrationTracker.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainsRegistrationTracker.kt
@@ -3,14 +3,14 @@ package org.wordpress.android.ui.domains
 import org.wordpress.android.analytics.AnalyticsTracker
 import org.wordpress.android.fluxc.model.SiteModel
 import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
-import org.wordpress.android.util.config.SiteCreationDomainPurchasingFeatureConfig
+import org.wordpress.android.util.config.PlansInSiteCreationFeatureConfig
 import javax.inject.Inject
 import javax.inject.Singleton

 @Singleton
 class DomainsRegistrationTracker @Inject constructor(
     val tracker: AnalyticsTrackerWrapper,
-    private val purchasingFeatureConfig: SiteCreationDomainPurchasingFeatureConfig,
+    private val plansInSiteCreationFeatureConfig: PlansInSiteCreationFeatureConfig
 ) {
     private enum class PROPERTY(val key: String) {
         ORIGIN("origin"),
@@ -22,7 +22,7 @@ class DomainsRegistrationTracker @Inject constructor(
     }

     fun trackDomainsPurchaseWebviewViewed(site: SiteModel?, isSiteCreation: Boolean) {
-        if (purchasingFeatureConfig.isEnabledOrManuallyOverridden()) {
+        if (plansInSiteCreationFeatureConfig.isEnabled()) {
             val origin = if (isSiteCreation) VALUE.ORIGIN_SITE_CREATION.key else VALUE.ORIGIN_MENU.key
             tracker.track(
                 AnalyticsTracker.Stat.DOMAINS_PURCHASE_WEBVIEW_VIEWED, site, mutableMapOf(PROPERTY.ORIGIN.key to origin)
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModel.kt
index 8fad81d3aaf5..5143e65b36c6 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModel.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModel.kt
@@ -47,7 +47,7 @@ import org.wordpress.android.ui.utils.UiString.UiStringRes
 import org.wordpress.android.ui.utils.UiString.UiStringText
 import org.wordpress.android.util.AppLog
 import org.wordpress.android.util.NetworkUtilsWrapper
-import org.wordpress.android.util.config.SiteCreationDomainPurchasingFeatureConfig
+import org.wordpress.android.util.config.PlansInSiteCreationFeatureConfig
 import org.wordpress.android.util.extensions.isOnSale
 import org.wordpress.android.viewmodel.SingleLiveEvent
 import javax.inject.Inject
@@ -65,7 +65,7 @@ class SiteCreationDomainsViewModel @Inject constructor(
     private val domainSanitizer: SiteCreationDomainSanitizer,
     private val fetchDomainsUseCase: FetchDomainsUseCase,
     private val productsStore: ProductsStore,
-    private val purchasingFeatureConfig: SiteCreationDomainPurchasingFeatureConfig,
+    private val plansInSiteCreationFeatureConfig: PlansInSiteCreationFeatureConfig,
     private val tracker: SiteCreationTracker,
     @Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher,
     @Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher
@@ -111,7 +111,7 @@ class SiteCreationDomainsViewModel @Inject constructor(
         isStarted = true
         tracker.trackDomainsAccessed()
         resetUiState()
-        if (purchasingFeatureConfig.isEnabledOrManuallyOverridden()) fetchAndCacheProducts()
+        if (plansInSiteCreationFeatureConfig.isEnabled()) fetchAndCacheProducts()
     }

     private fun fetchAndCacheProducts() {
@@ -178,7 +178,7 @@ class SiteCreationDomainsViewModel @Inject constructor(
     }

     private suspend fun fetchDomainsByPurchasingFeatureConfig(query: String): OnSuggestedDomains {
-        val onlyWordpressCom = !purchasingFeatureConfig.isEnabledOrManuallyOverridden()
+        val onlyWordpressCom = !plansInSiteCreationFeatureConfig.isEnabled()
         val vendor = if (onlyWordpressCom) FETCH_DOMAINS_VENDOR_DOT else FETCH_DOMAINS_VENDOR_MOBILE

         return fetchDomainsUseCase.fetchDomains(query, vendor, onlyWordpressCom)
@@ -252,7 +252,7 @@ class SiteCreationDomainsViewModel @Inject constructor(
     }

     private fun getCreateSiteButtonState() = selectedDomain?.run {
-        when (purchasingFeatureConfig.isEnabledOrManuallyOverridden()) {
+        when (plansInSiteCreationFeatureConfig.isEnabled()) {
             true -> if (isFree) CreateSiteButtonState.Free else CreateSiteButtonState.Paid
             else -> CreateSiteButtonState.Old
         }
@@ -276,7 +276,7 @@ class SiteCreationDomainsViewModel @Inject constructor(
         return if (items.isEmpty()) {
             if (isNonEmptyUserQuery(query) && (state is Success || state is Ready)) {
                 DomainsUiContentState.Empty(emptyListMessage)
-            } else DomainsUiContentState.Initial(purchasingFeatureConfig.isEnabledOrManuallyOverridden())
+            } else DomainsUiContentState.Initial(plansInSiteCreationFeatureConfig.isEnabled())
         } else {
             DomainsUiContentState.VisibleItems(items)
         }
@@ -313,7 +313,7 @@ class SiteCreationDomainsViewModel @Inject constructor(
     }

     private fun createAvailableItemUiState(domain: DomainModel, index: Int): ListItemUiState {
-        return when (purchasingFeatureConfig.isEnabledOrManuallyOverridden()) {
+        return when (plansInSiteCreationFeatureConfig.isEnabled()) {
             true -> {
                 val product = products[domain.productId]
                 New.DomainUiState(
@@ -353,7 +353,7 @@ class SiteCreationDomainsViewModel @Inject constructor(
         domains: List<DomainModel>
     ): ListItemUiState? {
         if (domains.isEmpty()) return null
-        if (purchasingFeatureConfig.isEnabledOrManuallyOverridden()) return null // TODO: Add FQDN availability check
+        if (plansInSiteCreationFeatureConfig.isEnabled()) return null // TODO: Add FQDN availability check
         val sanitizedQuery = domainSanitizer.sanitizeDomainQuery(query)
         val isDomainUnavailable = domains.none { it.domainName.startsWith("$sanitizedQuery.") }
         return if (isDomainUnavailable) {
@@ -366,15 +366,13 @@ class SiteCreationDomainsViewModel @Inject constructor(
     }

     private fun createHeaderUiState(isVisible: Boolean) = if (!isVisible) null else
-        purchasingFeatureConfig.isEnabledOrManuallyOverridden().let { isPurchasingEnabled ->
-            SiteCreationHeaderUiState(
-                title = UiStringRes(R.string.new_site_creation_domain_header_title),
-                subtitle = UiStringRes(
-                    if (isPurchasingEnabled) R.string.site_creation_domain_header_subtitle
-                    else R.string.new_site_creation_domain_header_subtitle,
-                ),
-            )
-        }
+        SiteCreationHeaderUiState(
+            title = UiStringRes(R.string.new_site_creation_domain_header_title),
+            subtitle = UiStringRes(
+                if (plansInSiteCreationFeatureConfig.isEnabled()) R.string.site_creation_domain_header_subtitle
+                else R.string.new_site_creation_domain_header_subtitle,
+            ),
+        )

 private fun createSearchInputUiState(
         showProgress: Boolean,
@@ -382,7 +380,7 @@ private fun createSearchInputUiState(
         showDivider: Boolean,
     ): SiteCreationSearchInputUiState {
         val hint = UiStringRes(
-            if (purchasingFeatureConfig.isEnabledOrManuallyOverridden())
+            if (plansInSiteCreationFeatureConfig.isEnabled())
                 R.string.site_creation_domain_search_input_hint
             else
                 R.string.new_site_creation_search_domain_input_hint
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/misc/SiteCreationTracker.kt b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/misc/SiteCreationTracker.kt
index af0ecc0741a3..d33852fc0007 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/misc/SiteCreationTracker.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/misc/SiteCreationTracker.kt
@@ -16,7 +16,7 @@ import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker.PROPERTY.T
 import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker.PROPERTY.THUMBNAIL_MODE
 import org.wordpress.android.ui.sitecreation.misc.SiteCreationTracker.PROPERTY.VERTICAL_SLUG
 import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
-import org.wordpress.android.util.config.SiteCreationDomainPurchasingFeatureConfig
+import org.wordpress.android.util.config.PlansInSiteCreationFeatureConfig
 import javax.inject.Inject
 import javax.inject.Singleton

@@ -32,7 +32,7 @@ private const val SITE_CREATION_SOURCE = "source"
 @Singleton
 class SiteCreationTracker @Inject constructor(
     val tracker: AnalyticsTrackerWrapper,
-    private val purchasingFeatureConfig: SiteCreationDomainPurchasingFeatureConfig,
+    private val plansInSiteCreationFeatureConfig: PlansInSiteCreationFeatureConfig
 ) : LayoutPickerTracker {
     private enum class PROPERTY(val key: String) {
         TEMPLATE("template"),
@@ -63,7 +63,7 @@ class SiteCreationTracker @Inject constructor(
     }

     fun trackDomainSelected(chosenDomain: String, searchTerm: String, domainCost: String = "free") {
-        if(purchasingFeatureConfig.isEnabledOrManuallyOverridden()) {
+        if(plansInSiteCreationFeatureConfig.isEnabled()) {
             tracker.track(
                 AnalyticsTracker.Stat.ENHANCED_SITE_CREATION_DOMAINS_SELECTED,
                 mapOf(
diff --git a/WordPress/src/main/java/org/wordpress/android/util/config/SiteCreationDomainPurchasingFeatureConfig.kt b/WordPress/src/main/java/org/wordpress/android/util/config/SiteCreationDomainPurchasingFeatureConfig.kt
deleted file mode 100644
index da13b7b00260..000000000000
--- a/WordPress/src/main/java/org/wordpress/android/util/config/SiteCreationDomainPurchasingFeatureConfig.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.wordpress.android.util.config
-
-import org.wordpress.android.BuildConfig
-import org.wordpress.android.annotation.FeatureInDevelopment
-import org.wordpress.android.util.config.AppConfig.FeatureState.ManuallyOverriden
-import javax.inject.Inject
-
-@FeatureInDevelopment
-class SiteCreationDomainPurchasingFeatureConfig
-@Inject constructor(
-    appConfig: AppConfig,
-) : FeatureConfig(
-    appConfig,
-    BuildConfig.ENABLE_SITE_CREATION_DOMAIN_PURCHASING,
-) {
-    fun isEnabledOrManuallyOverridden() = (featureState() as? ManuallyOverriden)?.isEnabled ?: isEnabled()
-}

diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModelTest.kt
index 6d43f782cbab..e761a7ee74b3 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModelTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/domains/SiteCreationDomainsViewModelTest.kt
@@ -45,7 +45,7 @@ import org.wordpress.android.ui.sitecreation.usecases.FETCH_DOMAINS_VENDOR_MOBIL
 import org.wordpress.android.ui.sitecreation.usecases.FetchDomainsUseCase
 import org.wordpress.android.ui.utils.UiString.UiStringRes
 import org.wordpress.android.util.NetworkUtilsWrapper
-import org.wordpress.android.util.config.SiteCreationDomainPurchasingFeatureConfig
+import org.wordpress.android.util.config.PlansInSiteCreationFeatureConfig
 import kotlin.test.assertIs

 private const val MULTI_RESULT_DOMAIN_FETCH_RESULT_SIZE = 20
@@ -66,7 +66,7 @@ class SiteCreationDomainsViewModelTest : BaseUnitTest() {
     private lateinit var productsStore: ProductsStore

     @Mock
-    lateinit var purchasingFeatureConfig: SiteCreationDomainPurchasingFeatureConfig
+    lateinit var plansInSiteCreationFeatureConfig: PlansInSiteCreationFeatureConfig

     @Mock
     private lateinit var tracker: SiteCreationTracker
@@ -99,7 +99,7 @@ class SiteCreationDomainsViewModelTest : BaseUnitTest() {
             dispatcher = dispatcher,
             fetchDomainsUseCase = fetchDomainsUseCase,
             productsStore = productsStore,
-            purchasingFeatureConfig = purchasingFeatureConfig,
+            plansInSiteCreationFeatureConfig = plansInSiteCreationFeatureConfig,
             tracker = tracker,
             bgDispatcher = testDispatcher(),
             mainDispatcher = testDispatcher()
@@ -353,7 +353,7 @@ class SiteCreationDomainsViewModelTest : BaseUnitTest() {
     // region New UI

     private fun testNewUi(block: suspend CoroutineScope.() -> Unit) = test {
-        whenever(purchasingFeatureConfig.isEnabledOrManuallyOverridden()).thenReturn(true)
+        whenever(plansInSiteCreationFeatureConfig.isEnabled()).thenReturn(true)
         whenever(productsStore.fetchProducts(any())).thenReturn(mock())
         block()
     }


Fixes #19265

- [x] Merge https://github.com/wordpress-mobile/WordPress-FluxC-Android/pull/2864
- [x] Update FluxC reference to `trunk`

This makes the project compatible with the FluxC change. `CreateShoppingCartPayload` was deprecated in the FluxC PR, and this PR changes it with `CreateShoppingCartWithDomainAndPlanPayload`.

This PR shouldn't introduce any behavior change. This only adds the ability to add plans to the cart, but the plan selection screen will be added with another PR.

To test:
### Regression test for domain purchasing
1. Enable Plans in Site Creation feature flag
2. Select Site Picker
3. Create new WordPress.com site
4. Select a paid domain
5. Finish creating a site
6. Confirm that the domain exists in the cart

### Test the FluxC change (adding plans to the cart)
- Manually add `planProductId = 1009` into [createCartUseCase.execute(...](https://github.com/wordpress-mobile/WordPress-Android/blob/d7ef92147051ff914261550cbd6df9ceb7a4d636/WordPress/src/main/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModel.kt#L204) in `SiteCreationProgressViewModel`.
1. Enable Plans in Site Creation feature flag
2. Select Site Picker
4. Create new WordPress.com site
5. Select a free or paid domain
6. Finish creating a site
7. Confirm that plan exists in the cart (Notice that the personal plan was added to the cart in the video below)

https://github.com/wordpress-mobile/WordPress-Android/assets/2471769/4d55da75-214e-4ad1-8775-74ff66d1629b

## Regression Notes
1. Potential unintended areas of impact
Current domain purchasing feature.

2. What I did to test those areas of impact (or what existing automated tests I relied on)
Tested manually.

3. What automated tests I added (or what prevented me from doing so)
None. Because this doesn't introduce a new behavior.

PR submission checklist:

- [x] I have completed the Regression Notes.
- [x] I have considered adding accessibility improvements for my changes.
- [x] I have considered if this change warrants user-facing release notes and have added them to `RELEASE-NOTES.txt` if necessary.

UI Changes testing checklist:

- [ ] Portrait and landscape orientations.
- [ ] Light and dark modes.
- [ ] Fonts: Larger, smaller and bold text.
- [ ] High contrast.
- [ ] Talkback.
- [ ] Languages with large words or with letters/accents not frequently used in English.
- [ ] Right-to-left languages. (Even if translation isn’t complete, formatting should still respect the right-to-left layout)
- [ ] Large and small screen sizes. (Tablet and smaller phones)
- [ ] Multi-tasking: Split screen and Pop-up view. (Android 10 or higher)

Plans in Site Creation: Create functionality to add domain with a plan to a cart
Create functionality to add domain together with a plan via `me/shopping-cart/siteID` endpoint.

We can pass a plan and a domain objects to a `products` parameter in this format:

```
products: [
    {
      product_id: 1003
    },
    {
      product_id: 6
      meta: "someDomain.com"
    },
]
```

See iOS issue for more details: https://github.com/wordpress-mobile/WordPress-iOS/issues/21636

diff --git a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainRegistrationDetailsViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainRegistrationDetailsViewModel.kt
index 98d36051a627..bf5d598e19ea 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainRegistrationDetailsViewModel.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/domains/DomainRegistrationDetailsViewModel.kt
@@ -24,7 +24,6 @@ import org.wordpress.android.fluxc.store.SiteStore.OnDomainSupportedStatesFetche
 import org.wordpress.android.fluxc.store.SiteStore.OnPrimaryDomainDesignated
 import org.wordpress.android.fluxc.store.SiteStore.OnSiteChanged
 import org.wordpress.android.fluxc.store.TransactionsStore
-import org.wordpress.android.fluxc.store.TransactionsStore.CreateShoppingCartPayload
 import org.wordpress.android.fluxc.store.TransactionsStore.OnShoppingCartCreated
 import org.wordpress.android.fluxc.store.TransactionsStore.OnShoppingCartRedeemed
 import org.wordpress.android.fluxc.store.TransactionsStore.OnSupportedCountriesFetched
@@ -326,8 +325,8 @@ class DomainRegistrationDetailsViewModel @Inject constructor(
             state = uiState.value?.selectedState?.code
         )
         dispatcher.dispatch(
-            TransactionActionBuilder.newCreateShoppingCartAction(
-                CreateShoppingCartPayload(
+            TransactionActionBuilder.newCreateShoppingCartWithDomainAndPlanAction(
+                TransactionsStore.CreateShoppingCartWithDomainAndPlanPayload(
                     site,
                     domainProductDetails.productId,
                     domainProductDetails.domainName,
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/domains/usecases/CreateCartUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/domains/usecases/CreateCartUseCase.kt
index 362e94696e4e..e1fe40165076 100644
--- a/WordPress/src/main/java/org/wordpress/android/ui/domains/usecases/CreateCartUseCase.kt
+++ b/WordPress/src/main/java/org/wordpress/android/ui/domains/usecases/CreateCartUseCase.kt
@@ -5,7 +5,6 @@ import org.wordpress.android.fluxc.Dispatcher
 import org.wordpress.android.fluxc.generated.TransactionActionBuilder
 import org.wordpress.android.fluxc.model.SiteModel
 import org.wordpress.android.fluxc.store.TransactionsStore
-import org.wordpress.android.fluxc.store.TransactionsStore.CreateShoppingCartPayload
 import org.wordpress.android.fluxc.store.TransactionsStore.OnShoppingCartCreated
 import javax.inject.Inject
 import kotlin.coroutines.Continuation
@@ -32,18 +31,26 @@ class CreateCartUseCase @Inject constructor(
     @Suppress("UseCheckOrError")
     suspend fun execute(
         site: SiteModel,
-        productId: Int,
+        domainProductId: Int,
         domainName: String,
-        isPrivacyEnabled: Boolean,
-        isTemporary: Boolean
+        isDomainPrivacyEnabled: Boolean,
+        isTemporary: Boolean,
+        planProductId: Int? = null
     ): OnShoppingCartCreated {
         if (continuation != null) {
             throw IllegalStateException("Cart creation is already in progress!")
         }
         return suspendCoroutine {
             continuation = it
-            val payload = CreateShoppingCartPayload(site, productId, domainName, isPrivacyEnabled, isTemporary)
-            dispatcher.dispatch(TransactionActionBuilder.newCreateShoppingCartAction(payload))
+            val payload = TransactionsStore.CreateShoppingCartWithDomainAndPlanPayload(
+                site,
+                domainProductId,
+                domainName,
+                isDomainPrivacyEnabled,
+                planProductId,
+                isTemporary
+            )
+            dispatcher.dispatch(TransactionActionBuilder.newCreateShoppingCartWithDomainAndPlanAction(payload))
         }
     }

diff --git a/build.gradle b/build.gradle
index a98e8623b87c..2e47034981c5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -22,7 +22,7 @@ ext {
     automatticTracksVersion = '3.3.0'
     gutenbergMobileVersion = 'v1.105.0'
     wordPressAztecVersion = 'v1.8.0'
-    wordPressFluxCVersion = 'trunk-55122d0f327b24441003653dcfe7d3cd03bc7972'
+    wordPressFluxCVersion = 'trunk-f3ba57a9f1d9be24a4f43f929c6d98bfd8539df2'
     wordPressLoginVersion = '1.6.0'
     wordPressPersistentEditTextVersion = '1.0.2'
     wordPressUtilsVersion = '3.10.0'

diff --git a/WordPress/src/test/java/org/wordpress/android/ui/domains/DomainRegistrationDetailsViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/domains/DomainRegistrationDetailsViewModelTest.kt
index 6bbe25cc3b7a..8d71993756e9 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/domains/DomainRegistrationDetailsViewModelTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/domains/DomainRegistrationDetailsViewModelTest.kt
@@ -46,7 +46,7 @@ import org.wordpress.android.fluxc.store.SiteStore.SiteErrorType
 import org.wordpress.android.fluxc.store.TransactionsStore
 import org.wordpress.android.fluxc.store.TransactionsStore.CreateCartErrorType.GENERIC_ERROR
 import org.wordpress.android.fluxc.store.TransactionsStore.CreateShoppingCartError
-import org.wordpress.android.fluxc.store.TransactionsStore.CreateShoppingCartPayload
+import org.wordpress.android.fluxc.store.TransactionsStore.CreateShoppingCartWithDomainAndPlanPayload
 import org.wordpress.android.fluxc.store.TransactionsStore.FetchSupportedCountriesError
 import org.wordpress.android.fluxc.store.TransactionsStore.FetchSupportedCountriesErrorType
 import org.wordpress.android.fluxc.store.TransactionsStore.OnShoppingCartCreated
@@ -702,7 +702,7 @@ class DomainRegistrationDetailsViewModelTest : BaseUnitTest() {
             OnShoppingCartCreated(createShoppingCartResponse)
         }
         whenever(dispatcher.dispatch(argWhere<Action<Void>> {
-            it.type == TransactionAction.CREATE_SHOPPING_CART
+            it.type == TransactionAction.CREATE_SHOPPING_CART_WITH_DOMAIN_AND_PLAN
         })).then {
             viewModel.onShoppingCartCreated(event)
         }
@@ -759,15 +759,15 @@ class DomainRegistrationDetailsViewModelTest : BaseUnitTest() {
     }

     private fun validateCreateCartAction(action: Action<*>) {
-        assertThat(action.type).isEqualTo(TransactionAction.CREATE_SHOPPING_CART)
+        assertThat(action.type).isEqualTo(TransactionAction.CREATE_SHOPPING_CART_WITH_DOMAIN_AND_PLAN)
         assertThat(action.payload).isNotNull
-        assertThat(action.payload).isInstanceOf(CreateShoppingCartPayload::class.java)
+        assertThat(action.payload).isInstanceOf(CreateShoppingCartWithDomainAndPlanPayload::class.java)

-        val createShoppingCartPayload = action.payload as CreateShoppingCartPayload
+        val createShoppingCartPayload = action.payload as CreateShoppingCartWithDomainAndPlanPayload
         assertThat(createShoppingCartPayload.site).isEqualTo(site)
         assertThat(createShoppingCartPayload.domainName).isEqualTo(testDomainName)
-        assertThat(createShoppingCartPayload.productId).isEqualTo(productId)
-        assertThat(createShoppingCartPayload.isPrivacyEnabled).isEqualTo(true)
+        assertThat(createShoppingCartPayload.domainProductId).isEqualTo(productId)
+        assertThat(createShoppingCartPayload.isDomainPrivacyEnabled).isEqualTo(true)
     }

     private fun validateRedeemCartAction(action: Action<*>) {
diff --git a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModelTest.kt
index 6b3a33ae7d9e..2be76a5a723c 100644
--- a/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModelTest.kt
+++ b/WordPress/src/test/java/org/wordpress/android/ui/sitecreation/progress/SiteCreationProgressViewModelTest.kt
@@ -9,6 +9,7 @@ import org.assertj.core.api.Assertions.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.nullable
 import org.mockito.junit.MockitoJUnitRunner
 import org.mockito.kotlin.any
 import org.mockito.kotlin.argThat
@@ -168,7 +169,7 @@ class SiteCreationProgressViewModelTest : BaseUnitTest() {
         startViewModel(SITE_CREATION_STATE.copy(domain = PAID_DOMAIN))
         viewModel.onSiteCreationServiceStateUpdated(SERVICE_SUCCESS)
         viewModel.retry()
-        verify(createCartUseCase, times(2)).execute(any(), any(), any(), any(), eq(false))
+        verify(createCartUseCase, times(2)).execute(any(), any(), any(), any(), eq(false), nullable(Int::class.java))
     }

     @Test
@@ -205,6 +206,7 @@ class SiteCreationProgressViewModelTest : BaseUnitTest() {
             eq(PAID_DOMAIN.domainName),
             eq(PAID_DOMAIN.supportsPrivacy),
             any(),
+            nullable(Int::class.java)
         )
     }

@@ -248,7 +250,8 @@ class SiteCreationProgressViewModelTest : BaseUnitTest() {
             eq(PAID_DOMAIN.productId),
             eq(PAID_DOMAIN.domainName),
             eq(PAID_DOMAIN.supportsPrivacy),
-            any()
+            any(),
+            nullable(Int::class.java)
         )
     }

@@ -288,7 +291,16 @@ class SiteCreationProgressViewModelTest : BaseUnitTest() {

     // region Helpers
     private fun testWith(response: OnShoppingCartCreated, block: suspend CoroutineScope.() -> Unit) = test {
-        whenever(createCartUseCase.execute(any(), any(), any(), any(), any())).thenReturn(response)
+        whenever(
+            createCartUseCase.execute(
+                any(),
+                any(),
+                any(),
+                any(),
+                any(),
+                nullable(Int::class.java)
+            )
+        ).thenReturn(response)
         block()
     }