frames-react-native 1.1.9 → 1.2.3
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/.github/workflows/cd.yml +36 -36
- package/.github/workflows/ci.yml +3 -3
- package/README.md +36 -2
- package/__mocks__/fileTransformer.js +9 -0
- package/__tests__/Integration.test.tsx +148 -359
- package/__tests__/Unit.test.tsx +1 -1
- package/dist/Frames.d.ts +2 -2
- package/dist/Frames.js +11 -8
- package/dist/Frames.js.map +1 -1
- package/dist/components/CardNumber.js +17 -16
- package/dist/components/CardNumber.js.map +1 -1
- package/dist/components/Cvv.d.ts +1 -1
- package/dist/components/Cvv.js +9 -8
- package/dist/components/Cvv.js.map +1 -1
- package/dist/components/ExpiryDate.d.ts +1 -1
- package/dist/components/ExpiryDate.js +9 -8
- package/dist/components/ExpiryDate.js.map +1 -1
- package/dist/components/SubmitButton.js +11 -11
- package/dist/components/SubmitButton.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/types/types.d.ts +18 -14
- package/dist/types/types.js +1 -0
- package/dist/utils/card.d.ts +5 -4
- package/dist/utils/card.js +14 -10
- package/dist/utils/card.js.map +1 -1
- package/dist/utils/date.js.map +1 -1
- package/dist/utils/http.d.ts +1 -1
- package/dist/utils/http.js +5 -6
- package/dist/utils/http.js.map +1 -1
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/reducer.d.ts +5 -28
- package/dist/utils/reducer.js +7 -7
- package/dist/utils/reducer.js.map +1 -1
- package/package.json +18 -15
|
@@ -1,401 +1,190 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { createRef } from "react";
|
|
2
2
|
import { render, fireEvent, waitFor } from "@testing-library/react-native";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
-
CardNumber,
|
|
6
5
|
Frames,
|
|
6
|
+
CardNumber,
|
|
7
7
|
ExpiryDate,
|
|
8
8
|
Cvv,
|
|
9
9
|
SubmitButton,
|
|
10
10
|
} from "../src/index";
|
|
11
|
+
import type { FramesRef } from "../src/index";
|
|
12
|
+
|
|
13
|
+
// Mock network-dependent modules to avoid real HTTP requests
|
|
14
|
+
jest.mock("../src/utils/http", () => {
|
|
15
|
+
const actual = jest.requireActual("../src/utils/http");
|
|
16
|
+
return {
|
|
17
|
+
...actual,
|
|
18
|
+
tokenize: jest.fn(),
|
|
19
|
+
};
|
|
20
|
+
});
|
|
11
21
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<Frames
|
|
20
|
-
config={{
|
|
21
|
-
publicKey: PK,
|
|
22
|
-
debug: true,
|
|
23
|
-
}}
|
|
24
|
-
cardTokenized={tokenized}
|
|
25
|
-
>
|
|
26
|
-
<CardNumber placeholder="card-number" />
|
|
27
|
-
<ExpiryDate placeholder="expiry-date" />
|
|
28
|
-
<Cvv placeholder="cvv" />
|
|
29
|
-
<SubmitButton
|
|
30
|
-
title="Pay Now"
|
|
31
|
-
testID={"submit-button"}
|
|
32
|
-
onPress={() => {}}
|
|
33
|
-
/>
|
|
34
|
-
</Frames>
|
|
35
|
-
);
|
|
22
|
+
jest.mock("../src/utils/logger", () => {
|
|
23
|
+
const actual = jest.requireActual("../src/utils/logger");
|
|
24
|
+
return {
|
|
25
|
+
...actual,
|
|
26
|
+
log: jest.fn(),
|
|
27
|
+
};
|
|
28
|
+
});
|
|
36
29
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
30
|
+
describe("Frames integration", () => {
|
|
31
|
+
const validVisa = "4242 4242 4242 4242"; // Visa test number
|
|
32
|
+
const validExpiry = "12/30"; // future year
|
|
33
|
+
const validCvv = "123";
|
|
34
|
+
|
|
35
|
+
const config = {
|
|
36
|
+
publicKey: "pk_sbox_eo3yb3urja2ozf6ycgn5kuy7ke#",
|
|
37
|
+
debug: true,
|
|
38
|
+
cardholder: {
|
|
39
|
+
name: "John Doe",
|
|
40
|
+
phone: "+1234567890",
|
|
41
|
+
billingAddress: {
|
|
42
|
+
addressLine1: "123 Test St",
|
|
43
|
+
city: "Test City",
|
|
44
|
+
state: "TS",
|
|
45
|
+
zip: "12345",
|
|
46
|
+
country: "US",
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
beforeEach(() => {
|
|
52
|
+
jest.clearAllMocks();
|
|
49
53
|
});
|
|
50
54
|
|
|
51
|
-
it("
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
+
it("emits validation and bin events, and tokenizes on submit", async () => {
|
|
56
|
+
const { tokenize } = require("../src/utils/http");
|
|
57
|
+
|
|
58
|
+
const mockTokenResponse = {
|
|
59
|
+
type: "card",
|
|
60
|
+
token: "tok_test_123",
|
|
61
|
+
expires_on: "2030-12-31T23:59:59Z",
|
|
62
|
+
expiry_month: "12",
|
|
63
|
+
expiry_year: "2030",
|
|
64
|
+
scheme: "Visa",
|
|
65
|
+
last4: "4242",
|
|
66
|
+
bin: "424242",
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
tokenize.mockResolvedValueOnce(mockTokenResponse);
|
|
70
|
+
|
|
71
|
+
const frameValidationChanged = jest.fn();
|
|
72
|
+
const paymentMethodChanged = jest.fn();
|
|
73
|
+
const cardValidationChanged = jest.fn();
|
|
74
|
+
const cardTokenized = jest.fn();
|
|
75
|
+
const cardTokenizationFailed = jest.fn();
|
|
76
|
+
const cardBinChanged = jest.fn();
|
|
77
|
+
|
|
78
|
+
const screen = render(
|
|
55
79
|
<Frames
|
|
56
|
-
config={
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
cardTokenized={
|
|
61
|
-
|
|
80
|
+
config={config}
|
|
81
|
+
frameValidationChanged={frameValidationChanged}
|
|
82
|
+
paymentMethodChanged={paymentMethodChanged}
|
|
83
|
+
cardValidationChanged={cardValidationChanged}
|
|
84
|
+
cardTokenized={cardTokenized}
|
|
85
|
+
cardTokenizationFailed={cardTokenizationFailed}
|
|
86
|
+
cardBinChanged={cardBinChanged}
|
|
62
87
|
>
|
|
63
|
-
<CardNumber
|
|
64
|
-
<ExpiryDate
|
|
65
|
-
<Cvv
|
|
66
|
-
<SubmitButton
|
|
67
|
-
title="Pay Now"
|
|
68
|
-
testID={"submit-button"}
|
|
69
|
-
onPress={() => {}}
|
|
70
|
-
/>
|
|
88
|
+
<CardNumber />
|
|
89
|
+
<ExpiryDate />
|
|
90
|
+
<Cvv />
|
|
91
|
+
<SubmitButton title="Pay" />
|
|
71
92
|
</Frames>
|
|
72
93
|
);
|
|
73
94
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
let pay = getByTestId("submit-button");
|
|
78
|
-
fireEvent.changeText(cardNumber, "42424242");
|
|
79
|
-
expect(binChange).toHaveBeenCalledTimes(1);
|
|
80
|
-
});
|
|
95
|
+
const cardNumberInput = screen.getByPlaceholderText("•••• •••• •••• ••••");
|
|
96
|
+
const expiryInput = screen.getByPlaceholderText("MM/YY");
|
|
97
|
+
const cvvInput = screen.getByPlaceholderText("•••");
|
|
81
98
|
|
|
82
|
-
|
|
83
|
-
|
|
99
|
+
// Enter card number -> should emit bin and payment method changes
|
|
100
|
+
fireEvent.changeText(cardNumberInput, validVisa);
|
|
84
101
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
publicKey: PK,
|
|
89
|
-
}}
|
|
90
|
-
cardTokenized={() => {}}
|
|
91
|
-
cardTokenizationFailed={failed}
|
|
92
|
-
>
|
|
93
|
-
<CardNumber placeholder="card-number" />
|
|
94
|
-
<ExpiryDate placeholder="expiry-date" />
|
|
95
|
-
<Cvv placeholder="cvv" />
|
|
96
|
-
<SubmitButton
|
|
97
|
-
title="Pay Now"
|
|
98
|
-
testID={"submit-button"}
|
|
99
|
-
onPress={() => {}}
|
|
100
|
-
/>
|
|
101
|
-
</Frames>
|
|
102
|
+
await waitFor(() => expect(paymentMethodChanged).toHaveBeenCalled());
|
|
103
|
+
expect(paymentMethodChanged).toHaveBeenCalledWith(
|
|
104
|
+
expect.objectContaining({ paymentMethod: "Visa", isValid: false })
|
|
102
105
|
);
|
|
103
106
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
fireEvent.changeText(cvv, "100");
|
|
111
|
-
fireEvent.press(pay);
|
|
112
|
-
await waitFor(() => {
|
|
113
|
-
expect(failed).toHaveBeenCalledTimes(1);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it("throws when the pay button is outside of context", async () => {
|
|
118
|
-
expect(() => {
|
|
119
|
-
render(
|
|
120
|
-
<SubmitButton
|
|
121
|
-
title="Pay Now"
|
|
122
|
-
testID={"submit-button"}
|
|
123
|
-
onPress={() => {}}
|
|
124
|
-
/>
|
|
125
|
-
);
|
|
126
|
-
}).toThrow(
|
|
127
|
-
"It looks like you are trying to render the SubmitButton outside of the Frames Component."
|
|
107
|
+
await waitFor(() => expect(cardBinChanged).toHaveBeenCalled());
|
|
108
|
+
expect(cardBinChanged).toHaveBeenCalledWith(
|
|
109
|
+
expect.objectContaining({
|
|
110
|
+
bin: expect.stringMatching(/^42424242/),
|
|
111
|
+
scheme: "Visa",
|
|
112
|
+
})
|
|
128
113
|
);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("throws allow then use of the onPress handler", async () => {
|
|
132
|
-
const press = jest.fn();
|
|
133
114
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}}
|
|
152
|
-
cardTokenized={() => {}}
|
|
153
|
-
>
|
|
154
|
-
<CardNumber placeholder="card-number" />
|
|
155
|
-
<ExpiryDate placeholder="expiry-date" />
|
|
156
|
-
<Cvv placeholder="cvv" />
|
|
157
|
-
<SubmitButton
|
|
158
|
-
title="Pay Now"
|
|
159
|
-
testID={"submit-button"}
|
|
160
|
-
onPress={press}
|
|
161
|
-
/>
|
|
162
|
-
</Frames>
|
|
115
|
+
// Enter expiry date
|
|
116
|
+
fireEvent.changeText(expiryInput, validExpiry);
|
|
117
|
+
|
|
118
|
+
// Enter cvv
|
|
119
|
+
fireEvent.changeText(cvvInput, validCvv);
|
|
120
|
+
|
|
121
|
+
// After all fields valid, cardValidationChanged should report isValid: true
|
|
122
|
+
await waitFor(() => expect(cardValidationChanged).toHaveBeenCalled());
|
|
123
|
+
expect(cardValidationChanged).toHaveBeenLastCalledWith(
|
|
124
|
+
expect.objectContaining({
|
|
125
|
+
isValid: true,
|
|
126
|
+
isElementValid: expect.objectContaining({
|
|
127
|
+
cardNumber: true,
|
|
128
|
+
expiryDate: true,
|
|
129
|
+
cvv: true,
|
|
130
|
+
}),
|
|
131
|
+
})
|
|
163
132
|
);
|
|
164
|
-
let cardNumber = getByPlaceholderText("card-number");
|
|
165
|
-
let expiryDate = getByPlaceholderText("expiry-date");
|
|
166
|
-
let cvv = getByPlaceholderText("cvv");
|
|
167
|
-
let pay = getByTestId("submit-button");
|
|
168
|
-
fireEvent.changeText(cardNumber, "4242424242424242");
|
|
169
|
-
fireEvent.changeText(expiryDate, "1128");
|
|
170
|
-
fireEvent.changeText(cvv, "100");
|
|
171
|
-
fireEvent.press(pay);
|
|
172
|
-
|
|
173
|
-
fireEvent.press(pay);
|
|
174
|
-
expect(press).toHaveBeenCalled();
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
it("fails tokenization", async () => {
|
|
178
|
-
const failed = jest.fn();
|
|
179
133
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
publicKey: "pk_test_baabd05f-1cdb-43d9-851e-635a79f6e7ad", // this account does not have Visa enabled
|
|
184
|
-
debug: true,
|
|
185
|
-
}}
|
|
186
|
-
cardTokenized={() => {}}
|
|
187
|
-
frameValidationChanged={(e) => {}}
|
|
188
|
-
paymentMethodChanged={(e) => {}}
|
|
189
|
-
cardValidationChanged={(e) => {}}
|
|
190
|
-
cardTokenizationFailed={failed}
|
|
191
|
-
>
|
|
192
|
-
<CardNumber placeholder="card-number" />
|
|
193
|
-
<ExpiryDate placeholder="expiry-date" />
|
|
194
|
-
<Cvv placeholder="cvv" />
|
|
195
|
-
<SubmitButton
|
|
196
|
-
title="Pay Now"
|
|
197
|
-
testID={"submit-button"}
|
|
198
|
-
onPress={() => {}}
|
|
199
|
-
/>
|
|
200
|
-
</Frames>
|
|
201
|
-
);
|
|
134
|
+
// Submit and expect tokenization to be called and success event emitted
|
|
135
|
+
const payButton = screen.getByText("Pay");
|
|
136
|
+
fireEvent.press(payButton);
|
|
202
137
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
let pay = getByTestId("submit-button");
|
|
207
|
-
fireEvent.changeText(cardNumber, "4242424242424242");
|
|
208
|
-
fireEvent.changeText(expiryDate, "0628");
|
|
209
|
-
fireEvent.changeText(cvv, "100");
|
|
210
|
-
fireEvent.press(pay);
|
|
211
|
-
await waitFor(() => {
|
|
212
|
-
expect(failed).toHaveBeenCalledTimes(1);
|
|
213
|
-
});
|
|
138
|
+
await waitFor(() => expect(tokenize).toHaveBeenCalledTimes(1));
|
|
139
|
+
expect(cardTokenized).toHaveBeenCalledWith(mockTokenResponse);
|
|
140
|
+
expect(cardTokenizationFailed).not.toHaveBeenCalled();
|
|
214
141
|
});
|
|
215
142
|
|
|
216
|
-
it("
|
|
217
|
-
const
|
|
143
|
+
it("allows submitting via Frames ref submitCard()", async () => {
|
|
144
|
+
const { tokenize } = require("../src/utils/http");
|
|
218
145
|
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
city: "London",
|
|
230
|
-
state: "London",
|
|
231
|
-
zip: "W1W 8GY",
|
|
232
|
-
country: "GB",
|
|
233
|
-
},
|
|
234
|
-
phone: "07123456789",
|
|
235
|
-
},
|
|
236
|
-
}}
|
|
237
|
-
cardTokenized={tokenized}
|
|
238
|
-
>
|
|
239
|
-
<CardNumber placeholder="card-number" />
|
|
240
|
-
<ExpiryDate placeholder="expiry-date" />
|
|
241
|
-
<Cvv placeholder="cvv" />
|
|
242
|
-
<SubmitButton
|
|
243
|
-
title="Pay Now"
|
|
244
|
-
testID={"submit-button"}
|
|
245
|
-
onPress={() => {}}
|
|
246
|
-
/>
|
|
247
|
-
</Frames>
|
|
248
|
-
);
|
|
146
|
+
const mockTokenResponse = {
|
|
147
|
+
type: "card",
|
|
148
|
+
token: "tok_test_ref_123",
|
|
149
|
+
expires_on: "2030-12-31T23:59:59Z",
|
|
150
|
+
expiry_month: "12",
|
|
151
|
+
expiry_year: "2030",
|
|
152
|
+
scheme: "Visa",
|
|
153
|
+
last4: "4242",
|
|
154
|
+
bin: "424242",
|
|
155
|
+
};
|
|
249
156
|
|
|
250
|
-
|
|
251
|
-
let expiryDate = getByPlaceholderText("expiry-date");
|
|
252
|
-
let cvv = getByPlaceholderText("cvv");
|
|
253
|
-
let pay = getByTestId("submit-button");
|
|
254
|
-
fireEvent.changeText(cardNumber, "4242424242424242");
|
|
255
|
-
fireEvent.changeText(expiryDate, "1128");
|
|
256
|
-
fireEvent.changeText(cvv, "100");
|
|
257
|
-
fireEvent.press(pay);
|
|
258
|
-
await waitFor(() => {
|
|
259
|
-
expect(tokenized).toHaveBeenCalledTimes(1);
|
|
260
|
-
});
|
|
261
|
-
expect(tokenized.mock.calls[0][0].billing_address.address_line1).toEqual(
|
|
262
|
-
"Wall Street"
|
|
263
|
-
);
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
it("triggers the card tokenization with amex", async () => {
|
|
267
|
-
const tokenized = jest.fn();
|
|
268
|
-
|
|
269
|
-
const { getByPlaceholderText, getByTestId } = render(
|
|
270
|
-
<Frames
|
|
271
|
-
config={{
|
|
272
|
-
publicKey: PK,
|
|
273
|
-
}}
|
|
274
|
-
cardTokenized={tokenized}
|
|
275
|
-
>
|
|
276
|
-
<CardNumber placeholder="card-number" />
|
|
277
|
-
<ExpiryDate placeholder="expiry-date" />
|
|
278
|
-
<Cvv placeholder="cvv" />
|
|
279
|
-
<SubmitButton
|
|
280
|
-
title="Pay Now"
|
|
281
|
-
testID={"submit-button"}
|
|
282
|
-
onPress={() => {}}
|
|
283
|
-
/>
|
|
284
|
-
</Frames>
|
|
285
|
-
);
|
|
157
|
+
tokenize.mockResolvedValueOnce(mockTokenResponse);
|
|
286
158
|
|
|
287
|
-
|
|
288
|
-
let expiryDate = getByPlaceholderText("expiry-date");
|
|
289
|
-
let cvv = getByPlaceholderText("cvv");
|
|
290
|
-
let pay = getByTestId("submit-button");
|
|
291
|
-
fireEvent.changeText(cardNumber, "378282246310005");
|
|
292
|
-
fireEvent.changeText(expiryDate, "1128");
|
|
293
|
-
fireEvent.changeText(cvv, "1000");
|
|
294
|
-
fireEvent.press(pay);
|
|
295
|
-
await waitFor(() => {
|
|
296
|
-
expect(tokenized).toHaveBeenCalledTimes(1);
|
|
297
|
-
});
|
|
298
|
-
});
|
|
159
|
+
const cardTokenized = jest.fn();
|
|
299
160
|
|
|
300
|
-
|
|
301
|
-
const tokenized = jest.fn();
|
|
161
|
+
const ref = createRef<FramesRef>();
|
|
302
162
|
|
|
303
|
-
const
|
|
304
|
-
<Frames
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
cardholder: {
|
|
309
|
-
name: "John Smith",
|
|
310
|
-
billingAddress: {
|
|
311
|
-
addressLine1: "Wall Street",
|
|
312
|
-
addressLine2: "Dollar Avenue",
|
|
313
|
-
},
|
|
314
|
-
},
|
|
315
|
-
}}
|
|
316
|
-
cardTokenized={tokenized}
|
|
317
|
-
cardTokenizationFailed={(e) => {
|
|
318
|
-
console.log(e);
|
|
319
|
-
}}
|
|
320
|
-
>
|
|
321
|
-
<CardNumber placeholder="card-number" />
|
|
322
|
-
<ExpiryDate placeholder="expiry-date" />
|
|
323
|
-
<Cvv placeholder="cvv" />
|
|
324
|
-
<SubmitButton
|
|
325
|
-
title="Pay Now"
|
|
326
|
-
testID={"submit-button"}
|
|
327
|
-
onPress={() => {}}
|
|
328
|
-
/>
|
|
163
|
+
const screen = render(
|
|
164
|
+
<Frames config={config} cardTokenized={cardTokenized} ref={ref}>
|
|
165
|
+
<CardNumber />
|
|
166
|
+
<ExpiryDate />
|
|
167
|
+
<Cvv />
|
|
329
168
|
</Frames>
|
|
330
169
|
);
|
|
331
170
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
let pay = getByTestId("submit-button");
|
|
336
|
-
fireEvent.changeText(cardNumber, "4242424242424242");
|
|
337
|
-
fireEvent.changeText(expiryDate, "1128");
|
|
338
|
-
fireEvent.changeText(cvv, "100");
|
|
339
|
-
fireEvent.press(pay);
|
|
340
|
-
await waitFor(() => {
|
|
341
|
-
expect(tokenized).toHaveBeenCalledTimes(1);
|
|
342
|
-
});
|
|
343
|
-
expect(tokenized.mock.calls[0][0].billing_address.address_line1).toEqual(
|
|
344
|
-
"Wall Street"
|
|
345
|
-
);
|
|
346
|
-
});
|
|
171
|
+
const cardNumberInput = screen.getByPlaceholderText("•••• •••• •••• ••••");
|
|
172
|
+
const expiryInput = screen.getByPlaceholderText("MM/YY");
|
|
173
|
+
const cvvInput = screen.getByPlaceholderText("•••");
|
|
347
174
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
} catch (e) {
|
|
353
|
-
exception = e;
|
|
354
|
-
}
|
|
355
|
-
expect(exception).toEqual(
|
|
356
|
-
"It looks like you are trying to render the CardNumber outside of the Frames Component."
|
|
357
|
-
);
|
|
358
|
-
});
|
|
175
|
+
// Fill valid data
|
|
176
|
+
fireEvent.changeText(cardNumberInput, validVisa);
|
|
177
|
+
fireEvent.changeText(expiryInput, validExpiry);
|
|
178
|
+
fireEvent.changeText(cvvInput, validCvv);
|
|
359
179
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
} catch (e) {
|
|
365
|
-
exception = e;
|
|
366
|
-
}
|
|
367
|
-
expect(exception).toEqual(
|
|
368
|
-
"It looks like you are trying to render the ExpiryDate outside of the Frames Component."
|
|
369
|
-
);
|
|
370
|
-
});
|
|
180
|
+
// Call submit via ref
|
|
181
|
+
await waitFor(async () => {
|
|
182
|
+
expect(ref.current).not.toBeNull();
|
|
183
|
+
});
|
|
371
184
|
|
|
372
|
-
|
|
373
|
-
let exception;
|
|
374
|
-
try {
|
|
375
|
-
render(<Cvv placeholder="cvv" />);
|
|
376
|
-
} catch (e) {
|
|
377
|
-
exception = e;
|
|
378
|
-
}
|
|
379
|
-
expect(exception).toEqual(
|
|
380
|
-
"It looks like you are trying to render the Cvv outside of the Frames Component."
|
|
381
|
-
);
|
|
382
|
-
});
|
|
185
|
+
await ref.current!.submitCard();
|
|
383
186
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
try {
|
|
387
|
-
render(
|
|
388
|
-
<SubmitButton
|
|
389
|
-
title="Pay Now"
|
|
390
|
-
testID={"submit-button"}
|
|
391
|
-
onPress={() => {}}
|
|
392
|
-
/>
|
|
393
|
-
);
|
|
394
|
-
} catch (e) {
|
|
395
|
-
exception = e;
|
|
396
|
-
}
|
|
397
|
-
expect(exception).toEqual(
|
|
398
|
-
"It looks like you are trying to render the SubmitButton outside of the Frames Component."
|
|
399
|
-
);
|
|
187
|
+
await waitFor(() => expect(tokenize).toHaveBeenCalledTimes(1));
|
|
188
|
+
expect(cardTokenized).toHaveBeenCalledWith(mockTokenResponse);
|
|
400
189
|
});
|
|
401
190
|
});
|
package/__tests__/Unit.test.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { getFormattedDate } from "../src/utils/date";
|
|
|
3
3
|
import { getEnvironment } from "../src/utils/http";
|
|
4
4
|
import { getEnvironment as loggerGetEnvironment } from "../src/utils/logger";
|
|
5
5
|
|
|
6
|
-
const PK_SB = "
|
|
6
|
+
const PK_SB = "pk_sbox_eo3yb3urja2ozf6ycgn5kuy7ke#";
|
|
7
7
|
const PK_PROD = "pk_4296fd52-efba-4a38-b6ce-cf0d93639d8a"; // fake key
|
|
8
8
|
|
|
9
9
|
describe("Date", () => {
|
package/dist/Frames.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { FramesContextType, FramesProps } from "./types/types";
|
|
2
|
+
import { FramesContextType, FramesProps, FramesRef } from "./types/types";
|
|
3
3
|
export declare const FramesContext: React.Context<FramesContextType>;
|
|
4
|
-
declare const Frames:
|
|
4
|
+
declare const Frames: React.ForwardRefExoticComponent<FramesProps & React.RefAttributes<FramesRef>>;
|
|
5
5
|
export default Frames;
|
|
6
6
|
export declare const FramesConsumer: React.Consumer<FramesContextType>;
|
|
7
7
|
export declare const FramesProvider: React.Provider<FramesContextType>;
|
package/dist/Frames.js
CHANGED
|
@@ -13,7 +13,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
13
13
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
14
|
function step(op) {
|
|
15
15
|
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
-
while (_) try {
|
|
16
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
17
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
18
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
19
|
switch (op[0]) {
|
|
@@ -34,15 +34,14 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
34
34
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
-
import React, { useEffect } from "react";
|
|
37
|
+
import React, { useEffect, useImperativeHandle } from "react";
|
|
38
38
|
import { View, StyleSheet } from "react-native";
|
|
39
39
|
import { framesReducer } from "./utils/reducer";
|
|
40
40
|
import { log } from "./utils/logger";
|
|
41
41
|
import { tokenize, formatDataForTokenization } from "./utils/http";
|
|
42
42
|
export var FramesContext = React.createContext({});
|
|
43
|
-
var Frames = function (props) {
|
|
44
|
-
|
|
45
|
-
var _a = React.useReducer(framesReducer, {
|
|
43
|
+
var Frames = React.forwardRef(function (props, ref) {
|
|
44
|
+
var initialState = {
|
|
46
45
|
cardNumber: null,
|
|
47
46
|
cardBin: {
|
|
48
47
|
bin: null,
|
|
@@ -59,7 +58,8 @@ var Frames = function (props) {
|
|
|
59
58
|
cvv: false,
|
|
60
59
|
card: false,
|
|
61
60
|
},
|
|
62
|
-
}
|
|
61
|
+
};
|
|
62
|
+
var _a = React.useReducer(framesReducer, initialState), state = _a[0], dispatch = _a[1];
|
|
63
63
|
var submitCard = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
64
64
|
var response, error_1;
|
|
65
65
|
return __generator(this, function (_a) {
|
|
@@ -82,12 +82,15 @@ var Frames = function (props) {
|
|
|
82
82
|
console.info("Emitting \"cardTokenizationFailed\"", error_1);
|
|
83
83
|
if (props.cardTokenizationFailed)
|
|
84
84
|
props.cardTokenizationFailed(error_1);
|
|
85
|
-
log("error", "com.checkout.frames-mobile-sdk.exception", props.config, error_1);
|
|
85
|
+
log("error", "com.checkout.frames-mobile-sdk.exception", props.config, error_1 || {});
|
|
86
86
|
return [3 /*break*/, 3];
|
|
87
87
|
case 3: return [2 /*return*/];
|
|
88
88
|
}
|
|
89
89
|
});
|
|
90
90
|
}); };
|
|
91
|
+
useImperativeHandle(ref, function () { return ({
|
|
92
|
+
submitCard: submitCard,
|
|
93
|
+
}); }, [submitCard]);
|
|
91
94
|
useEffect(function () {
|
|
92
95
|
if (state.cardBin.bin !== null) {
|
|
93
96
|
if (props.config.debug)
|
|
@@ -170,7 +173,7 @@ var Frames = function (props) {
|
|
|
170
173
|
{props.children}
|
|
171
174
|
</FramesContext.Provider>
|
|
172
175
|
</View>);
|
|
173
|
-
};
|
|
176
|
+
});
|
|
174
177
|
export default Frames;
|
|
175
178
|
export var FramesConsumer = FramesContext.Consumer;
|
|
176
179
|
export var FramesProvider = FramesContext.Provider;
|
package/dist/Frames.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Frames.js","sourceRoot":"","sources":["../src/Frames.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Frames.js","sourceRoot":"","sources":["../src/Frames.tsx"],"names":[],"mappings":"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"}
|