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

Issue:
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


Discussion hints:

Pull request: Plans in Site Creation: Create functionality to add domain with a plan to a cart
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)


Test command: ./gradlew :WordPress:testWordpressVanillaDebugUnitTest --tests "org.wordpress.android.ui.domains.DomainRegistrationDetailsViewModelTest" --tests "org.wordpress.android.ui.sitecreation.progress.SiteCreationProgressViewModelTest"

Fix patch:
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'


Test patch:
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()
     }