@@ -20,6 +20,9 @@ const mockUseOrder = jest.fn()
2020const mockUpdatePaymentInstrumentForOrder = jest . fn ( )
2121const mockFailOrder = jest . fn ( )
2222const mockGetSFPaymentsInstrument = jest . fn ( )
23+ const mockGetOrder = jest . fn ( )
24+ const mockGetTokenWhenReady = jest . fn ( )
25+ const mockInvalidateQueries = jest . fn ( )
2326
2427jest . mock ( '@salesforce/retail-react-app/app/hooks/use-navigation' , ( ) => ( {
2528 __esModule : true ,
@@ -40,6 +43,14 @@ jest.mock('@salesforce/commerce-sdk-react', () => {
4043 const actual = jest . requireActual ( '@salesforce/commerce-sdk-react' )
4144 return {
4245 ...actual ,
46+ useCommerceApi : ( ) => ( {
47+ shopperOrders : {
48+ getOrder : mockGetOrder
49+ }
50+ } ) ,
51+ useAccessToken : ( ) => ( {
52+ getTokenWhenReady : mockGetTokenWhenReady
53+ } ) ,
4354 useShopperOrdersMutation : ( mutationKey ) => {
4455 if ( mutationKey === 'updatePaymentInstrumentForOrder' ) {
4556 return { mutateAsync : mockUpdatePaymentInstrumentForOrder }
@@ -53,6 +64,16 @@ jest.mock('@salesforce/commerce-sdk-react', () => {
5364 }
5465} )
5566
67+ jest . mock ( '@tanstack/react-query' , ( ) => {
68+ const actual = jest . requireActual ( '@tanstack/react-query' )
69+ return {
70+ ...actual ,
71+ useQueryClient : ( ) => ( {
72+ invalidateQueries : mockInvalidateQueries
73+ } )
74+ }
75+ } )
76+
5677jest . mock ( '@salesforce/retail-react-app/app/utils/sf-payments-utils' , ( ) => ( {
5778 getSFPaymentsInstrument : ( ) => mockGetSFPaymentsInstrument ( )
5879} ) )
@@ -90,6 +111,9 @@ describe('PaymentProcessing', () => {
90111 mockUpdatePaymentInstrumentForOrder . mockReturnValue ( { } )
91112
92113 mockGetSFPaymentsInstrument . mockReturnValue ( { } )
114+
115+ mockGetOrder . mockResolvedValue ( { status : 'created' } )
116+ mockGetTokenWhenReady . mockResolvedValue ( 'token' )
93117 } )
94118
95119 afterEach ( ( ) => {
@@ -205,6 +229,7 @@ describe('PaymentProcessing', () => {
205229 expect ( screen . getByText ( 'Return to Checkout' ) ) . toBeInTheDocument ( )
206230
207231 await waitFor ( ( ) => {
232+ expect ( mockGetOrder ) . toHaveBeenCalled ( )
208233 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
209234 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
210235 parameters : {
@@ -229,6 +254,7 @@ describe('PaymentProcessing', () => {
229254 expect ( screen . getByText ( 'Return to Checkout' ) ) . toBeInTheDocument ( )
230255
231256 await waitFor ( ( ) => {
257+ expect ( mockGetOrder ) . toHaveBeenCalled ( )
232258 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
233259 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
234260 parameters : {
@@ -253,6 +279,7 @@ describe('PaymentProcessing', () => {
253279 expect ( screen . getByText ( 'Return to Checkout' ) ) . toBeInTheDocument ( )
254280
255281 await waitFor ( ( ) => {
282+ expect ( mockGetOrder ) . toHaveBeenCalled ( )
256283 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
257284 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
258285 parameters : {
@@ -380,13 +407,13 @@ describe('PaymentProcessing', () => {
380407 } )
381408 } )
382409
383- test ( 'navigates back to checkout on failed payment' , async ( ) => {
410+ test ( 'navigates to cart on failed payment' , async ( ) => {
384411 mockHandleRedirect . mockResolvedValue ( { responseCode : 1 } )
385412
386413 renderWithProviders ( < PaymentProcessing /> )
387414
388415 await waitFor ( ( ) => {
389- expect ( mockNavigate ) . toHaveBeenCalledWith ( '/checkout ' )
416+ expect ( mockNavigate ) . toHaveBeenCalledWith ( '/cart ' )
390417 } )
391418 } )
392419
@@ -400,6 +427,7 @@ describe('PaymentProcessing', () => {
400427 } )
401428
402429 await waitFor ( ( ) => {
430+ expect ( mockGetOrder ) . toHaveBeenCalled ( )
403431 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
404432 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
405433 parameters : {
@@ -412,7 +440,22 @@ describe('PaymentProcessing', () => {
412440 } )
413441 } )
414442
415- expect ( mockNavigate ) . toHaveBeenCalledWith ( '/checkout' )
443+ expect ( mockNavigate ) . toHaveBeenCalledWith ( '/cart' )
444+ } )
445+
446+ test ( 'does not call failOrder when order already failed by webhook (e.g. 3DS declined)' , async ( ) => {
447+ mockHandleRedirect . mockResolvedValue ( { responseCode : 1 } )
448+ mockGetOrder . mockResolvedValue ( { status : 'failed' } )
449+
450+ renderWithProviders ( < PaymentProcessing /> )
451+
452+ await waitFor ( ( ) => {
453+ expect ( mockToast ) . toHaveBeenCalled ( )
454+ expect ( mockNavigate ) . toHaveBeenCalledWith ( '/cart' )
455+ } )
456+
457+ expect ( mockGetOrder ) . toHaveBeenCalled ( )
458+ expect ( mockFailOrder ) . not . toHaveBeenCalled ( )
416459 } )
417460
418461 test ( 'handles different error response codes' , async ( ) => {
@@ -421,12 +464,14 @@ describe('PaymentProcessing', () => {
421464 for ( const code of errorCodes ) {
422465 jest . clearAllMocks ( )
423466 mockHandleRedirect . mockResolvedValue ( { responseCode : code } )
467+ mockGetOrder . mockResolvedValue ( { status : 'created' } )
468+ mockGetTokenWhenReady . mockResolvedValue ( 'token' )
424469
425470 renderWithProviders ( < PaymentProcessing /> )
426471
427472 await waitFor ( ( ) => {
428473 expect ( mockToast ) . toHaveBeenCalled ( )
429- expect ( mockNavigate ) . toHaveBeenCalledWith ( '/checkout ' )
474+ expect ( mockNavigate ) . toHaveBeenCalledWith ( '/cart ' )
430475 } )
431476 }
432477 } )
@@ -536,11 +581,11 @@ describe('PaymentProcessing', () => {
536581 } )
537582 } )
538583
539- test ( 'navigates back to checkout on failed payment' , async ( ) => {
584+ test ( 'navigates to cart on failed payment' , async ( ) => {
540585 renderWithProviders ( < PaymentProcessing /> )
541586
542587 await waitFor ( ( ) => {
543- expect ( mockNavigate ) . toHaveBeenCalledWith ( '/checkout ' )
588+ expect ( mockNavigate ) . toHaveBeenCalledWith ( '/cart ' )
544589 } )
545590 } )
546591
@@ -552,6 +597,7 @@ describe('PaymentProcessing', () => {
552597 } )
553598
554599 await waitFor ( ( ) => {
600+ expect ( mockGetOrder ) . toHaveBeenCalled ( )
555601 expect ( mockFailOrder ) . toHaveBeenCalledTimes ( 1 )
556602 expect ( mockFailOrder ) . toHaveBeenCalledWith ( {
557603 parameters : {
@@ -564,7 +610,7 @@ describe('PaymentProcessing', () => {
564610 } )
565611 } )
566612
567- expect ( mockNavigate ) . toHaveBeenCalledWith ( '/checkout ' )
613+ expect ( mockNavigate ) . toHaveBeenCalledWith ( '/cart ' )
568614 } )
569615 } )
570616 } )
0 commit comments