1
+ import { QueryClient , QueryClientProvider } from '@tanstack/react-query'
1
2
import { render , screen } from '@testing-library/react'
2
3
import userEvent from '@testing-library/user-event'
3
4
@@ -6,18 +7,37 @@ import { Plans } from 'shared/utils/billing'
6
7
7
8
import PaymentCard from './PaymentCard'
8
9
10
+ const queryClient = new QueryClient ( )
11
+
9
12
const mocks = vi . hoisted ( ( ) => ( {
10
- useUpdateCard : vi . fn ( ) ,
13
+ useUpdatePaymentMethod : vi . fn ( ) ,
14
+ useCreateStripeSetupIntent : vi . fn ( ) ,
11
15
} ) )
12
16
13
- vi . mock ( 'services/account' , async ( ) => {
14
- const actual = await vi . importActual ( 'services/account' )
17
+ vi . mock ( 'services/account/useUpdatePaymentMethod' , async ( ) => {
18
+ const actual = await vi . importActual (
19
+ 'services/account/useUpdatePaymentMethod'
20
+ )
15
21
return {
16
22
...actual ,
17
- useUpdateCard : mocks . useUpdateCard ,
23
+ useUpdatePaymentMethod : mocks . useUpdatePaymentMethod ,
18
24
}
19
25
} )
20
26
27
+ vi . mock ( 'services/account/useCreateStripeSetupIntent' , async ( ) => {
28
+ const actual = await vi . importActual (
29
+ 'services/account/useCreateStripeSetupIntent'
30
+ )
31
+ return {
32
+ ...actual ,
33
+ useCreateStripeSetupIntent : mocks . useCreateStripeSetupIntent ,
34
+ }
35
+ } )
36
+
37
+ afterEach ( ( ) => {
38
+ vi . clearAllMocks ( )
39
+ } )
40
+
21
41
const subscriptionDetail = {
22
42
defaultPaymentMethod : {
23
43
card : {
@@ -35,7 +55,9 @@ const subscriptionDetail = {
35
55
}
36
56
37
57
const wrapper = ( { children } ) => (
38
- < ThemeContextProvider > { children } </ ThemeContextProvider >
58
+ < QueryClientProvider client = { queryClient } >
59
+ < ThemeContextProvider > { children } </ ThemeContextProvider >
60
+ </ QueryClientProvider >
39
61
)
40
62
41
63
// mocking all the stripe components; and trusting the library :)
@@ -48,9 +70,11 @@ vi.mock('@stripe/react-stripe-js', () => {
48
70
return {
49
71
useElements : ( ) => ( {
50
72
getElement : vi . fn ( ) ,
73
+ submit : vi . fn ( ) ,
51
74
} ) ,
52
75
useStripe : ( ) => ( { } ) ,
53
- CardElement : makeFakeComponent ( 'CardElement' ) ,
76
+ PaymentElement : makeFakeComponent ( 'PaymentElement' ) ,
77
+ Elements : makeFakeComponent ( 'Elements' ) ,
54
78
}
55
79
} )
56
80
@@ -64,20 +88,20 @@ describe('PaymentCard', () => {
64
88
describe ( `when the user doesn't have any subscriptionDetail` , ( ) => {
65
89
// NOTE: This test is misleading because we hide this component from a higher level in
66
90
// BillingDetails.tsx if there is no subscriptionDetail
67
- it ( 'renders the set card message' , ( ) => {
91
+ it ( 'renders the set payment method message' , ( ) => {
68
92
render (
69
93
< PaymentCard subscriptionDetail = { null } provider = "gh" owner = "codecov" />
70
94
)
71
95
72
96
expect (
73
97
screen . getByText (
74
- / N o c r e d i t c a r d s e t . P l e a s e c o n t a c t s u p p o r t i f y o u t h i n k i t ’ s a n e r r o r o r s e t i t y o u r s e l f ./
98
+ / N o p a y m e n t m e t h o d s e t . P l e a s e c o n t a c t s u p p o r t i f y o u t h i n k i t ' s a n e r r o r o r s e t i t y o u r s e l f ./
75
99
)
76
100
) . toBeInTheDocument ( )
77
101
} )
78
102
} )
79
103
80
- describe ( `when the user doesn't have any card ` , ( ) => {
104
+ describe ( `when the user doesn't have any payment method ` , ( ) => {
81
105
it ( 'renders an error message' , ( ) => {
82
106
render (
83
107
< PaymentCard
@@ -93,7 +117,7 @@ describe('PaymentCard', () => {
93
117
94
118
expect (
95
119
screen . getByText (
96
- / N o c r e d i t c a r d s e t . P l e a s e c o n t a c t s u p p o r t i f y o u t h i n k i t ’ s a n e r r o r o r s e t i t y o u r s e l f ./
120
+ / N o p a y m e n t m e t h o d s e t . P l e a s e c o n t a c t s u p p o r t i f y o u t h i n k i t ' s a n e r r o r o r s e t i t y o u r s e l f ./
97
121
)
98
122
) . toBeInTheDocument ( )
99
123
} )
@@ -113,7 +137,7 @@ describe('PaymentCard', () => {
113
137
{ wrapper }
114
138
)
115
139
116
- mocks . useUpdateCard . mockReturnValue ( {
140
+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
117
141
mutate : ( ) => null ,
118
142
isLoading : false ,
119
143
} )
@@ -136,15 +160,13 @@ describe('PaymentCard', () => {
136
160
{ wrapper }
137
161
)
138
162
139
- mocks . useUpdateCard . mockReturnValue ( {
163
+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
140
164
mutate : ( ) => null ,
141
165
isLoading : false ,
142
166
} )
143
167
await user . click ( screen . getByTestId ( 'open-modal' ) )
144
168
145
- expect (
146
- screen . getByRole ( 'button' , { name : / u p d a t e / i } )
147
- ) . toBeInTheDocument ( )
169
+ expect ( screen . getByTestId ( 'save-payment-method' ) ) . toBeInTheDocument ( )
148
170
} )
149
171
} )
150
172
} )
@@ -199,9 +221,9 @@ describe('PaymentCard', () => {
199
221
describe ( 'when the user clicks on Edit card' , ( ) => {
200
222
it ( `doesn't render the card anymore` , async ( ) => {
201
223
const { user } = setup ( )
202
- const updateCard = vi . fn ( )
203
- mocks . useUpdateCard . mockReturnValue ( {
204
- mutate : updateCard ,
224
+ const updatePaymentMethod = vi . fn ( )
225
+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
226
+ mutate : updatePaymentMethod ,
205
227
isLoading : false ,
206
228
} )
207
229
@@ -213,16 +235,16 @@ describe('PaymentCard', () => {
213
235
/> ,
214
236
{ wrapper }
215
237
)
216
- await user . click ( screen . getByTestId ( 'edit-card ' ) )
238
+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
217
239
218
240
expect ( screen . queryByText ( / V i s a / ) ) . not . toBeInTheDocument ( )
219
241
} )
220
242
221
243
it ( 'renders the form' , async ( ) => {
222
244
const { user } = setup ( )
223
- const updateCard = vi . fn ( )
224
- mocks . useUpdateCard . mockReturnValue ( {
225
- mutate : updateCard ,
245
+ const updatePaymentMethod = vi . fn ( )
246
+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
247
+ mutate : updatePaymentMethod ,
226
248
isLoading : false ,
227
249
} )
228
250
render (
@@ -233,21 +255,23 @@ describe('PaymentCard', () => {
233
255
/> ,
234
256
{ wrapper }
235
257
)
236
- await user . click ( screen . getByTestId ( 'edit-card ' ) )
258
+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
237
259
238
- expect (
239
- screen . getByRole ( 'button' , { name : / u p d a t e / i } )
240
- ) . toBeInTheDocument ( )
260
+ expect ( screen . getByTestId ( 'save-payment-method' ) ) . toBeInTheDocument ( )
241
261
} )
242
262
243
263
describe ( 'when submitting' , ( ) => {
244
264
it ( 'calls the service to update the card' , async ( ) => {
245
265
const { user } = setup ( )
246
- const updateCard = vi . fn ( )
247
- mocks . useUpdateCard . mockReturnValue ( {
248
- mutate : updateCard ,
266
+ const updatePaymentMethod = vi . fn ( )
267
+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
268
+ mutate : updatePaymentMethod ,
249
269
isLoading : false ,
250
270
} )
271
+ mocks . useCreateStripeSetupIntent . mockReturnValue ( {
272
+ data : { clientSecret : 'test-secret' } ,
273
+ } )
274
+
251
275
render (
252
276
< PaymentCard
253
277
subscriptionDetail = { subscriptionDetail }
@@ -256,17 +280,17 @@ describe('PaymentCard', () => {
256
280
/> ,
257
281
{ wrapper }
258
282
)
259
- await user . click ( screen . getByTestId ( 'edit-card ' ) )
260
- await user . click ( screen . queryByRole ( 'button' , { name : / u p d a t e / i } ) )
283
+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
284
+ await user . click ( screen . getByTestId ( 'save-payment-method' ) )
261
285
262
- expect ( updateCard ) . toHaveBeenCalled ( )
286
+ expect ( updatePaymentMethod ) . toHaveBeenCalled ( )
263
287
} )
264
288
} )
265
289
266
290
describe ( 'when the user clicks on cancel' , ( ) => {
267
291
it ( `doesn't render the form anymore` , async ( ) => {
268
292
const { user } = setup ( )
269
- mocks . useUpdateCard . mockReturnValue ( {
293
+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
270
294
mutate : vi . fn ( ) ,
271
295
isLoading : false ,
272
296
} )
@@ -279,11 +303,11 @@ describe('PaymentCard', () => {
279
303
{ wrapper }
280
304
)
281
305
282
- await user . click ( screen . getByTestId ( 'edit-card ' ) )
283
- await user . click ( screen . getByRole ( 'button' , { name : / C a n c e l / } ) )
306
+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
307
+ await user . click ( screen . getByTestId ( 'cancel-payment' ) )
284
308
285
309
expect (
286
- screen . queryByRole ( 'button' , { name : / s a v e / i } )
310
+ screen . queryByTestId ( 'update-payment-method' )
287
311
) . not . toBeInTheDocument ( )
288
312
} )
289
313
} )
@@ -293,7 +317,7 @@ describe('PaymentCard', () => {
293
317
it ( 'renders the error' , async ( ) => {
294
318
const { user } = setup ( )
295
319
const randomError = 'not rich enough'
296
- mocks . useUpdateCard . mockReturnValue ( {
320
+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
297
321
mutate : vi . fn ( ) ,
298
322
error : { message : randomError } ,
299
323
} )
@@ -306,7 +330,7 @@ describe('PaymentCard', () => {
306
330
{ wrapper }
307
331
)
308
332
309
- await user . click ( screen . getByTestId ( 'edit-card ' ) )
333
+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
310
334
311
335
expect ( screen . getByText ( randomError ) ) . toBeInTheDocument ( )
312
336
} )
@@ -315,7 +339,7 @@ describe('PaymentCard', () => {
315
339
describe ( 'when the form is loading' , ( ) => {
316
340
it ( 'has the error and save button disabled' , async ( ) => {
317
341
const { user } = setup ( )
318
- mocks . useUpdateCard . mockReturnValue ( {
342
+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
319
343
mutate : vi . fn ( ) ,
320
344
isLoading : true ,
321
345
} )
@@ -327,10 +351,10 @@ describe('PaymentCard', () => {
327
351
/> ,
328
352
{ wrapper }
329
353
)
330
- await user . click ( screen . getByTestId ( 'edit-card ' ) )
354
+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
331
355
332
- expect ( screen . queryByRole ( 'button' , { name : / u p d a t e / i } ) ) . toBeDisabled ( )
333
- expect ( screen . queryByRole ( 'button' , { name : / c a n c e l / i } ) ) . toBeDisabled ( )
356
+ expect ( screen . getByTestId ( 'save-payment-method' ) ) . toBeDisabled ( )
357
+ expect ( screen . getByTestId ( ' cancel-payment' ) ) . toBeDisabled ( )
334
358
} )
335
359
} )
336
360
} )
0 commit comments