Skip to content

Commit 8ff1609

Browse files
authored
Add network tests for saving a new card and setting it as the default PM (#10357)
* Add network tests for saving a new card and setting it as the default PM * Fix merge conflicts * Remove need to get card metadata * Fix lint issue
1 parent 6861292 commit 8ff1609

File tree

4 files changed

+127
-9
lines changed

4 files changed

+127
-9
lines changed

payments-ui-core/src/main/java/com/stripe/android/ui/core/elements/SetAsDefaultPaymentMethodElementUI.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import androidx.compose.ui.platform.LocalContext
88
import com.stripe.android.uicore.elements.CheckboxElementUI
99
import com.stripe.android.uicore.utils.collectAsState
1010

11-
internal const val SET_AS_DEFAULT_PAYMENT_METHOD_TEST_TAG = "SET_AS_DEFAULT_PAYMENT_METHOD_TEST_TAG"
11+
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
12+
const val SET_AS_DEFAULT_PAYMENT_METHOD_TEST_TAG = "SET_AS_DEFAULT_PAYMENT_METHOD_TEST_TAG"
1213

1314
@Composable
1415
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)

paymentsheet/src/androidTest/java/com/stripe/android/paymentsheet/DefaultPaymentMethodsTest.kt

+110-6
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@ import androidx.compose.ui.test.hasTestTag
55
import androidx.test.core.app.ApplicationProvider
66
import com.google.testing.junit.testparameterinjector.TestParameter
77
import com.google.testing.junit.testparameterinjector.TestParameterInjector
8+
import com.stripe.android.core.utils.urlEncode
89
import com.stripe.android.model.PaymentMethod
910
import com.stripe.android.networktesting.RequestMatchers
11+
import com.stripe.android.networktesting.RequestMatchers.bodyPart
12+
import com.stripe.android.networktesting.RequestMatchers.method
13+
import com.stripe.android.networktesting.RequestMatchers.path
14+
import com.stripe.android.networktesting.testBodyFromFile
1015
import com.stripe.android.paymentsheet.ui.SAVED_PAYMENT_OPTION_TAB_LAYOUT_TEST_TAG
1116
import com.stripe.android.paymentsheet.utils.PaymentSheetLayoutType
1217
import com.stripe.android.paymentsheet.utils.PaymentSheetLayoutTypeProvider
1318
import com.stripe.android.paymentsheet.utils.ProductIntegrationTestRunnerContext
1419
import com.stripe.android.paymentsheet.utils.ProductIntegrationType
1520
import com.stripe.android.paymentsheet.utils.ProductIntegrationTypeProvider
1621
import com.stripe.android.paymentsheet.utils.TestRules
22+
import com.stripe.android.paymentsheet.utils.assertCompleted
1723
import com.stripe.android.paymentsheet.utils.runProductIntegrationTest
1824
import com.stripe.android.testing.PaymentMethodFactory
1925
import org.json.JSONArray
@@ -164,8 +170,106 @@ internal class DefaultPaymentMethodsTest {
164170
testContext.markTestSucceeded()
165171
}
166172

173+
@Test
174+
fun setNewCardAsDefault_sendsSetAsDefaultParamInConfirmCall() = runProductIntegrationTest(
175+
networkRule = networkRule,
176+
integrationType = integrationType,
177+
resultCallback = ::assertCompleted,
178+
) { testContext ->
179+
val paymentSheetPage = PaymentSheetPage(composeTestRule)
180+
181+
enqueueElementsSessionResponse()
182+
183+
launch(
184+
testContext = testContext,
185+
paymentMethodLayout = layoutType.paymentMethodLayout,
186+
hasSavedPaymentMethods = false,
187+
)
188+
189+
paymentSheetPage.fillOutCardDetails()
190+
paymentSheetPage.checkSaveForFuture()
191+
paymentSheetPage.checkSetAsDefaultCheckbox()
192+
193+
enqueuePaymentIntentConfirmWithExpectedSetAsDefault(setAsDefaultValue = true)
194+
195+
paymentSheetPage.clickPrimaryButton()
196+
}
197+
198+
@Test
199+
fun payWithNewCard_dontCheckSetAsDefault_sendsSetAsDefaultAsFalseParamInConfirmCall() = runProductIntegrationTest(
200+
networkRule = networkRule,
201+
integrationType = integrationType,
202+
resultCallback = ::assertCompleted,
203+
) { testContext ->
204+
val paymentSheetPage = PaymentSheetPage(composeTestRule)
205+
206+
enqueueElementsSessionResponse()
207+
208+
launch(
209+
testContext = testContext,
210+
paymentMethodLayout = layoutType.paymentMethodLayout,
211+
hasSavedPaymentMethods = false,
212+
)
213+
214+
paymentSheetPage.fillOutCardDetails()
215+
paymentSheetPage.checkSaveForFuture()
216+
217+
enqueuePaymentIntentConfirmWithExpectedSetAsDefault(setAsDefaultValue = false)
218+
219+
paymentSheetPage.clickPrimaryButton()
220+
}
221+
222+
@Test
223+
fun payWithNewCard_uncheckSaveForFuture_doesNotSendSetAsDefaultInConfirmCall() = runProductIntegrationTest(
224+
networkRule = networkRule,
225+
integrationType = integrationType,
226+
resultCallback = ::assertCompleted,
227+
) { testContext ->
228+
val paymentSheetPage = PaymentSheetPage(composeTestRule)
229+
230+
enqueueElementsSessionResponse()
231+
232+
launch(
233+
testContext = testContext,
234+
paymentMethodLayout = layoutType.paymentMethodLayout,
235+
hasSavedPaymentMethods = false,
236+
)
237+
238+
paymentSheetPage.fillOutCardDetails()
239+
paymentSheetPage.checkSaveForFuture()
240+
paymentSheetPage.checkSetAsDefaultCheckbox()
241+
242+
// Un-check save for future -- this will hide the set as default checkbox
243+
paymentSheetPage.checkSaveForFuture()
244+
245+
enqueuePaymentIntentConfirmWithoutSetAsDefault()
246+
247+
paymentSheetPage.clickPrimaryButton()
248+
}
249+
250+
private fun enqueuePaymentIntentConfirmWithoutSetAsDefault() {
251+
return networkRule.enqueue(
252+
method("POST"),
253+
path("/v1/payment_intents/pi_example/confirm"),
254+
bodyPart(urlEncode("payment_method_data[allow_redisplay]"), "unspecified"),
255+
) { response ->
256+
response.testBodyFromFile("payment-intent-confirm.json")
257+
}
258+
}
259+
260+
private fun enqueuePaymentIntentConfirmWithExpectedSetAsDefault(setAsDefaultValue: Boolean) {
261+
return networkRule.enqueue(
262+
method("POST"),
263+
path("/v1/payment_intents/pi_example/confirm"),
264+
bodyPart(urlEncode("payment_method_data[allow_redisplay]"), "always"),
265+
bodyPart(urlEncode("set_as_default_payment_method"), setAsDefaultValue.toString())
266+
) { response ->
267+
response.testBodyFromFile("payment-intent-confirm.json")
268+
}
269+
}
270+
167271
private fun enqueueElementsSessionResponse(
168-
cards: List<PaymentMethod>,
272+
cards: List<PaymentMethod> = emptyList(),
169273
setAsDefaultFeatureEnabled: Boolean = true,
170274
defaultPaymentMethod: String? = null,
171275
) {
@@ -187,6 +291,7 @@ internal class DefaultPaymentMethodsTest {
187291
private fun launch(
188292
testContext: ProductIntegrationTestRunnerContext,
189293
paymentMethodLayout: PaymentSheet.PaymentMethodLayout,
294+
hasSavedPaymentMethods: Boolean = true,
190295
) {
191296
testContext.launch(
192297
configuration = PaymentSheet.Configuration(
@@ -199,7 +304,10 @@ internal class DefaultPaymentMethodsTest {
199304
),
200305
)
201306

202-
if (paymentMethodLayout == PaymentSheet.PaymentMethodLayout.Horizontal) {
307+
if (
308+
paymentMethodLayout == PaymentSheet.PaymentMethodLayout.Horizontal &&
309+
hasSavedPaymentMethods
310+
) {
203311
composeTestRule.waitUntil(timeoutMillis = 5_000) {
204312
composeTestRule
205313
.onAllNodes(hasTestTag(SAVED_PAYMENT_OPTION_TAB_LAYOUT_TEST_TAG))
@@ -238,10 +346,6 @@ internal class DefaultPaymentMethodsTest {
238346
"ordered_payment_method_types_and_wallets": [
239347
"card"
240348
],
241-
"card_brand_choice": {
242-
"eligible": true,
243-
"preferred_networks": ["cartes_bancaires"]
244-
},
245349
"customer": {
246350
"payment_methods": $cardsStringified,
247351
"customer_session": {

paymentsheet/src/androidTest/java/com/stripe/android/paymentsheet/PaymentSheetPage.kt

+13
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import androidx.compose.ui.test.hasText
1313
import androidx.compose.ui.test.isEnabled
1414
import androidx.compose.ui.test.isSelected
1515
import androidx.compose.ui.test.junit4.ComposeTestRule
16+
import androidx.compose.ui.test.onAllNodesWithTag
1617
import androidx.compose.ui.test.onNodeWithTag
1718
import androidx.compose.ui.test.onNodeWithText
1819
import androidx.compose.ui.test.onParent
@@ -30,6 +31,7 @@ import com.stripe.android.paymentsheet.ui.TEST_TAG_LIST
3031
import com.stripe.android.paymentsheet.verticalmode.TEST_TAG_NEW_PAYMENT_METHOD_ROW_BUTTON
3132
import com.stripe.android.paymentsheet.verticalmode.TEST_TAG_PAYMENT_METHOD_VERTICAL_LAYOUT
3233
import com.stripe.android.ui.core.elements.SAVE_FOR_FUTURE_CHECKBOX_TEST_TAG
34+
import com.stripe.android.ui.core.elements.SET_AS_DEFAULT_PAYMENT_METHOD_TEST_TAG
3335
import com.stripe.android.uicore.elements.DROPDOWN_MENU_CLICKABLE_TEST_TAG
3436

3537
internal class PaymentSheetPage(
@@ -219,6 +221,17 @@ internal class PaymentSheetPage(
219221
.performClick()
220222
}
221223

224+
fun checkSetAsDefaultCheckbox() {
225+
composeTestRule.waitUntil {
226+
composeTestRule.onAllNodesWithTag(
227+
SET_AS_DEFAULT_PAYMENT_METHOD_TEST_TAG
228+
).fetchSemanticsNodes().isNotEmpty()
229+
}
230+
composeTestRule.onNode(hasTestTag(SET_AS_DEFAULT_PAYMENT_METHOD_TEST_TAG))
231+
.performScrollTo()
232+
.performClick()
233+
}
234+
222235
fun clickOnLpm(code: String, forVerticalMode: Boolean = false) {
223236
if (forVerticalMode) {
224237
composeTestRule.waitUntil {

paymentsheet/src/androidTest/java/com/stripe/android/paymentsheet/utils/PaymentSheetLayoutType.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ internal sealed class PaymentSheetLayoutType(val paymentMethodLayout: PaymentShe
3030

3131
abstract fun setDefaultPaymentMethod(
3232
composeTestRule: ComposeTestRule,
33-
newDefaultPaymentMethod: PaymentMethod
33+
newDefaultPaymentMethod: PaymentMethod,
3434
)
3535

3636
abstract fun assertDefaultPaymentMethodBadgeDisplayed(
37-
composeTestRule: ComposeTestRule
37+
composeTestRule: ComposeTestRule,
3838
)
3939

4040
class Horizontal : PaymentSheetLayoutType(paymentMethodLayout = PaymentSheet.PaymentMethodLayout.Horizontal) {

0 commit comments

Comments
 (0)