@@ -305,6 +305,35 @@ const createMockOrder = (overrides = {}) => ({
305305 ...overrides
306306} )
307307
308+ const setupConfirmPaymentMocks = ( ) => {
309+ const mockOrder = createMockOrder ( )
310+ mockUpdateBillingAddress . mockResolvedValue ( {
311+ ...mockBasket ,
312+ billingAddress : mockBasket . shipments [ 0 ] . shippingAddress ,
313+ paymentInstruments : [ ]
314+ } )
315+ mockAddPaymentInstrument . mockResolvedValue ( {
316+ ...mockBasket ,
317+ paymentInstruments : [
318+ {
319+ paymentInstrumentId : 'PI123' ,
320+ paymentMethodId : 'Salesforce Payments' ,
321+ paymentReference : {
322+ clientSecret : 'secret123' ,
323+ paymentReferenceId : 'ref123'
324+ }
325+ }
326+ ]
327+ } )
328+ mockOnCreateOrder . mockResolvedValue ( mockOrder )
329+ mockUpdatePaymentInstrument . mockResolvedValue ( mockOrder )
330+ mockCheckoutConfirm . mockResolvedValue ( {
331+ responseCode : STATUS_SUCCESS ,
332+ data : { }
333+ } )
334+ return mockOrder
335+ }
336+
308337describe ( 'SFPaymentsSheet' , ( ) => {
309338 const mockRef = { current : null }
310339
@@ -820,6 +849,152 @@ describe('SFPaymentsSheet', () => {
820849 { timeout : 3000 }
821850 )
822851 } )
852+
853+ test ( 'confirmPayment calls confirm with setup_future_usage when savePaymentMethodForFutureUse event was fired' , async ( ) => {
854+ const ref = React . createRef ( )
855+ setupConfirmPaymentMocks ( )
856+
857+ renderWithCheckoutContext (
858+ < SFPaymentsSheet
859+ ref = { ref }
860+ onCreateOrder = { mockOnCreateOrder }
861+ onError = { mockOnError }
862+ />
863+ )
864+
865+ await waitFor ( ( ) => {
866+ expect ( ref . current ) . toBeDefined ( )
867+ } )
868+
869+ await waitFor ( ( ) => {
870+ expect ( mockCheckout ) . toHaveBeenCalled ( )
871+ } )
872+
873+ const paymentElement = mockCheckout . mock . calls [ 0 ] [ 4 ]
874+
875+ await act ( async ( ) => {
876+ paymentElement . dispatchEvent (
877+ new CustomEvent ( 'sfp:paymentmethodselected' , {
878+ bubbles : true ,
879+ composed : true ,
880+ detail : {
881+ selectedPaymentMethod : 'card' ,
882+ savePaymentMethodForFutureUse : true
883+ }
884+ } )
885+ )
886+ } )
887+
888+ await ref . current . confirmPayment ( )
889+
890+ await waitFor ( ( ) => {
891+ expect ( mockCheckoutConfirm ) . toHaveBeenCalled ( )
892+ } )
893+
894+ const confirmCall = mockCheckoutConfirm . mock . calls [ 0 ]
895+ const paymentIntentFunction = confirmCall [ 0 ]
896+ const paymentIntent = await paymentIntentFunction ( )
897+
898+ expect ( paymentIntent . setup_future_usage ) . toBe ( 'on_session' )
899+ } )
900+
901+ test ( 'confirmPayment reads savePaymentMethodRef and passes it to createAndUpdateOrder when event was fired' , async ( ) => {
902+ const ref = React . createRef ( )
903+ setupConfirmPaymentMocks ( )
904+
905+ renderWithCheckoutContext (
906+ < SFPaymentsSheet
907+ ref = { ref }
908+ onCreateOrder = { mockOnCreateOrder }
909+ onError = { mockOnError }
910+ />
911+ )
912+
913+ await waitFor ( ( ) => {
914+ expect ( ref . current ) . toBeDefined ( )
915+ } )
916+
917+ await waitFor ( ( ) => {
918+ expect ( mockCheckout ) . toHaveBeenCalled ( )
919+ } )
920+
921+ const paymentElement = mockCheckout . mock . calls [ 0 ] [ 4 ]
922+
923+ await act ( async ( ) => {
924+ paymentElement . dispatchEvent (
925+ new CustomEvent ( 'sfp:paymentmethodselected' , {
926+ bubbles : true ,
927+ composed : true ,
928+ detail : {
929+ selectedPaymentMethod : 'card' ,
930+ savePaymentMethodForFutureUse : true
931+ }
932+ } )
933+ )
934+ } )
935+
936+ await ref . current . confirmPayment ( )
937+
938+ await waitFor ( ( ) => {
939+ expect ( mockUpdatePaymentInstrument ) . toHaveBeenCalled ( )
940+ } )
941+
942+ const updateCall = mockUpdatePaymentInstrument . mock . calls [ 0 ]
943+ const requestBody = updateCall [ 0 ] . body
944+
945+ expect ( requestBody . paymentReferenceRequest . gateway ) . toBe ( 'stripe' )
946+ expect (
947+ requestBody . paymentReferenceRequest . gatewayProperties . stripe . setupFutureUsage
948+ ) . toBe ( 'on_session' )
949+ } )
950+
951+ test ( 'confirmPayment calls confirm without setup_future_usage when savePaymentMethodForFutureUse was false' , async ( ) => {
952+ const ref = React . createRef ( )
953+ setupConfirmPaymentMocks ( )
954+
955+ renderWithCheckoutContext (
956+ < SFPaymentsSheet
957+ ref = { ref }
958+ onCreateOrder = { mockOnCreateOrder }
959+ onError = { mockOnError }
960+ />
961+ )
962+
963+ await waitFor ( ( ) => {
964+ expect ( ref . current ) . toBeDefined ( )
965+ } )
966+
967+ await waitFor ( ( ) => {
968+ expect ( mockCheckout ) . toHaveBeenCalled ( )
969+ } )
970+
971+ const paymentElement = mockCheckout . mock . calls [ 0 ] [ 4 ]
972+
973+ await act ( async ( ) => {
974+ paymentElement . dispatchEvent (
975+ new CustomEvent ( 'sfp:paymentmethodselected' , {
976+ bubbles : true ,
977+ composed : true ,
978+ detail : {
979+ selectedPaymentMethod : 'card' ,
980+ savePaymentMethodForFutureUse : false
981+ }
982+ } )
983+ )
984+ } )
985+
986+ await ref . current . confirmPayment ( )
987+
988+ await waitFor ( ( ) => {
989+ expect ( mockCheckoutConfirm ) . toHaveBeenCalled ( )
990+ } )
991+
992+ const confirmCall = mockCheckoutConfirm . mock . calls [ 0 ]
993+ const paymentIntentFunction = confirmCall [ 0 ]
994+ const paymentIntent = await paymentIntentFunction ( )
995+
996+ expect ( paymentIntent . setup_future_usage ) . toBeUndefined ( )
997+ } )
823998 } )
824999
8251000 describe ( 'lifecycle' , ( ) => {
0 commit comments