@@ -904,3 +904,105 @@ test.skip("[TYPE ONLY] can narrow validation type to success", () => {
904
904
}
905
905
}
906
906
} ) ;
907
+
908
+ test ( "can validate files" , async ( ) => {
909
+ const spy = jest . fn ( ) ;
910
+
911
+ const Schema = z . object ( {
912
+ myFile : z . instanceof ( File ) . refine ( ( file ) => {
913
+ spy ( file . type ) ;
914
+ return file . type === "image/png" ;
915
+ } , "Only .png images are allowed" ) ,
916
+ } ) ;
917
+
918
+ function Test ( ) {
919
+ const zo = useZorm ( "form" , Schema ) ;
920
+
921
+ return (
922
+ < form ref = { zo . ref } data-testid = "form" >
923
+ < input
924
+ data-testid = "file"
925
+ type = "file"
926
+ name = { zo . fields . myFile ( ) }
927
+ />
928
+
929
+ { zo . errors . myFile ( ( e ) => (
930
+ < div data-testid = "error" > { e . message } </ div >
931
+ ) ) }
932
+ </ form >
933
+ ) ;
934
+ }
935
+
936
+ render ( < Test /> ) ;
937
+
938
+ const file = new File ( [ "(⌐□_□)" ] , "chucknorris.txt" , {
939
+ type : "text/plain" ,
940
+ } ) ;
941
+
942
+ const fileInput = screen . getByTestId ( "file" ) as HTMLInputElement ;
943
+ await userEvent . upload ( fileInput , file ) ;
944
+ fireEvent . submit ( screen . getByTestId ( "form" ) ) ;
945
+
946
+ {
947
+ // TEMP TESTS
948
+ const form = screen . getByTestId ( "form" ) as HTMLFormElement ;
949
+ expect ( fileInput . files ?. [ 0 ] ?. name ) . toBe ( "chucknorris.txt" ) ;
950
+ const formData = new FormData ( form ) ;
951
+ expect ( formData . get ( "myFile" ) ) . toBeInstanceOf ( File ) ;
952
+ const formFile = formData . get ( "myFile" ) as File ;
953
+
954
+ // XXX Bug in jsdom or react testing lib?
955
+ // FormData cannot read file from the form.
956
+ expect ( formFile . name ) . toBe ( "chucknorris.txt" ) ;
957
+ }
958
+
959
+ expect ( spy ) . toHaveBeenCalledWith ( "text/plain" ) ;
960
+
961
+ expect ( screen . queryByTestId ( "error" ) ) . toHaveTextContent (
962
+ "Only .png images are allowed" ,
963
+ ) ;
964
+ } ) ;
965
+
966
+ test ( "can submit files" , async ( ) => {
967
+ const spy = jest . fn ( ) ;
968
+
969
+ const Schema = z . object ( {
970
+ myFile : z . instanceof ( File ) . refine ( ( file ) => {
971
+ return file . type === "image/png" ;
972
+ } , "Only .png images are allowed" ) ,
973
+ } ) ;
974
+
975
+ function Test ( ) {
976
+ const zo = useZorm ( "form" , Schema , {
977
+ onValidSubmit ( e ) {
978
+ spy ( e . data . myFile . name ) ;
979
+ } ,
980
+ } ) ;
981
+
982
+ return (
983
+ < form ref = { zo . ref } data-testid = "form" >
984
+ < input
985
+ data-testid = "file"
986
+ type = "file"
987
+ name = { zo . fields . myFile ( ) }
988
+ />
989
+
990
+ { zo . errors . myFile ( ( e ) => (
991
+ < div data-testid = "error" > { e . message } </ div >
992
+ ) ) }
993
+ </ form >
994
+ ) ;
995
+ }
996
+
997
+ render ( < Test /> ) ;
998
+
999
+ const file = new File ( [ "(⌐□_□)" ] , "chucknorris.png" , {
1000
+ type : "image/png" ,
1001
+ } ) ;
1002
+
1003
+ const fileInput = screen . getByTestId ( "file" ) as HTMLInputElement ;
1004
+ await userEvent . upload ( fileInput , file ) ;
1005
+ fireEvent . submit ( screen . getByTestId ( "form" ) ) ;
1006
+
1007
+ expect ( spy ) . toHaveBeenCalledWith ( "text/plain" ) ;
1008
+ } ) ;
0 commit comments