@@ -666,6 +666,132 @@ describe('Payment Component', () => {
666666 expect ( checkboxAfter ) . toBeChecked ( )
667667 } )
668668
669+ test ( 'does not add payment again during registration when payment already exists on basket' , async ( ) => {
670+ const user = userEvent . setup ( )
671+ const mockAddPaymentInstrument = jest . fn ( ) . mockResolvedValue ( { } )
672+
673+ const basketWithPayment = {
674+ ...mockBasket ,
675+ paymentInstruments : [ mockPaymentInstruments [ 0 ] ]
676+ }
677+
678+ useShopperBasketsMutation . mockImplementation ( ( mutationType ) => {
679+ switch ( mutationType ) {
680+ case 'addPaymentInstrumentToBasket' :
681+ return { mutateAsync : mockAddPaymentInstrument }
682+ case 'updateBillingAddressForBasket' :
683+ return { mutateAsync : jest . fn ( ) . mockResolvedValue ( { } ) }
684+ case 'removePaymentInstrumentFromBasket' :
685+ return { mutateAsync : jest . fn ( ) . mockResolvedValue ( { } ) }
686+ default :
687+ return { mutateAsync : jest . fn ( ) }
688+ }
689+ } )
690+
691+ render (
692+ < TestWrapper
693+ basketData = { basketWithPayment }
694+ enableUserRegistration = { true }
695+ paymentMethodForm = { {
696+ handleSubmit : jest . fn ( ( callback ) => ( e ) => {
697+ e ?. preventDefault ?. ( )
698+ callback ( { } )
699+ } ) ,
700+ watch : jest . fn ( ( ) => ( { unsubscribe : jest . fn ( ) } ) ) ,
701+ getValues : jest . fn ( ( ) => ( {
702+ number : '4111111111111111' ,
703+ holder : 'John Doe' ,
704+ expiry : '12/25'
705+ } ) ) ,
706+ formState : { isSubmitting : false , isValid : true }
707+ } }
708+ />
709+ )
710+
711+ // Find and trigger user registration
712+ const registrationComponent = screen . getByTestId ( 'user-registration' )
713+ const triggerRegistrationButton =
714+ within ( registrationComponent ) . getByTestId ( 'trigger-registration' )
715+
716+ // Trigger registration
717+ await user . click ( triggerRegistrationButton )
718+
719+ // Wait for registration to complete
720+ await waitFor ( ( ) => {
721+ expect ( screen . getByTestId ( 'user-registration' ) ) . toBeInTheDocument ( )
722+ } )
723+
724+ // Verify payment was NOT added again (payment already exists on basket)
725+ // Payment should be transferred during basket merge, not added again
726+ expect ( mockAddPaymentInstrument ) . not . toHaveBeenCalled ( )
727+ } )
728+
729+ test ( 'does not add payment during registration even when payment form has values' , async ( ) => {
730+ const user = userEvent . setup ( )
731+ const mockAddPaymentInstrument = jest . fn ( ) . mockResolvedValue ( { } )
732+
733+ // Basket without payment initially, but payment will be on basket before registration
734+ // (since registration checkbox is disabled until payment is filled)
735+ const basketWithPayment = {
736+ ...mockBasket ,
737+ paymentInstruments : [ mockPaymentInstruments [ 0 ] ]
738+ }
739+
740+ useShopperBasketsMutation . mockImplementation ( ( mutationType ) => {
741+ switch ( mutationType ) {
742+ case 'addPaymentInstrumentToBasket' :
743+ return { mutateAsync : mockAddPaymentInstrument }
744+ case 'updateBillingAddressForBasket' :
745+ return { mutateAsync : jest . fn ( ) . mockResolvedValue ( { } ) }
746+ case 'removePaymentInstrumentFromBasket' :
747+ return { mutateAsync : jest . fn ( ) . mockResolvedValue ( { } ) }
748+ default :
749+ return { mutateAsync : jest . fn ( ) }
750+ }
751+ } )
752+
753+ const mockPaymentMethodForm = {
754+ handleSubmit : jest . fn ( ( callback ) => ( e ) => {
755+ e ?. preventDefault ?. ( )
756+ callback ( { } )
757+ } ) ,
758+ watch : jest . fn ( ( ) => ( { unsubscribe : jest . fn ( ) } ) ) ,
759+ getValues : jest . fn ( ( ) => ( {
760+ number : '4111111111111111' ,
761+ holder : 'John Doe' ,
762+ expiry : '12/25' ,
763+ cardType : 'Visa'
764+ } ) ) ,
765+ formState : { isSubmitting : false , isValid : true }
766+ }
767+
768+ render (
769+ < TestWrapper
770+ basketData = { basketWithPayment }
771+ enableUserRegistration = { true }
772+ paymentMethodForm = { mockPaymentMethodForm }
773+ />
774+ )
775+
776+ // Find and trigger user registration
777+ const registrationComponent = screen . getByTestId ( 'user-registration' )
778+ const triggerRegistrationButton =
779+ within ( registrationComponent ) . getByTestId ( 'trigger-registration' )
780+
781+ // Trigger registration
782+ await user . click ( triggerRegistrationButton )
783+
784+ // Wait for registration to complete
785+ await waitFor ( ( ) => {
786+ expect ( screen . getByTestId ( 'user-registration' ) ) . toBeInTheDocument ( )
787+ } )
788+
789+ // Verify payment was NOT added again
790+ // Payment is already on basket (registration requires payment to be filled first)
791+ // Basket transfer/merge will preserve the payment, no need to add it again
792+ expect ( mockAddPaymentInstrument ) . not . toHaveBeenCalled ( )
793+ } )
794+
669795 test ( 'disables user registration checkbox when payment is not filled in' , ( ) => {
670796 const mockPaymentMethodForm = {
671797 handleSubmit : jest . fn ( ( callback ) => ( e ) => {
0 commit comments