import React from 'react' ; import { render , screen , act } from '@testing-library/react' ; import user from '@testing-library/user-event' ; import { useForm } from 'react-hook-form' ; import * as t from 'typanion' ; import { typanionResolver } from '..' ; const ERROR_MESSAGE = 'Expected to have a length of at least 1 elements (got 0)' ; const schema = t . isObject ( { username : t . applyCascade ( t . isString ( ) , [ t . hasMinLength ( 1 ) ] ) , password : t . applyCascade ( t . isString ( ) , [ t . hasMinLength ( 1 ) ] ) , } ) ; interface FormData { unusedProperty : string ; username : string ; password : string ; } interface Props { onSubmit : ( data : FormData ) => void ; } function TestComponent ( { onSubmit } ) { const { register , handleSubmit } = useForm < FormData > ( { resolver : typanionResolver ( schema ) , shouldUseNativeValidation : true , } ) ; return ( < form onSubmit = { handleSubmit ( onSubmit ) } > < input { ... register ( 'username' ) } placeholder = "username" / > < input { ... register ( 'password' ) } placeholder = "password" / > < button type = "submit" > submit < /button> < /form>); } test ( "form's native validation with Typanion" , async ( ) => { const handleSubmit = jest . fn ( ) ; render ( < TestComponent onSubmit = { handleSubmit } / > ) ; let usernameField = screen . getByPlaceholderText ( /username/i ) as HTMLInputElement ; expect ( usernameField . validity . valid ) . toBe ( true ) ; expect ( usernameField . validationMessage ) . toBe ( '' ) ; let passwordField = screen . getByPlaceholderText ( /password/i ) as HTMLInputElement ; expect ( passwordField . validity . valid ) . toBe ( true ) ; expect ( passwordField . validationMessage ) . toBe ( '' ) ; await act ( async ( ) => { user . click ( screen . getByText ( /submit/i ) ) ; } ) ; usernameField = screen . getByPlaceholderText ( /username/i ) as HTMLInputElement ; expect ( usernameField . validity . valid ) . toBe ( false ) ; expect ( usernameField . validationMessage ) . toBe ( ERROR_MESSAGE ) ; passwordField = screen . getByPlaceholderText ( /password/i ) as HTMLInputElement ; expect ( passwordField . validity . valid ) . toBe ( false ) ; expect ( passwordField . validationMessage ) . toBe ( ERROR_MESSAGE ) ; await act ( async ( ) => { user . type ( screen . getByPlaceholderText ( /username/i ) , 'joe' ) ; user . type ( screen . getByPlaceholderText ( /password/i ) , 'password' ) ; } ) ; usernameField = screen . getByPlaceholderText ( /username/i ) as HTMLInputElement ; expect ( usernameField . validity . valid ) . toBe ( true ) ; expect ( usernameField . validationMessage ) . toBe ( '' ) ; passwordField = screen . getByPlaceholderText ( /password/i ) as HTMLInputElement ; expect ( passwordField . validity . valid ) . toBe ( true ) ; expect ( passwordField . validationMessage ) . toBe ( '' ) ; } ) ;