@@ -20,6 +20,8 @@ const mockUseOrder = jest.fn()
2020const mockUpdatePaymentInstrumentForOrder = jest . fn ( )
2121const mockFailOrder = jest . fn ( )
2222const mockGetSFPaymentsInstrument = jest . fn ( )
23+ const mockRefetchOrder = jest . fn ( )
24+ const mockInvalidateQueries = jest . fn ( )
2325
2426jest . mock ( '@salesforce/retail-react-app/app/hooks/use-navigation' , ( ) => ( {
2527 __esModule : true ,
@@ -53,6 +55,16 @@ jest.mock('@salesforce/commerce-sdk-react', () => {
5355 }
5456} )
5557
58+ jest . mock ( '@tanstack/react-query' , ( ) => {
59+ const actual = jest . requireActual ( '@tanstack/react-query' )
60+ return {
61+ ...actual ,
62+ useQueryClient : ( ) => ( {
63+ invalidateQueries : mockInvalidateQueries
64+ } )
65+ }
66+ } )
67+
5668jest . mock ( '@salesforce/retail-react-app/app/utils/sf-payments-utils' , ( ) => ( {
5769 getSFPaymentsInstrument : ( ) => mockGetSFPaymentsInstrument ( )
5870} ) )
@@ -83,8 +95,13 @@ describe('PaymentProcessing', () => {
8395
8496 mockUseOrder . mockReturnValue ( {
8597 data : {
86- orderNo : '12345'
87- }
98+ orderNo : '12345' ,
99+ status : 'created'
100+ } ,
101+ refetch : mockRefetchOrder
102+ } )
103+ mockRefetchOrder . mockResolvedValue ( {
104+ data : { orderNo : '12345' , status : 'created' }
88105 } )
89106
90107 mockUpdatePaymentInstrumentForOrder . mockReturnValue ( { } )
@@ -196,6 +213,13 @@ describe('PaymentProcessing', () => {
196213
197214 test ( 'renders error message for invalid Adyen URL missing type' , async ( ) => {
198215 mockLocation . search = '?vendor=Adyen&orderNo=12345&zoneId=default&redirectResult=ABC123'
216+ mockUseOrder . mockReturnValue ( {
217+ data : { orderNo : '12345' } ,
218+ refetch : mockRefetchOrder
219+ } )
220+ mockRefetchOrder . mockResolvedValue ( {
221+ data : { orderNo : '12345' , status : 'created' }
222+ } )
199223
200224 renderWithProviders ( < PaymentProcessing /> )
201225
@@ -205,6 +229,7 @@ describe('PaymentProcessing', () => {
205229 expect ( screen . getByText ( 'Return to Checkout' ) ) . toBeInTheDocument ( )
206230
207231 await waitFor ( ( ) => {
232+ expect ( mockRefetchOrder ) . toHaveBeenCalled ( )
208233 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
209234 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
210235 parameters : {
@@ -220,6 +245,13 @@ describe('PaymentProcessing', () => {
220245
221246 test ( 'renders error message for invalid Adyen URL missing zone id' , async ( ) => {
222247 mockLocation . search = '?vendor=Adyen&orderNo=12345&type=klarna&redirectResult=ABC123'
248+ mockUseOrder . mockReturnValue ( {
249+ data : { orderNo : '12345' } ,
250+ refetch : mockRefetchOrder
251+ } )
252+ mockRefetchOrder . mockResolvedValue ( {
253+ data : { orderNo : '12345' , status : 'created' }
254+ } )
223255
224256 renderWithProviders ( < PaymentProcessing /> )
225257
@@ -229,6 +261,7 @@ describe('PaymentProcessing', () => {
229261 expect ( screen . getByText ( 'Return to Checkout' ) ) . toBeInTheDocument ( )
230262
231263 await waitFor ( ( ) => {
264+ expect ( mockRefetchOrder ) . toHaveBeenCalled ( )
232265 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
233266 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
234267 parameters : {
@@ -244,6 +277,13 @@ describe('PaymentProcessing', () => {
244277
245278 test ( 'renders error message for invalid Adyen URL missing redirect result' , async ( ) => {
246279 mockLocation . search = '?vendor=Adyen&orderNo=12345&type=klarna&zoneId=default'
280+ mockUseOrder . mockReturnValue ( {
281+ data : { orderNo : '12345' } ,
282+ refetch : mockRefetchOrder
283+ } )
284+ mockRefetchOrder . mockResolvedValue ( {
285+ data : { orderNo : '12345' , status : 'created' }
286+ } )
247287
248288 renderWithProviders ( < PaymentProcessing /> )
249289
@@ -253,6 +293,7 @@ describe('PaymentProcessing', () => {
253293 expect ( screen . getByText ( 'Return to Checkout' ) ) . toBeInTheDocument ( )
254294
255295 await waitFor ( ( ) => {
296+ expect ( mockRefetchOrder ) . toHaveBeenCalled ( )
256297 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
257298 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
258299 parameters : {
@@ -392,6 +433,9 @@ describe('PaymentProcessing', () => {
392433
393434 test ( 'shows toast and calls failOrder before navigating on failed payment' , async ( ) => {
394435 mockHandleRedirect . mockResolvedValue ( { responseCode : 1 } )
436+ mockRefetchOrder . mockResolvedValue ( {
437+ data : { orderNo : '12345' , status : 'created' }
438+ } )
395439
396440 renderWithProviders ( < PaymentProcessing /> )
397441
@@ -400,6 +444,7 @@ describe('PaymentProcessing', () => {
400444 } )
401445
402446 await waitFor ( ( ) => {
447+ expect ( mockRefetchOrder ) . toHaveBeenCalled ( )
403448 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
404449 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
405450 parameters : {
@@ -415,12 +460,55 @@ describe('PaymentProcessing', () => {
415460 expect ( mockNavigate ) . toHaveBeenCalledWith ( '/checkout' )
416461 } )
417462
463+ test ( 'does not call failOrder when order already failed by webhook' , async ( ) => {
464+ mockHandleRedirect . mockResolvedValue ( { responseCode : 1 } )
465+ mockRefetchOrder . mockResolvedValue ( {
466+ data : { orderNo : '12345' , status : 'failed' }
467+ } )
468+
469+ renderWithProviders ( < PaymentProcessing /> )
470+
471+ await waitFor ( ( ) => {
472+ expect ( mockToast ) . toHaveBeenCalled ( )
473+ expect ( mockNavigate ) . toHaveBeenCalledWith ( '/checkout' )
474+ } )
475+
476+ expect ( mockRefetchOrder ) . toHaveBeenCalled ( )
477+ expect ( mockFailOrder ) . not . toHaveBeenCalled ( )
478+ } )
479+
480+ test ( 'shows toast and navigates to checkout when failOrder fails' , async ( ) => {
481+ mockHandleRedirect . mockResolvedValue ( { responseCode : 1 } )
482+ mockRefetchOrder . mockResolvedValue ( {
483+ data : { orderNo : '12345' , status : 'created' }
484+ } )
485+ mockFailOrder . mockRejectedValue ( new Error ( 'Order already failed' ) )
486+
487+ renderWithProviders ( < PaymentProcessing /> )
488+
489+ await waitFor ( ( ) => {
490+ expect ( mockToast ) . toHaveBeenCalled ( )
491+ expect ( mockNavigate ) . toHaveBeenCalledWith ( '/checkout' )
492+ } )
493+
494+ expect ( mockRefetchOrder ) . toHaveBeenCalled ( )
495+ expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
496+ expect ( mockInvalidateQueries ) . toHaveBeenCalled ( )
497+ } )
498+
418499 test ( 'handles different error response codes' , async ( ) => {
419500 const errorCodes = [ 1 , 2 , - 1 , 999 ]
420501
421502 for ( const code of errorCodes ) {
422503 jest . clearAllMocks ( )
423504 mockHandleRedirect . mockResolvedValue ( { responseCode : code } )
505+ mockUseOrder . mockReturnValue ( {
506+ data : { orderNo : '12345' , status : 'created' } ,
507+ refetch : mockRefetchOrder
508+ } )
509+ mockRefetchOrder . mockResolvedValue ( {
510+ data : { orderNo : '12345' , status : 'created' }
511+ } )
424512
425513 renderWithProviders ( < PaymentProcessing /> )
426514
@@ -545,13 +633,18 @@ describe('PaymentProcessing', () => {
545633 } )
546634
547635 test ( 'shows toast and calls failOrder before navigating on failed payment' , async ( ) => {
636+ mockRefetchOrder . mockResolvedValue ( {
637+ data : { orderNo : '12345' , status : 'created' }
638+ } )
639+
548640 renderWithProviders ( < PaymentProcessing /> )
549641
550642 await waitFor ( ( ) => {
551643 expect ( mockToast ) . toHaveBeenCalled ( )
552644 } )
553645
554646 await waitFor ( ( ) => {
647+ expect ( mockRefetchOrder ) . toHaveBeenCalled ( )
555648 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
556649 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
557650 parameters : {
0 commit comments