@@ -101,7 +101,14 @@ jest.mock('@salesforce/commerce-sdk-react', () => {
101101 defaultShippingMethodId : 'DefaultShippingMethod'
102102 } ,
103103 refetch : mockRefetchShippingMethods
104- } )
104+ } ) ,
105+ useCustomerId : ( ) => 'customer123' ,
106+ useCustomerType : ( ) => ( {
107+ isRegistered : true ,
108+ isGuest : false ,
109+ customerType : 'registered'
110+ } ) ,
111+ useCustomer : jest . fn ( )
105112 }
106113} )
107114
@@ -139,15 +146,21 @@ jest.mock('@salesforce/retail-react-app/app/hooks/use-current-basket', () => ({
139146 useCurrentBasket : ( ) => mockUseCurrentBasket ( )
140147} ) )
141148
142- jest . mock ( '@salesforce/retail-react-app/app/hooks/use-current-customer' , ( ) => ( {
143- useCurrentCustomer : ( ) => ( {
144- data : {
145- customerId : 'customer123' ,
146- isGuest : false ,
147- isRegistered : true ,
148- email : 'test@example.com'
149- }
150- } )
149+ const mockCustomer = {
150+ customerId : 'customer123' ,
151+ isGuest : false ,
152+ isRegistered : true ,
153+ email : 'test@example.com' ,
154+ paymentMethodReferences : [ ]
155+ }
156+
157+ // Get the mocked useCustomer from commerce-sdk-react
158+ // eslint-disable-next-line @typescript-eslint/no-var-requires
159+ const mockUseCustomer = require ( '@salesforce/commerce-sdk-react' ) . useCustomer
160+
161+ // Set default implementation
162+ mockUseCustomer . mockImplementation ( ( ) => ( {
163+ data : mockCustomer
151164} ) )
152165
153166jest . mock ( '@salesforce/retail-react-app/app/hooks/use-einstein' , ( ) => {
@@ -995,6 +1008,187 @@ describe('SFPaymentsSheet', () => {
9951008
9961009 expect ( paymentIntent . setup_future_usage ) . toBeUndefined ( )
9971010 } )
1011+
1012+ test ( 'confirmPayment sets setup_future_usage to off_session when futureUsageOffSession is true' , async ( ) => {
1013+ const ref = React . createRef ( )
1014+ setupConfirmPaymentMocks ( )
1015+
1016+ // eslint-disable-next-line @typescript-eslint/no-var-requires
1017+ const useShopperConfigurationModule = require ( '@salesforce/retail-react-app/app/hooks/use-shopper-configuration' )
1018+ const originalMock = useShopperConfigurationModule . useShopperConfiguration
1019+
1020+ useShopperConfigurationModule . useShopperConfiguration = jest . fn ( ( configId ) => {
1021+ if ( configId === 'futureUsageOffSession' ) return true
1022+ if ( configId === 'cardCaptureAutomatic' ) return true
1023+ if ( configId === 'zoneId' ) return 'default'
1024+ return undefined
1025+ } )
1026+
1027+ renderWithCheckoutContext (
1028+ < SFPaymentsSheet
1029+ ref = { ref }
1030+ onCreateOrder = { mockOnCreateOrder }
1031+ onError = { mockOnError }
1032+ />
1033+ )
1034+
1035+ await waitFor ( ( ) => {
1036+ expect ( ref . current ) . toBeDefined ( )
1037+ } )
1038+
1039+ await waitFor ( ( ) => {
1040+ expect ( mockCheckout ) . toHaveBeenCalled ( )
1041+ } )
1042+
1043+ const paymentElement = mockCheckout . mock . calls [ 0 ] [ 4 ]
1044+
1045+ await act ( async ( ) => {
1046+ paymentElement . dispatchEvent (
1047+ new CustomEvent ( 'sfp:paymentmethodselected' , {
1048+ bubbles : true ,
1049+ composed : true ,
1050+ detail : {
1051+ selectedPaymentMethod : 'card' ,
1052+ savePaymentMethodForFutureUse : true
1053+ }
1054+ } )
1055+ )
1056+ } )
1057+
1058+ await ref . current . confirmPayment ( )
1059+
1060+ await waitFor ( ( ) => {
1061+ expect ( mockCheckoutConfirm ) . toHaveBeenCalled ( )
1062+ } )
1063+
1064+ const confirmCall = mockCheckoutConfirm . mock . calls [ 0 ]
1065+ const paymentIntentFunction = confirmCall [ 0 ]
1066+ const paymentIntent = await paymentIntentFunction ( )
1067+
1068+ expect ( paymentIntent . setup_future_usage ) . toBe ( 'off_session' )
1069+
1070+ useShopperConfigurationModule . useShopperConfiguration = originalMock
1071+ } )
1072+ } )
1073+
1074+ describe ( 'SPM (Saved Payment Methods) Display' , ( ) => {
1075+ beforeEach ( ( ) => {
1076+ jest . clearAllMocks ( )
1077+ mockCustomer . paymentMethodReferences = [ ]
1078+ mockUseCustomer . mockImplementation ( ( ) => ( {
1079+ data : { ...mockCustomer }
1080+ } ) )
1081+ } )
1082+
1083+ test ( 'passes empty savedPaymentMethods to SDK when customer has no payment method references' , async ( ) => {
1084+ mockCustomer . paymentMethodReferences = [ ]
1085+
1086+ renderWithCheckoutContext (
1087+ < SFPaymentsSheet
1088+ ref = { React . createRef ( ) }
1089+ onCreateOrder = { mockOnCreateOrder }
1090+ onError = { mockOnError }
1091+ />
1092+ )
1093+
1094+ await waitFor ( ( ) => {
1095+ expect ( mockCheckout ) . toHaveBeenCalled ( )
1096+ } )
1097+
1098+ const checkoutCall = mockCheckout . mock . calls [ 0 ]
1099+ const config = checkoutCall [ 2 ]
1100+
1101+ expect ( config . options . savedPaymentMethods ) . toEqual ( [ ] )
1102+ } )
1103+
1104+ test ( 'passes empty savedPaymentMethods to SDK when paymentMethodReferences is null' , async ( ) => {
1105+ mockCustomer . paymentMethodReferences = null
1106+
1107+ renderWithCheckoutContext (
1108+ < SFPaymentsSheet
1109+ ref = { React . createRef ( ) }
1110+ onCreateOrder = { mockOnCreateOrder }
1111+ onError = { mockOnError }
1112+ />
1113+ )
1114+
1115+ await waitFor ( ( ) => {
1116+ expect ( mockCheckout ) . toHaveBeenCalled ( )
1117+ } )
1118+
1119+ const checkoutCall = mockCheckout . mock . calls [ 0 ]
1120+ const config = checkoutCall [ 2 ]
1121+
1122+ expect ( config . options . savedPaymentMethods ) . toEqual ( [ ] )
1123+ } )
1124+
1125+ test ( 'passes empty savedPaymentMethods to SDK when paymentMethodReferences is undefined' , async ( ) => {
1126+ mockCustomer . paymentMethodReferences = undefined
1127+
1128+ renderWithCheckoutContext (
1129+ < SFPaymentsSheet
1130+ ref = { React . createRef ( ) }
1131+ onCreateOrder = { mockOnCreateOrder }
1132+ onError = { mockOnError }
1133+ />
1134+ )
1135+
1136+ await waitFor ( ( ) => {
1137+ expect ( mockCheckout ) . toHaveBeenCalled ( )
1138+ } )
1139+
1140+ const checkoutCall = mockCheckout . mock . calls [ 0 ]
1141+ const config = checkoutCall [ 2 ]
1142+
1143+ expect ( config . options . savedPaymentMethods ) . toEqual ( [ ] )
1144+ } )
1145+
1146+ test ( 'passes empty savedPaymentMethods to SDK when paymentMethodSetAccounts is missing' , async ( ) => {
1147+ mockCustomer . paymentMethodReferences = [
1148+ {
1149+ id : 'pm_123' ,
1150+ accountId : 'stripe-account-1' ,
1151+ type : 'card' ,
1152+ brand : 'visa' ,
1153+ last4 : '4242'
1154+ }
1155+ ]
1156+
1157+ jest . spyOn (
1158+ // eslint-disable-next-line @typescript-eslint/no-var-requires
1159+ require ( '@salesforce/commerce-sdk-react' ) ,
1160+ 'usePaymentConfiguration'
1161+ ) . mockReturnValue ( {
1162+ data : {
1163+ paymentMethods : [
1164+ {
1165+ id : 'card' ,
1166+ name : 'Card' ,
1167+ paymentMethodType : 'card' ,
1168+ accountId : 'stripe-account-1'
1169+ }
1170+ ] ,
1171+ paymentMethodSetAccounts : null
1172+ }
1173+ } )
1174+
1175+ renderWithCheckoutContext (
1176+ < SFPaymentsSheet
1177+ ref = { React . createRef ( ) }
1178+ onCreateOrder = { mockOnCreateOrder }
1179+ onError = { mockOnError }
1180+ />
1181+ )
1182+
1183+ await waitFor ( ( ) => {
1184+ expect ( mockCheckout ) . toHaveBeenCalled ( )
1185+ } )
1186+
1187+ const checkoutCall = mockCheckout . mock . calls [ 0 ]
1188+ const config = checkoutCall [ 2 ]
1189+
1190+ expect ( config . options . savedPaymentMethods ) . toEqual ( [ ] )
1191+ } )
9981192 } )
9991193
10001194 describe ( 'lifecycle' , ( ) => {
0 commit comments