@stripe/stripe-react-native 0.58.0 → 0.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +2 -0
- package/android/src/main/AndroidManifest.xml +27 -1
- package/android/src/main/java/com/reactnativestripesdk/EmbeddedPaymentElementViewManager.kt +2 -0
- package/android/src/main/java/com/reactnativestripesdk/EventEmitterCompat.kt +8 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentElementConfig.kt +8 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfig.kt +147 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementView.kt +164 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentMethodMessagingElementViewManager.kt +65 -0
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetAppearance.kt +1 -1
- package/android/src/main/java/com/reactnativestripesdk/PaymentSheetManager.kt +55 -26
- package/android/src/main/java/com/reactnativestripesdk/StripeConnectDeepLinkInterceptorActivity.kt +77 -0
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkModule.kt +325 -22
- package/android/src/main/java/com/reactnativestripesdk/StripeSdkPackage.kt +1 -0
- package/android/src/main/java/com/reactnativestripesdk/customersheet/CustomerSheetManager.kt +3 -0
- package/android/src/main/java/com/reactnativestripesdk/utils/Errors.kt +8 -0
- package/android/src/main/res/xml/file_paths.xml +4 -0
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/PaymentMethodMessagingElementViewManagerDelegate.java +36 -0
- package/android/src/oldarch/java/com/facebook/react/viewmanagers/PaymentMethodMessagingElementViewManagerInterface.java +18 -0
- package/android/src/oldarch/java/com/reactnativestripesdk/NativeStripeSdkModuleSpec.java +20 -0
- package/android/src/test/java/com/reactnativestripesdk/PaymentElementConfigTest.kt +37 -0
- package/android/src/test/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfigTest.kt +543 -0
- package/android/src/test/java/com/reactnativestripesdk/PaymentSheetManagerTest.kt +70 -0
- package/ios/CustomerSheet/CustomerSheetUtils.swift +4 -0
- package/ios/OldArch/StripeSdkEventEmitterCompat.h +2 -0
- package/ios/OldArch/StripeSdkEventEmitterCompat.m +13 -1
- package/ios/PaymentMethodMessagingElementConfig.swift +116 -0
- package/ios/PaymentMethodMessagingElementHandler.m +9 -0
- package/ios/PaymentMethodMessagingElementView.swift +139 -0
- package/ios/StripeSdk.mm +40 -0
- package/ios/StripeSdkEmitter.swift +2 -0
- package/ios/StripeSdkImpl+CustomerSheet.swift +1 -0
- package/ios/StripeSdkImpl+Embedded.swift +4 -0
- package/ios/StripeSdkImpl+PaymentSheet.swift +16 -0
- package/ios/StripeSdkImpl.swift +132 -0
- package/jest/mock.js +20 -0
- package/lib/commonjs/connect/Components.js.map +1 -1
- package/lib/commonjs/connect/ConnectComponentsProvider.js +1 -1
- package/lib/commonjs/connect/ConnectComponentsProvider.js.map +1 -1
- package/lib/commonjs/connect/EmbeddedComponent.js +5 -5
- package/lib/commonjs/connect/EmbeddedComponent.js.map +1 -1
- package/lib/commonjs/connect/analytics/AnalyticsClient.js +2 -0
- package/lib/commonjs/connect/analytics/AnalyticsClient.js.map +1 -0
- package/lib/commonjs/connect/analytics/ComponentAnalyticsClient.js +2 -0
- package/lib/commonjs/connect/analytics/ComponentAnalyticsClient.js.map +1 -0
- package/lib/commonjs/connect/analytics/events.js +2 -0
- package/lib/commonjs/connect/analytics/events.js.map +1 -0
- package/lib/commonjs/connect/testUtils.js +2 -0
- package/lib/commonjs/connect/testUtils.js.map +1 -0
- package/lib/commonjs/events.js.map +1 -1
- package/lib/commonjs/functions.js +1 -1
- package/lib/commonjs/functions.js.map +1 -1
- package/lib/commonjs/hooks/useStripe.js +1 -1
- package/lib/commonjs/hooks/useStripe.js.map +1 -1
- package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js +2 -0
- package/lib/commonjs/specs/NativePaymentMethodMessagingElement.js.map +1 -0
- package/lib/commonjs/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/commonjs/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/commonjs/types/Errors.js +1 -1
- package/lib/commonjs/types/Errors.js.map +1 -1
- package/lib/commonjs/types/PaymentSheet.js.map +1 -1
- package/lib/commonjs/types/components/PaymentMethodMessagingElementComponent.js +2 -0
- package/lib/commonjs/types/components/PaymentMethodMessagingElementComponent.js.map +1 -0
- package/lib/commonjs/types/index.js.map +1 -1
- package/lib/module/connect/Components.js.map +1 -1
- package/lib/module/connect/ConnectComponentsProvider.js +1 -1
- package/lib/module/connect/ConnectComponentsProvider.js.map +1 -1
- package/lib/module/connect/EmbeddedComponent.js +5 -5
- package/lib/module/connect/EmbeddedComponent.js.map +1 -1
- package/lib/module/connect/analytics/AnalyticsClient.js +2 -0
- package/lib/module/connect/analytics/AnalyticsClient.js.map +1 -0
- package/lib/module/connect/analytics/ComponentAnalyticsClient.js +2 -0
- package/lib/module/connect/analytics/ComponentAnalyticsClient.js.map +1 -0
- package/lib/module/connect/analytics/events.js +2 -0
- package/lib/module/connect/analytics/events.js.map +1 -0
- package/lib/module/connect/testUtils.js +2 -0
- package/lib/module/connect/testUtils.js.map +1 -0
- package/lib/module/events.js.map +1 -1
- package/lib/module/functions.js +1 -1
- package/lib/module/functions.js.map +1 -1
- package/lib/module/hooks/useStripe.js +1 -1
- package/lib/module/hooks/useStripe.js.map +1 -1
- package/lib/module/specs/NativePaymentMethodMessagingElement.js +2 -0
- package/lib/module/specs/NativePaymentMethodMessagingElement.js.map +1 -0
- package/lib/module/specs/NativeStripeSdkModule.js.map +1 -1
- package/lib/module/types/EmbeddedPaymentElement.js.map +1 -1
- package/lib/module/types/Errors.js +1 -1
- package/lib/module/types/Errors.js.map +1 -1
- package/lib/module/types/PaymentSheet.js.map +1 -1
- package/lib/module/types/components/PaymentMethodMessagingElementComponent.js +2 -0
- package/lib/module/types/components/PaymentMethodMessagingElementComponent.js.map +1 -0
- package/lib/module/types/index.js.map +1 -1
- package/lib/typescript/src/connect/Components.d.ts +91 -0
- package/lib/typescript/src/connect/Components.d.ts.map +1 -1
- package/lib/typescript/src/connect/ConnectComponentsProvider.d.ts +61 -0
- package/lib/typescript/src/connect/ConnectComponentsProvider.d.ts.map +1 -1
- package/lib/typescript/src/connect/EmbeddedComponent.d.ts.map +1 -1
- package/lib/typescript/src/connect/analytics/AnalyticsClient.d.ts +32 -0
- package/lib/typescript/src/connect/analytics/AnalyticsClient.d.ts.map +1 -0
- package/lib/typescript/src/connect/analytics/ComponentAnalyticsClient.d.ts +94 -0
- package/lib/typescript/src/connect/analytics/ComponentAnalyticsClient.d.ts.map +1 -0
- package/lib/typescript/src/connect/analytics/events.d.ts +215 -0
- package/lib/typescript/src/connect/analytics/events.d.ts.map +1 -0
- package/lib/typescript/src/connect/testUtils.d.ts +45 -0
- package/lib/typescript/src/connect/testUtils.d.ts.map +1 -0
- package/lib/typescript/src/events.d.ts +2 -0
- package/lib/typescript/src/events.d.ts.map +1 -1
- package/lib/typescript/src/functions.d.ts +13 -1
- package/lib/typescript/src/functions.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useStripe.d.ts +2 -1
- package/lib/typescript/src/hooks/useStripe.d.ts.map +1 -1
- package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts +16 -0
- package/lib/typescript/src/specs/NativePaymentMethodMessagingElement.d.ts.map +1 -0
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts +16 -1
- package/lib/typescript/src/specs/NativeStripeSdkModule.d.ts.map +1 -1
- package/lib/typescript/src/types/CustomerSheet.d.ts +5 -0
- package/lib/typescript/src/types/CustomerSheet.d.ts.map +1 -1
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts +5 -0
- package/lib/typescript/src/types/EmbeddedPaymentElement.d.ts.map +1 -1
- package/lib/typescript/src/types/Errors.d.ts +4 -0
- package/lib/typescript/src/types/Errors.d.ts.map +1 -1
- package/lib/typescript/src/types/PaymentSheet.d.ts +5 -0
- package/lib/typescript/src/types/PaymentSheet.d.ts.map +1 -1
- package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts +69 -0
- package/lib/typescript/src/types/components/PaymentMethodMessagingElementComponent.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +8 -1
- package/lib/typescript/src/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/connect/Components.tsx +91 -0
- package/src/connect/ConnectComponentsProvider.tsx +69 -2
- package/src/connect/EmbeddedComponent.tsx +254 -30
- package/src/connect/analytics/AnalyticsClient.ts +75 -0
- package/src/connect/analytics/ComponentAnalyticsClient.ts +315 -0
- package/src/connect/analytics/events.ts +253 -0
- package/src/connect/testUtils.ts +37 -0
- package/src/events.ts +2 -0
- package/src/functions.ts +10 -0
- package/src/hooks/useStripe.tsx +8 -0
- package/src/specs/NativePaymentMethodMessagingElement.ts +25 -0
- package/src/specs/NativeStripeSdkModule.ts +21 -1
- package/src/types/CustomerSheet.ts +5 -0
- package/src/types/EmbeddedPaymentElement.tsx +5 -0
- package/src/types/Errors.ts +5 -0
- package/src/types/PaymentSheet.ts +6 -1
- package/src/types/components/PaymentMethodMessagingElementComponent.tsx +74 -0
- package/src/types/index.ts +11 -0
|
@@ -3,6 +3,7 @@ package com.reactnativestripesdk
|
|
|
3
3
|
import com.reactnativestripesdk.utils.PaymentSheetException
|
|
4
4
|
import com.reactnativestripesdk.utils.readableArrayOf
|
|
5
5
|
import com.reactnativestripesdk.utils.readableMapOf
|
|
6
|
+
import com.stripe.android.model.PaymentMethod
|
|
6
7
|
import com.stripe.android.paymentelement.PaymentMethodOptionsSetupFutureUsagePreview
|
|
7
8
|
import com.stripe.android.paymentsheet.CardFundingFilteringPrivatePreview
|
|
8
9
|
import com.stripe.android.paymentsheet.PaymentSheet
|
|
@@ -1098,6 +1099,42 @@ class PaymentElementConfigTest {
|
|
|
1098
1099
|
assertNull(result)
|
|
1099
1100
|
}
|
|
1100
1101
|
|
|
1102
|
+
// ============================================
|
|
1103
|
+
// computeTermsDisplayForUserKey Tests
|
|
1104
|
+
// ============================================
|
|
1105
|
+
|
|
1106
|
+
@Test
|
|
1107
|
+
fun computeTermsDisplayForUserKey_UserKey_ReturnsCardNever() {
|
|
1108
|
+
val result = computeTermsDisplayForUserKey("uk_test_123")
|
|
1109
|
+
assertEquals(1, result.size)
|
|
1110
|
+
assertEquals(PaymentSheet.TermsDisplay.NEVER, result[PaymentMethod.Type.Card])
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
@Test
|
|
1114
|
+
fun computeTermsDisplayForUserKey_LiveUserKey_ReturnsCardNever() {
|
|
1115
|
+
val result = computeTermsDisplayForUserKey("uk_live_456")
|
|
1116
|
+
assertEquals(1, result.size)
|
|
1117
|
+
assertEquals(PaymentSheet.TermsDisplay.NEVER, result[PaymentMethod.Type.Card])
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
@Test
|
|
1121
|
+
fun computeTermsDisplayForUserKey_PublishableKey_ReturnsEmpty() {
|
|
1122
|
+
val result = computeTermsDisplayForUserKey("pk_test_123")
|
|
1123
|
+
assertTrue(result.isEmpty())
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
@Test
|
|
1127
|
+
fun computeTermsDisplayForUserKey_LivePublishableKey_ReturnsEmpty() {
|
|
1128
|
+
val result = computeTermsDisplayForUserKey("pk_live_456")
|
|
1129
|
+
assertTrue(result.isEmpty())
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
@Test
|
|
1133
|
+
fun computeTermsDisplayForUserKey_EmptyKey_ReturnsEmpty() {
|
|
1134
|
+
val result = computeTermsDisplayForUserKey("")
|
|
1135
|
+
assertTrue(result.isEmpty())
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1101
1138
|
@Test
|
|
1102
1139
|
fun mapToAllowedCardFundingTypes_MissingAllowedCardFundingTypes_ReturnsNull() {
|
|
1103
1140
|
val params =
|
package/android/src/test/java/com/reactnativestripesdk/PaymentMethodMessagingElementConfigTest.kt
ADDED
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
@file:OptIn(PaymentMethodMessagingElementPreview::class)
|
|
2
|
+
|
|
3
|
+
package com.reactnativestripesdk
|
|
4
|
+
|
|
5
|
+
import android.content.Context
|
|
6
|
+
import androidx.core.graphics.toColorInt
|
|
7
|
+
import androidx.test.core.app.ApplicationProvider
|
|
8
|
+
import com.reactnativestripesdk.utils.PaymentMethodMessagingElementAppearanceException
|
|
9
|
+
import com.reactnativestripesdk.utils.PaymentMethodMessagingElementConfigurationException
|
|
10
|
+
import com.reactnativestripesdk.utils.readableArrayOf
|
|
11
|
+
import com.reactnativestripesdk.utils.readableMapOf
|
|
12
|
+
import com.stripe.android.model.PaymentMethod
|
|
13
|
+
import com.stripe.android.paymentmethodmessaging.element.PaymentMethodMessagingElement
|
|
14
|
+
import com.stripe.android.paymentmethodmessaging.element.PaymentMethodMessagingElementPreview
|
|
15
|
+
import org.junit.Assert.assertEquals
|
|
16
|
+
import org.junit.Assert.assertNotNull
|
|
17
|
+
import org.junit.Test
|
|
18
|
+
import org.junit.runner.RunWith
|
|
19
|
+
import org.robolectric.RobolectricTestRunner
|
|
20
|
+
|
|
21
|
+
@RunWith(RobolectricTestRunner::class)
|
|
22
|
+
class PaymentMethodMessagingElementConfigTest {
|
|
23
|
+
private val context: Context = ApplicationProvider.getApplicationContext()
|
|
24
|
+
|
|
25
|
+
// ============================================
|
|
26
|
+
// parseElementConfiguration Tests
|
|
27
|
+
// ============================================
|
|
28
|
+
|
|
29
|
+
@Test(expected = PaymentMethodMessagingElementConfigurationException::class)
|
|
30
|
+
fun parseElementConfiguration_EmptyMap_Throws_Exception() {
|
|
31
|
+
val params = readableMapOf()
|
|
32
|
+
|
|
33
|
+
parseElementConfiguration(params)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Test
|
|
37
|
+
fun parseElementConfiguration_WithAmountAndCurrency_Success() {
|
|
38
|
+
val params =
|
|
39
|
+
readableMapOf(
|
|
40
|
+
"amount" to 1000,
|
|
41
|
+
"currency" to "usd",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
val result = parseElementConfiguration(params)
|
|
45
|
+
|
|
46
|
+
val expected =
|
|
47
|
+
PaymentMethodMessagingElement
|
|
48
|
+
.Configuration()
|
|
49
|
+
.amount(1000)
|
|
50
|
+
.currency("usd")
|
|
51
|
+
|
|
52
|
+
checkEquals(expected, result)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@Test
|
|
56
|
+
fun parseElementConfiguration_WithLocale_Success() {
|
|
57
|
+
val params =
|
|
58
|
+
readableMapOf(
|
|
59
|
+
"amount" to 1000,
|
|
60
|
+
"currency" to "usd",
|
|
61
|
+
"locale" to "en_US",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
val result = parseElementConfiguration(params)
|
|
65
|
+
val expected =
|
|
66
|
+
PaymentMethodMessagingElement
|
|
67
|
+
.Configuration()
|
|
68
|
+
.amount(1000)
|
|
69
|
+
.currency("usd")
|
|
70
|
+
.locale("en_US")
|
|
71
|
+
|
|
72
|
+
checkEquals(expected, result)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@Test
|
|
76
|
+
fun parseElementConfiguration_WithCountry_Success() {
|
|
77
|
+
val params =
|
|
78
|
+
readableMapOf(
|
|
79
|
+
"amount" to 1000,
|
|
80
|
+
"currency" to "usd",
|
|
81
|
+
"country" to "US",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
val result = parseElementConfiguration(params)
|
|
85
|
+
val expected =
|
|
86
|
+
PaymentMethodMessagingElement
|
|
87
|
+
.Configuration()
|
|
88
|
+
.amount(1000)
|
|
89
|
+
.currency("usd")
|
|
90
|
+
.countryCode("US")
|
|
91
|
+
|
|
92
|
+
checkEquals(expected, result)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@Test
|
|
96
|
+
fun parseElementConfiguration_WithPaymentMethodTypes_Success() {
|
|
97
|
+
val params =
|
|
98
|
+
readableMapOf(
|
|
99
|
+
"amount" to 1000,
|
|
100
|
+
"currency" to "usd",
|
|
101
|
+
"paymentMethodTypes" to readableArrayOf("card", "klarna", "affirm"),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
val result = parseElementConfiguration(params)
|
|
105
|
+
val expected =
|
|
106
|
+
PaymentMethodMessagingElement
|
|
107
|
+
.Configuration()
|
|
108
|
+
.amount(1000)
|
|
109
|
+
.currency("usd")
|
|
110
|
+
.paymentMethodTypes(
|
|
111
|
+
listOf(PaymentMethod.Type.Card, PaymentMethod.Type.Klarna, PaymentMethod.Type.Affirm),
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
checkEquals(expected, result)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@Test
|
|
118
|
+
fun parseElementConfiguration_WithInvalidPaymentMethodTypes_FiltersInvalid() {
|
|
119
|
+
val params =
|
|
120
|
+
readableMapOf(
|
|
121
|
+
"amount" to 1000,
|
|
122
|
+
"currency" to "usd",
|
|
123
|
+
"paymentMethodTypes" to readableArrayOf("card", "invalid_type", "klarna"),
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
val result = parseElementConfiguration(params)
|
|
127
|
+
val expected =
|
|
128
|
+
PaymentMethodMessagingElement
|
|
129
|
+
.Configuration()
|
|
130
|
+
.amount(1000)
|
|
131
|
+
.currency("usd")
|
|
132
|
+
.paymentMethodTypes(
|
|
133
|
+
listOf(PaymentMethod.Type.Card, PaymentMethod.Type.Klarna),
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
checkEquals(expected, result)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@Test
|
|
140
|
+
fun parseElementConfiguration_CompleteConfiguration_Success() {
|
|
141
|
+
val params =
|
|
142
|
+
readableMapOf(
|
|
143
|
+
"amount" to 5000.0,
|
|
144
|
+
"currency" to "eur",
|
|
145
|
+
"locale" to "fr_FR",
|
|
146
|
+
"country" to "FR",
|
|
147
|
+
"paymentMethodTypes" to readableArrayOf("card", "klarna"),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
val result = parseElementConfiguration(params)
|
|
151
|
+
val expected =
|
|
152
|
+
PaymentMethodMessagingElement
|
|
153
|
+
.Configuration()
|
|
154
|
+
.amount(5000)
|
|
155
|
+
.currency("eur")
|
|
156
|
+
.locale("fr_FR")
|
|
157
|
+
.countryCode("FR")
|
|
158
|
+
.paymentMethodTypes(listOf(PaymentMethod.Type.Card, PaymentMethod.Type.Klarna))
|
|
159
|
+
|
|
160
|
+
checkEquals(expected, result)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@Test(expected = PaymentMethodMessagingElementConfigurationException::class)
|
|
164
|
+
fun parseElementConfiguration_WithNullAmount_ThrowsException() {
|
|
165
|
+
val params =
|
|
166
|
+
readableMapOf(
|
|
167
|
+
"amount" to null,
|
|
168
|
+
"currency" to "usd",
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
parseElementConfiguration(params)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@Test(expected = PaymentMethodMessagingElementConfigurationException::class)
|
|
175
|
+
fun parseElementConfiguration_WithNullCurrency_ThrowsException() {
|
|
176
|
+
val params =
|
|
177
|
+
readableMapOf(
|
|
178
|
+
"amount" to 1000.0,
|
|
179
|
+
"currency" to null,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
parseElementConfiguration(params)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ============================================
|
|
186
|
+
// parseAppearance Tests
|
|
187
|
+
// ============================================
|
|
188
|
+
|
|
189
|
+
@Test
|
|
190
|
+
fun parseAppearance_EmptyMap_ReturnsDefaultAppearance() {
|
|
191
|
+
val params = readableMapOf()
|
|
192
|
+
|
|
193
|
+
val result = parseAppearance(params, context)
|
|
194
|
+
val expected =
|
|
195
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
196
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.LIGHT)
|
|
197
|
+
colors(PaymentMethodMessagingElement.Appearance.Colors())
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
checkEquals(expected, result)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
@Test
|
|
204
|
+
fun parseAppearance_WithLightStyle_Success() {
|
|
205
|
+
val params =
|
|
206
|
+
readableMapOf(
|
|
207
|
+
"style" to "light",
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
val result = parseAppearance(params, context)
|
|
211
|
+
val expected =
|
|
212
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
213
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.LIGHT)
|
|
214
|
+
colors(PaymentMethodMessagingElement.Appearance.Colors())
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
checkEquals(expected, result)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
@Test
|
|
221
|
+
fun parseAppearance_WithDarkStyle_Success() {
|
|
222
|
+
val params =
|
|
223
|
+
readableMapOf(
|
|
224
|
+
"style" to "dark",
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
val result = parseAppearance(params, context)
|
|
228
|
+
val expected =
|
|
229
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
230
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.DARK)
|
|
231
|
+
colors(PaymentMethodMessagingElement.Appearance.Colors())
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
checkEquals(expected, result)
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@Test
|
|
238
|
+
fun parseAppearance_WithFlatStyle_Success() {
|
|
239
|
+
val params =
|
|
240
|
+
readableMapOf(
|
|
241
|
+
"style" to "flat",
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
val result = parseAppearance(params, context)
|
|
245
|
+
val expected =
|
|
246
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
247
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.FLAT)
|
|
248
|
+
colors(PaymentMethodMessagingElement.Appearance.Colors())
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
checkEquals(expected, result)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@Test
|
|
255
|
+
fun parseAppearance_WithInvalidStyle_DefaultsToLight() {
|
|
256
|
+
val params =
|
|
257
|
+
readableMapOf(
|
|
258
|
+
"style" to "invalid_style",
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
val result = parseAppearance(params, context)
|
|
262
|
+
val expected =
|
|
263
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
264
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.LIGHT)
|
|
265
|
+
colors(PaymentMethodMessagingElement.Appearance.Colors())
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
checkEquals(expected, result)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
@Test
|
|
272
|
+
fun parseAppearance_WithTextColorHex_Success() {
|
|
273
|
+
val params =
|
|
274
|
+
readableMapOf(
|
|
275
|
+
"textColor" to "#FF0000",
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
val result = parseAppearance(params, context)
|
|
279
|
+
val expected =
|
|
280
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
281
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.LIGHT)
|
|
282
|
+
val colors =
|
|
283
|
+
PaymentMethodMessagingElement.Appearance
|
|
284
|
+
.Colors()
|
|
285
|
+
.textColor("#FF0000".toColorInt())
|
|
286
|
+
colors(colors)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
checkEquals(expected, result)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
@Test
|
|
293
|
+
fun parseAppearance_WithTextColorLightDarkObject_Success() {
|
|
294
|
+
val params =
|
|
295
|
+
readableMapOf(
|
|
296
|
+
"style" to "light",
|
|
297
|
+
"textColor" to
|
|
298
|
+
readableMapOf(
|
|
299
|
+
"light" to "#000000",
|
|
300
|
+
"dark" to "#FFFFFF",
|
|
301
|
+
),
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
val result = parseAppearance(params, context)
|
|
305
|
+
val expected =
|
|
306
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
307
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.LIGHT)
|
|
308
|
+
val colors =
|
|
309
|
+
PaymentMethodMessagingElement.Appearance
|
|
310
|
+
.Colors()
|
|
311
|
+
.textColor("#000000".toColorInt())
|
|
312
|
+
colors(colors)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
checkEquals(expected, result)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
@Test
|
|
319
|
+
fun parseAppearance_WithTextColorDarkTheme_UsesCorrectColor() {
|
|
320
|
+
val params =
|
|
321
|
+
readableMapOf(
|
|
322
|
+
"style" to "dark",
|
|
323
|
+
"textColor" to
|
|
324
|
+
readableMapOf(
|
|
325
|
+
"light" to "#000000",
|
|
326
|
+
"dark" to "#FFFFFF",
|
|
327
|
+
),
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
val result = parseAppearance(params, context)
|
|
331
|
+
val expected =
|
|
332
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
333
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.DARK)
|
|
334
|
+
val colors =
|
|
335
|
+
PaymentMethodMessagingElement.Appearance
|
|
336
|
+
.Colors()
|
|
337
|
+
.textColor("#FFFFFF".toColorInt())
|
|
338
|
+
colors(colors)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
checkEquals(expected, result)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
@Test(expected = PaymentMethodMessagingElementAppearanceException::class)
|
|
345
|
+
fun parseAppearance_WithInvalidTextColorHex_ThrowsException() {
|
|
346
|
+
val params =
|
|
347
|
+
readableMapOf(
|
|
348
|
+
"textColor" to "#FF",
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
parseAppearance(params, context)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
@Test
|
|
355
|
+
fun parseAppearance_WithLinkTextColor_Success() {
|
|
356
|
+
val params =
|
|
357
|
+
readableMapOf(
|
|
358
|
+
"linkTextColor" to "#0000FF",
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
val result = parseAppearance(params, context)
|
|
362
|
+
val expected =
|
|
363
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
364
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.LIGHT)
|
|
365
|
+
val colors =
|
|
366
|
+
PaymentMethodMessagingElement.Appearance
|
|
367
|
+
.Colors()
|
|
368
|
+
.infoIconColor("#0000FF".toColorInt())
|
|
369
|
+
colors(colors)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
checkEquals(expected, result)
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
@Test
|
|
376
|
+
fun parseAppearance_WithLinkTextColorLightDarkObject_Success() {
|
|
377
|
+
val params =
|
|
378
|
+
readableMapOf(
|
|
379
|
+
"style" to "light",
|
|
380
|
+
"linkTextColor" to
|
|
381
|
+
readableMapOf(
|
|
382
|
+
"light" to "#0000FF",
|
|
383
|
+
"dark" to "#00FFFF",
|
|
384
|
+
),
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
val result = parseAppearance(params, context)
|
|
388
|
+
val expected =
|
|
389
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
390
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.LIGHT)
|
|
391
|
+
val colors =
|
|
392
|
+
PaymentMethodMessagingElement.Appearance
|
|
393
|
+
.Colors()
|
|
394
|
+
.infoIconColor("#0000FF".toColorInt())
|
|
395
|
+
colors(colors)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
checkEquals(expected, result)
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
@Test
|
|
402
|
+
fun parseAppearance_WithFontScaleOnly_Success() {
|
|
403
|
+
val params =
|
|
404
|
+
readableMapOf(
|
|
405
|
+
"font" to
|
|
406
|
+
readableMapOf(
|
|
407
|
+
"scale" to 1.5,
|
|
408
|
+
),
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
val result = parseAppearance(params, context)
|
|
412
|
+
val expected =
|
|
413
|
+
PaymentMethodMessagingElement.Appearance().apply {
|
|
414
|
+
theme(PaymentMethodMessagingElement.Appearance.Theme.LIGHT)
|
|
415
|
+
val font =
|
|
416
|
+
PaymentMethodMessagingElement.Appearance
|
|
417
|
+
.Font()
|
|
418
|
+
.fontFamily(null)
|
|
419
|
+
.fontSizeSp((16 * 1.5).toFloat())
|
|
420
|
+
font(font)
|
|
421
|
+
colors(PaymentMethodMessagingElement.Appearance.Colors())
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
checkEquals(expected, result)
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
@Test
|
|
428
|
+
fun parseAppearance_CompleteAppearance_Success() {
|
|
429
|
+
val params =
|
|
430
|
+
readableMapOf(
|
|
431
|
+
"style" to "dark",
|
|
432
|
+
"textColor" to "#FFFFFF",
|
|
433
|
+
"linkTextColor" to "#00FFFF",
|
|
434
|
+
"font" to
|
|
435
|
+
readableMapOf(
|
|
436
|
+
"scale" to 1.2,
|
|
437
|
+
),
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
val result = parseAppearance(params, context)
|
|
441
|
+
|
|
442
|
+
// We can't easily predict the font resource ID in tests, so just verify it doesn't crash
|
|
443
|
+
assertNotNull(result)
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
private fun checkEquals(
|
|
447
|
+
expected: PaymentMethodMessagingElement.Configuration,
|
|
448
|
+
actual: PaymentMethodMessagingElement.Configuration,
|
|
449
|
+
) {
|
|
450
|
+
val fieldNames = listOf("amount", "currency", "locale", "countryCode", "paymentMethodTypes")
|
|
451
|
+
|
|
452
|
+
for (fieldName in fieldNames) {
|
|
453
|
+
val expectedField = expected.javaClass.getDeclaredField(fieldName)
|
|
454
|
+
expectedField.isAccessible = true
|
|
455
|
+
val expectedValue = expectedField.get(expected)
|
|
456
|
+
|
|
457
|
+
val actualField = actual.javaClass.getDeclaredField(fieldName)
|
|
458
|
+
actualField.isAccessible = true
|
|
459
|
+
val actualValue = actualField.get(actual)
|
|
460
|
+
|
|
461
|
+
assertEquals(expectedValue, actualValue)
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
private fun checkEquals(
|
|
466
|
+
expected: PaymentMethodMessagingElement.Appearance,
|
|
467
|
+
actual: PaymentMethodMessagingElement.Appearance,
|
|
468
|
+
) {
|
|
469
|
+
val fieldNames = listOf("theme", "font", "colors")
|
|
470
|
+
|
|
471
|
+
for (fieldName in fieldNames) {
|
|
472
|
+
val expectedField = expected.javaClass.getDeclaredField(fieldName)
|
|
473
|
+
expectedField.isAccessible = true
|
|
474
|
+
val expectedValue = expectedField.get(expected)
|
|
475
|
+
|
|
476
|
+
val actualField = actual.javaClass.getDeclaredField(fieldName)
|
|
477
|
+
actualField.isAccessible = true
|
|
478
|
+
val actualValue = actualField.get(actual)
|
|
479
|
+
|
|
480
|
+
when (fieldName) {
|
|
481
|
+
"font" -> {
|
|
482
|
+
if (expectedValue != null && actualValue != null) {
|
|
483
|
+
checkEqualsFont(
|
|
484
|
+
expectedValue, // as PaymentMethodMessagingElement.Appearance.Font,
|
|
485
|
+
actualValue, // as PaymentMethodMessagingElement.Appearance.Font
|
|
486
|
+
)
|
|
487
|
+
} else {
|
|
488
|
+
assertEquals(expectedValue, actualValue)
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
"colors" -> {
|
|
492
|
+
if (expectedValue != null && actualValue != null) {
|
|
493
|
+
checkEqualsColors(
|
|
494
|
+
expectedValue, // as PaymentMethodMessagingElement.Appearance.Colors,
|
|
495
|
+
actualValue, // as PaymentMethodMessagingElement.Appearance.Colors
|
|
496
|
+
)
|
|
497
|
+
} else {
|
|
498
|
+
assertEquals(expectedValue, actualValue)
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
else -> assertEquals(expectedValue, actualValue)
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
private fun checkEqualsFont(
|
|
507
|
+
expected: Any,
|
|
508
|
+
actual: Any,
|
|
509
|
+
) {
|
|
510
|
+
val fieldNames = listOf("fontFamily", "fontSizeSp")
|
|
511
|
+
|
|
512
|
+
for (fieldName in fieldNames) {
|
|
513
|
+
val expectedField = expected.javaClass.getDeclaredField(fieldName)
|
|
514
|
+
expectedField.isAccessible = true
|
|
515
|
+
val expectedValue = expectedField.get(expected)
|
|
516
|
+
|
|
517
|
+
val actualField = actual.javaClass.getDeclaredField(fieldName)
|
|
518
|
+
actualField.isAccessible = true
|
|
519
|
+
val actualValue = actualField.get(actual)
|
|
520
|
+
|
|
521
|
+
assertEquals("Font field '$fieldName' mismatch", expectedValue, actualValue)
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
private fun checkEqualsColors(
|
|
526
|
+
expected: Any,
|
|
527
|
+
actual: Any,
|
|
528
|
+
) {
|
|
529
|
+
val fieldNames = listOf("textColor", "infoIconColor")
|
|
530
|
+
|
|
531
|
+
for (fieldName in fieldNames) {
|
|
532
|
+
val expectedField = expected.javaClass.getDeclaredField(fieldName)
|
|
533
|
+
expectedField.isAccessible = true
|
|
534
|
+
val expectedValue = expectedField.get(expected)
|
|
535
|
+
|
|
536
|
+
val actualField = actual.javaClass.getDeclaredField(fieldName)
|
|
537
|
+
actualField.isAccessible = true
|
|
538
|
+
val actualValue = actualField.get(actual)
|
|
539
|
+
|
|
540
|
+
assertEquals("Colors field '$fieldName' mismatch", expectedValue, actualValue)
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
package com.reactnativestripesdk
|
|
2
2
|
|
|
3
|
+
import com.facebook.react.bridge.Promise
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
3
5
|
import com.reactnativestripesdk.utils.readableArrayOf
|
|
4
6
|
import com.reactnativestripesdk.utils.readableMapOf
|
|
5
7
|
import com.stripe.android.paymentelement.PaymentMethodOptionsSetupFutureUsagePreview
|
|
6
8
|
import com.stripe.android.paymentsheet.PaymentSheet
|
|
7
9
|
import org.junit.Assert.assertEquals
|
|
8
10
|
import org.junit.Assert.assertNotNull
|
|
11
|
+
import org.junit.Assert.assertTrue
|
|
9
12
|
import org.junit.Test
|
|
10
13
|
import org.junit.runner.RunWith
|
|
14
|
+
import org.mockito.ArgumentCaptor
|
|
15
|
+
import org.mockito.Mockito.mock
|
|
16
|
+
import org.mockito.Mockito.verify
|
|
11
17
|
import org.robolectric.RobolectricTestRunner
|
|
12
18
|
|
|
13
19
|
@RunWith(RobolectricTestRunner::class)
|
|
@@ -520,4 +526,68 @@ class PaymentSheetManagerTest {
|
|
|
520
526
|
|
|
521
527
|
assertNotNull(result)
|
|
522
528
|
}
|
|
529
|
+
|
|
530
|
+
// ============================================
|
|
531
|
+
// handleFlowControllerConfigured Tests
|
|
532
|
+
// ============================================
|
|
533
|
+
|
|
534
|
+
@Test
|
|
535
|
+
fun handleFlowControllerConfigured_Failure_ResolvesWithError() {
|
|
536
|
+
val promise = mock(Promise::class.java)
|
|
537
|
+
val errorMessage = "Configuration failed: invalid API key"
|
|
538
|
+
|
|
539
|
+
handleFlowControllerConfigured(
|
|
540
|
+
success = false,
|
|
541
|
+
error = IllegalArgumentException(errorMessage),
|
|
542
|
+
promise = promise,
|
|
543
|
+
flowController = null,
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
val captor = ArgumentCaptor.forClass(WritableMap::class.java)
|
|
547
|
+
verify(promise).resolve(captor.capture())
|
|
548
|
+
val resolved = captor.value
|
|
549
|
+
assertNotNull(resolved)
|
|
550
|
+
val errorMap = resolved.getMap("error")
|
|
551
|
+
assertNotNull(errorMap)
|
|
552
|
+
assertEquals(errorMessage, errorMap!!.getString("message"))
|
|
553
|
+
assertEquals("Failed", errorMap.getString("code"))
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
@Test
|
|
557
|
+
fun handleFlowControllerConfigured_FailureWithNullError_UsesDefaultMessage() {
|
|
558
|
+
val promise = mock(Promise::class.java)
|
|
559
|
+
|
|
560
|
+
handleFlowControllerConfigured(
|
|
561
|
+
success = false,
|
|
562
|
+
error = null,
|
|
563
|
+
promise = promise,
|
|
564
|
+
flowController = null,
|
|
565
|
+
)
|
|
566
|
+
|
|
567
|
+
val captor = ArgumentCaptor.forClass(WritableMap::class.java)
|
|
568
|
+
verify(promise).resolve(captor.capture())
|
|
569
|
+
val resolved = captor.value
|
|
570
|
+
assertNotNull(resolved)
|
|
571
|
+
val errorMap = resolved.getMap("error")
|
|
572
|
+
assertNotNull(errorMap)
|
|
573
|
+
assertEquals("Failed to configure payment sheet", errorMap!!.getString("message"))
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
@Test
|
|
577
|
+
fun handleFlowControllerConfigured_SuccessWithNoPaymentOption_ResolvesEmptyMap() {
|
|
578
|
+
val promise = mock(Promise::class.java)
|
|
579
|
+
|
|
580
|
+
handleFlowControllerConfigured(
|
|
581
|
+
success = true,
|
|
582
|
+
error = null,
|
|
583
|
+
promise = promise,
|
|
584
|
+
flowController = null,
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
val captor = ArgumentCaptor.forClass(WritableMap::class.java)
|
|
588
|
+
verify(promise).resolve(captor.capture())
|
|
589
|
+
val resolved = captor.value
|
|
590
|
+
assertNotNull(resolved)
|
|
591
|
+
assertTrue(!resolved.hasKey("error"))
|
|
592
|
+
}
|
|
523
593
|
}
|
|
@@ -21,6 +21,7 @@ class CustomerSheetUtils {
|
|
|
21
21
|
defaultBillingDetails: NSDictionary?,
|
|
22
22
|
preferredNetworks: [Int]?,
|
|
23
23
|
allowsRemovalOfLastSavedPaymentMethod: Bool?,
|
|
24
|
+
opensCardScannerAutomatically: Bool?,
|
|
24
25
|
cardBrandAcceptance: PaymentSheet.CardBrandAcceptance
|
|
25
26
|
) -> CustomerSheet.Configuration {
|
|
26
27
|
var config = CustomerSheet.Configuration()
|
|
@@ -59,6 +60,9 @@ class CustomerSheetUtils {
|
|
|
59
60
|
if let allowsRemovalOfLastSavedPaymentMethod = allowsRemovalOfLastSavedPaymentMethod {
|
|
60
61
|
config.allowsRemovalOfLastSavedPaymentMethod = allowsRemovalOfLastSavedPaymentMethod
|
|
61
62
|
}
|
|
63
|
+
if let opensCardScannerAutomatically = opensCardScannerAutomatically {
|
|
64
|
+
config.opensCardScannerAutomatically = opensCardScannerAutomatically
|
|
65
|
+
}
|
|
62
66
|
config.cardBrandAcceptance = cardBrandAcceptance
|
|
63
67
|
return config
|
|
64
68
|
}
|
|
@@ -24,5 +24,7 @@
|
|
|
24
24
|
- (void)emitEmbeddedPaymentElementLoadingFailed:(NSDictionary *)value;
|
|
25
25
|
- (void)emitOnCustomPaymentMethodConfirmHandlerCallback:(NSDictionary *)value;
|
|
26
26
|
- (void)emitOnCheckoutClientSecretRequested:(NSDictionary *)value;
|
|
27
|
+
- (void)emitPaymentMethodMessagingElementDidUpdateHeight:(NSDictionary *)value;
|
|
28
|
+
- (void)emitPaymentMethodMessagingElementConfigureResult:(NSDictionary *)value;
|
|
27
29
|
@end
|
|
28
30
|
|