1+ import { QueryClient , QueryClientProvider } from '@tanstack/react-query'
12import { render , screen } from '@testing-library/react'
23import userEvent from '@testing-library/user-event'
34
@@ -6,18 +7,37 @@ import { Plans } from 'shared/utils/billing'
67
78import PaymentCard from './PaymentCard'
89
10+ const queryClient = new QueryClient ( )
11+
912const mocks = vi . hoisted ( ( ) => ( {
10- useUpdateCard : vi . fn ( ) ,
13+ useUpdatePaymentMethod : vi . fn ( ) ,
14+ useCreateStripeSetupIntent : vi . fn ( ) ,
1115} ) )
1216
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+ )
1521 return {
1622 ...actual ,
17- useUpdateCard : mocks . useUpdateCard ,
23+ useUpdatePaymentMethod : mocks . useUpdatePaymentMethod ,
1824 }
1925} )
2026
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+
2141const subscriptionDetail = {
2242 defaultPaymentMethod : {
2343 card : {
@@ -35,7 +55,9 @@ const subscriptionDetail = {
3555}
3656
3757const wrapper = ( { children } ) => (
38- < ThemeContextProvider > { children } </ ThemeContextProvider >
58+ < QueryClientProvider client = { queryClient } >
59+ < ThemeContextProvider > { children } </ ThemeContextProvider >
60+ </ QueryClientProvider >
3961)
4062
4163// mocking all the stripe components; and trusting the library :)
@@ -48,9 +70,11 @@ vi.mock('@stripe/react-stripe-js', () => {
4870 return {
4971 useElements : ( ) => ( {
5072 getElement : vi . fn ( ) ,
73+ submit : vi . fn ( ) ,
5174 } ) ,
5275 useStripe : ( ) => ( { } ) ,
53- CardElement : makeFakeComponent ( 'CardElement' ) ,
76+ PaymentElement : makeFakeComponent ( 'PaymentElement' ) ,
77+ Elements : makeFakeComponent ( 'Elements' ) ,
5478 }
5579} )
5680
@@ -64,20 +88,20 @@ describe('PaymentCard', () => {
6488 describe ( `when the user doesn't have any subscriptionDetail` , ( ) => {
6589 // NOTE: This test is misleading because we hide this component from a higher level in
6690 // BillingDetails.tsx if there is no subscriptionDetail
67- it ( 'renders the set card message' , ( ) => {
91+ it ( 'renders the set payment method message' , ( ) => {
6892 render (
6993 < PaymentCard subscriptionDetail = { null } provider = "gh" owner = "codecov" />
7094 )
7195
7296 expect (
7397 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 ./
7599 )
76100 ) . toBeInTheDocument ( )
77101 } )
78102 } )
79103
80- describe ( `when the user doesn't have any card ` , ( ) => {
104+ describe ( `when the user doesn't have any payment method ` , ( ) => {
81105 it ( 'renders an error message' , ( ) => {
82106 render (
83107 < PaymentCard
@@ -93,7 +117,7 @@ describe('PaymentCard', () => {
93117
94118 expect (
95119 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 ./
97121 )
98122 ) . toBeInTheDocument ( )
99123 } )
@@ -113,7 +137,7 @@ describe('PaymentCard', () => {
113137 { wrapper }
114138 )
115139
116- mocks . useUpdateCard . mockReturnValue ( {
140+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
117141 mutate : ( ) => null ,
118142 isLoading : false ,
119143 } )
@@ -136,15 +160,13 @@ describe('PaymentCard', () => {
136160 { wrapper }
137161 )
138162
139- mocks . useUpdateCard . mockReturnValue ( {
163+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
140164 mutate : ( ) => null ,
141165 isLoading : false ,
142166 } )
143167 await user . click ( screen . getByTestId ( 'open-modal' ) )
144168
145- expect (
146- screen . getByRole ( 'button' , { name : / u p d a t e / i } )
147- ) . toBeInTheDocument ( )
169+ expect ( screen . getByTestId ( 'save-payment-method' ) ) . toBeInTheDocument ( )
148170 } )
149171 } )
150172 } )
@@ -199,9 +221,9 @@ describe('PaymentCard', () => {
199221 describe ( 'when the user clicks on Edit card' , ( ) => {
200222 it ( `doesn't render the card anymore` , async ( ) => {
201223 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 ,
205227 isLoading : false ,
206228 } )
207229
@@ -213,16 +235,16 @@ describe('PaymentCard', () => {
213235 /> ,
214236 { wrapper }
215237 )
216- await user . click ( screen . getByTestId ( 'edit-card ' ) )
238+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
217239
218240 expect ( screen . queryByText ( / V i s a / ) ) . not . toBeInTheDocument ( )
219241 } )
220242
221243 it ( 'renders the form' , async ( ) => {
222244 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 ,
226248 isLoading : false ,
227249 } )
228250 render (
@@ -233,21 +255,23 @@ describe('PaymentCard', () => {
233255 /> ,
234256 { wrapper }
235257 )
236- await user . click ( screen . getByTestId ( 'edit-card ' ) )
258+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
237259
238- expect (
239- screen . getByRole ( 'button' , { name : / u p d a t e / i } )
240- ) . toBeInTheDocument ( )
260+ expect ( screen . getByTestId ( 'save-payment-method' ) ) . toBeInTheDocument ( )
241261 } )
242262
243263 describe ( 'when submitting' , ( ) => {
244264 it ( 'calls the service to update the card' , async ( ) => {
245265 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 ,
249269 isLoading : false ,
250270 } )
271+ mocks . useCreateStripeSetupIntent . mockReturnValue ( {
272+ data : { clientSecret : 'test-secret' } ,
273+ } )
274+
251275 render (
252276 < PaymentCard
253277 subscriptionDetail = { subscriptionDetail }
@@ -256,17 +280,17 @@ describe('PaymentCard', () => {
256280 /> ,
257281 { wrapper }
258282 )
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' ) )
261285
262- expect ( updateCard ) . toHaveBeenCalled ( )
286+ expect ( updatePaymentMethod ) . toHaveBeenCalled ( )
263287 } )
264288 } )
265289
266290 describe ( 'when the user clicks on cancel' , ( ) => {
267291 it ( `doesn't render the form anymore` , async ( ) => {
268292 const { user } = setup ( )
269- mocks . useUpdateCard . mockReturnValue ( {
293+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
270294 mutate : vi . fn ( ) ,
271295 isLoading : false ,
272296 } )
@@ -279,11 +303,11 @@ describe('PaymentCard', () => {
279303 { wrapper }
280304 )
281305
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' ) )
284308
285309 expect (
286- screen . queryByRole ( 'button' , { name : / s a v e / i } )
310+ screen . queryByTestId ( 'update-payment-method' )
287311 ) . not . toBeInTheDocument ( )
288312 } )
289313 } )
@@ -293,7 +317,7 @@ describe('PaymentCard', () => {
293317 it ( 'renders the error' , async ( ) => {
294318 const { user } = setup ( )
295319 const randomError = 'not rich enough'
296- mocks . useUpdateCard . mockReturnValue ( {
320+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
297321 mutate : vi . fn ( ) ,
298322 error : { message : randomError } ,
299323 } )
@@ -306,7 +330,7 @@ describe('PaymentCard', () => {
306330 { wrapper }
307331 )
308332
309- await user . click ( screen . getByTestId ( 'edit-card ' ) )
333+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
310334
311335 expect ( screen . getByText ( randomError ) ) . toBeInTheDocument ( )
312336 } )
@@ -315,7 +339,7 @@ describe('PaymentCard', () => {
315339 describe ( 'when the form is loading' , ( ) => {
316340 it ( 'has the error and save button disabled' , async ( ) => {
317341 const { user } = setup ( )
318- mocks . useUpdateCard . mockReturnValue ( {
342+ mocks . useUpdatePaymentMethod . mockReturnValue ( {
319343 mutate : vi . fn ( ) ,
320344 isLoading : true ,
321345 } )
@@ -327,10 +351,10 @@ describe('PaymentCard', () => {
327351 /> ,
328352 { wrapper }
329353 )
330- await user . click ( screen . getByTestId ( 'edit-card ' ) )
354+ await user . click ( screen . getByTestId ( 'edit-payment-method ' ) )
331355
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 ( )
334358 } )
335359 } )
336360} )
0 commit comments