@@ -932,4 +932,215 @@ describe('CardNumberElement', () => {
932932 } ) ;
933933 } ) ;
934934 } ) ;
935+
936+ describe ( 'setValue validate parameter' , ( ) => {
937+ test ( 'setValue without validate parameter does not trigger onChange' , async ( ) => {
938+ const onChange = jest . fn ( ) ;
939+ const ref = {
940+ current : null as any ,
941+ } ;
942+
943+ render (
944+ < CardNumberElement
945+ btRef = { ref }
946+ onChange = { onChange }
947+ placeholder = "Card Number"
948+ style = { { } }
949+ />
950+ ) ;
951+
952+ onChange . mockClear ( ) ;
953+
954+ ref . current . setValue (
955+ { id : ref . current . id , format : ( val : string ) => val }
956+ ) ;
957+
958+ await waitFor ( ( ) => {
959+ expect ( onChange ) . not . toHaveBeenCalled ( ) ;
960+ } ) ;
961+ } ) ;
962+
963+ test ( 'setValue with validate=false does not trigger onChange' , async ( ) => {
964+ const onChange = jest . fn ( ) ;
965+ const ref = {
966+ current : null as any ,
967+ } ;
968+
969+ render (
970+ < CardNumberElement
971+ btRef = { ref }
972+ onChange = { onChange }
973+ placeholder = "Card Number"
974+ style = { { } }
975+ />
976+ ) ;
977+
978+ onChange . mockClear ( ) ;
979+
980+ ref . current . setValue (
981+ { id : ref . current . id , format : ( val : string ) => val } ,
982+ false
983+ ) ;
984+
985+ await waitFor ( ( ) => {
986+ expect ( onChange ) . not . toHaveBeenCalled ( ) ;
987+ } ) ;
988+ } ) ;
989+
990+ test ( 'setValue with validate=true triggers onChange with validation' , async ( ) => {
991+ const onChange = jest . fn ( ) ;
992+ const ref = {
993+ current : null as any ,
994+ } ;
995+
996+ render (
997+ < CardNumberElement
998+ btRef = { ref }
999+ onChange = { onChange }
1000+ placeholder = "Card Number"
1001+ style = { { } }
1002+ />
1003+ ) ;
1004+
1005+ onChange . mockClear ( ) ;
1006+
1007+ const validCardRef = {
1008+ id : ref . current . id ,
1009+ format : ( ) => '4242424242424242' ,
1010+ } ;
1011+
1012+ ref . current . setValue ( validCardRef , true ) ;
1013+
1014+ await waitFor ( ( ) => {
1015+ expect ( onChange ) . toHaveBeenCalledWith (
1016+ expect . objectContaining ( {
1017+ brand : 'visa' ,
1018+ cardBin : '42424242' ,
1019+ cardLast4 : '4242' ,
1020+ complete : true ,
1021+ cvcLength : 3 ,
1022+ empty : false ,
1023+ maskSatisfied : true ,
1024+ valid : true ,
1025+ } )
1026+ ) ;
1027+ } ) ;
1028+ } ) ;
1029+
1030+ test ( 'setValue with validate=true validates invalid card number' , async ( ) => {
1031+ const onChange = jest . fn ( ) ;
1032+ const ref = {
1033+ current : null as any ,
1034+ } ;
1035+
1036+ render (
1037+ < CardNumberElement
1038+ btRef = { ref }
1039+ onChange = { onChange }
1040+ placeholder = "Card Number"
1041+ style = { { } }
1042+ />
1043+ ) ;
1044+
1045+ onChange . mockClear ( ) ;
1046+
1047+ const invalidCardRef = {
1048+ id : ref . current . id ,
1049+ format : ( ) => '4242424242424241' ,
1050+ } ;
1051+
1052+ ref . current . setValue ( invalidCardRef , true ) ;
1053+
1054+ await waitFor ( ( ) => {
1055+ expect ( onChange ) . toHaveBeenCalledWith (
1056+ expect . objectContaining ( {
1057+ brand : 'visa' ,
1058+ complete : false ,
1059+ empty : false ,
1060+ errors : [ { targetId : 'cardNumber' , type : 'invalid' } ] ,
1061+ maskSatisfied : true ,
1062+ valid : false ,
1063+ } )
1064+ ) ;
1065+ } ) ;
1066+ } ) ;
1067+
1068+ test ( 'setValue with validate=true validates incomplete card number' , async ( ) => {
1069+ const onChange = jest . fn ( ) ;
1070+ const ref = {
1071+ current : null as any ,
1072+ } ;
1073+
1074+ render (
1075+ < CardNumberElement
1076+ btRef = { ref }
1077+ onChange = { onChange }
1078+ placeholder = "Card Number"
1079+ style = { { } }
1080+ />
1081+ ) ;
1082+
1083+ onChange . mockClear ( ) ;
1084+
1085+ const incompleteCardRef = {
1086+ id : ref . current . id ,
1087+ format : ( ) => '4242' ,
1088+ } ;
1089+
1090+ ref . current . setValue ( incompleteCardRef , true ) ;
1091+
1092+ await waitFor ( ( ) => {
1093+ expect ( onChange ) . toHaveBeenCalledWith (
1094+ expect . objectContaining ( {
1095+ brand : 'visa' ,
1096+ cardBin : undefined ,
1097+ cardLast4 : undefined ,
1098+ cvcLength : 3 ,
1099+ complete : false ,
1100+ empty : false ,
1101+ errors : [ { targetId : 'cardNumber' , type : 'incomplete' } ] ,
1102+ maskSatisfied : false ,
1103+ valid : false ,
1104+ } )
1105+ ) ;
1106+ } ) ;
1107+ } ) ;
1108+
1109+ test ( 'setValue with validate=true and empty value' , async ( ) => {
1110+ const onChange = jest . fn ( ) ;
1111+ const ref = {
1112+ current : null as any ,
1113+ } ;
1114+
1115+ render (
1116+ < CardNumberElement
1117+ btRef = { ref }
1118+ onChange = { onChange }
1119+ placeholder = "Card Number"
1120+ style = { { } }
1121+ />
1122+ ) ;
1123+
1124+ onChange . mockClear ( ) ;
1125+
1126+ const emptyCardRef = {
1127+ id : ref . current . id ,
1128+ format : ( ) => '' ,
1129+ } ;
1130+
1131+ ref . current . setValue ( emptyCardRef , true ) ;
1132+
1133+ await waitFor ( ( ) => {
1134+ expect ( onChange ) . toHaveBeenCalledWith (
1135+ expect . objectContaining ( {
1136+ brand : 'unknown' ,
1137+ complete : false ,
1138+ empty : true ,
1139+ maskSatisfied : false ,
1140+ valid : false ,
1141+ } )
1142+ ) ;
1143+ } ) ;
1144+ } ) ;
1145+ } ) ;
9351146} ) ;
0 commit comments