1- import React from 'react' ;
1+ import React , { createRef } from 'react' ;
22import { act , render , screen } from '@testing-library/react' ;
33import userEvent from '@testing-library/user-event' ;
44
@@ -26,7 +26,7 @@ describe('<AsyncButton /> component', () => {
2626 errorConfig,
2727 } ;
2828
29- let user ;
29+ let user : ReturnType < typeof userEvent . setup > ;
3030 beforeEach ( ( ) => {
3131 user = userEvent . setup ( {
3232 advanceTimers : jest . advanceTimersByTime ,
@@ -40,7 +40,7 @@ describe('<AsyncButton /> component', () => {
4040 } ) ;
4141
4242 it ( 'passes ref correctly' , ( ) => {
43- const ref = React . createRef ( ) ;
43+ const ref = createRef < HTMLButtonElement > ( ) ;
4444
4545 render ( < AsyncButton { ...defaultProps } ref = { ref } /> ) ;
4646
@@ -63,7 +63,9 @@ describe('<AsyncButton /> component', () => {
6363 } ) ;
6464
6565 it ( 'changes button state to success on click if onClick is synchronous' , async ( ) => {
66- const onClick = ( ) => { } ;
66+ const onClick = ( ) => {
67+ // Intentionally empty
68+ } ;
6769
6870 render ( < AsyncButton { ...defaultProps } onClick = { onClick } /> ) ;
6971
@@ -76,7 +78,9 @@ describe('<AsyncButton /> component', () => {
7678 } ) ;
7779
7880 it ( 'changes button state to default after refresh timeout has passed' , async ( ) => {
79- const onClick = ( ) => { } ;
81+ const onClick = ( ) => {
82+ // Intentionally empty
83+ } ;
8084
8185 render ( < AsyncButton { ...defaultProps } onClick = { onClick } /> ) ;
8286
@@ -103,9 +107,9 @@ describe('<AsyncButton /> component', () => {
103107 } ) ;
104108
105109 it ( 'changes button state to pending on click if onClick is asynchronous' , async ( ) => {
106- let resolve ;
110+ let resolve : ( ) => void ;
107111 const onClick = ( ) =>
108- new Promise ( ( res ) => {
112+ new Promise < void > ( ( res ) => {
109113 resolve = res ;
110114 } ) ;
111115
@@ -124,9 +128,9 @@ describe('<AsyncButton /> component', () => {
124128 } ) ;
125129
126130 it ( 'changes button state to success after asynchronous onClick is resolved' , async ( ) => {
127- let resolve ;
131+ let resolve : ( ) => void ;
128132 const onClick = ( ) =>
129- new Promise ( ( res ) => {
133+ new Promise < void > ( ( res ) => {
130134 resolve = res ;
131135 } ) ;
132136
@@ -148,9 +152,9 @@ describe('<AsyncButton /> component', () => {
148152 } ) ;
149153
150154 it ( 'changes button state to default after refresh timeout has passed' , async ( ) => {
151- let resolve ;
155+ let resolve : ( ) => void ;
152156 const onClick = ( ) =>
153- new Promise ( ( res ) => {
157+ new Promise < void > ( ( res ) => {
154158 resolve = res ;
155159 } ) ;
156160
@@ -184,4 +188,71 @@ describe('<AsyncButton /> component', () => {
184188 const button5 = screen . getByRole ( 'button' ) ;
185189 expect ( button5 ) . toHaveTextContent ( 'Click me' ) ;
186190 } ) ;
191+
192+ it ( 'should allow button props to be passed by default' , ( ) => {
193+ // @ts -expect-no-error
194+ < AsyncButton { ...defaultProps } type = "submit" /> ;
195+ } ) ;
196+
197+ it ( 'should allow button props to be passed given as="button"' , ( ) => {
198+ // @ts -expect-no-error
199+ < AsyncButton { ...defaultProps } as = "button" disabled /> ;
200+ } ) ;
201+
202+ it ( 'should not allow link props to be passed given as="button"' , ( ) => {
203+ // @ts -expect-error-next-line
204+ < AsyncButton { ...defaultProps } as = "button" href = "https://example.com" /> ;
205+
206+ // Sanity check
207+ // @ts -expect-error-next-line
208+ < button href = "https://example.com" > </ button > ;
209+ } ) ;
210+
211+ it ( 'should allow link props to be passed given as="a"' , ( ) => {
212+ // @ts -expect-no-error
213+ < AsyncButton { ...defaultProps } as = "a" href = "https://example.com" /> ;
214+ } ) ;
215+
216+ it ( 'should not allow button props to be passed given as="a"' , ( ) => {
217+ // @ts -expect-error-next-line
218+ < AsyncButton { ...defaultProps } as = "a" disabled href = "https://example.com" /> ;
219+
220+ // Sanity check
221+ // @ts -expect-error-next-line
222+ < a disabled href = "https://example.com" >
223+ Click me
224+ </ a > ;
225+ } ) ;
226+
227+ it ( 'should not allow button props to be passed given as={MyButton}' , ( ) => {
228+ function MyButton ( ) {
229+ return < button type = "submit" > </ button > ;
230+ }
231+
232+ // @ts -expect-error-next-line
233+ < AsyncButton { ...defaultProps } as = { MyButton } type = "submit" /> ;
234+
235+ // Sanity check
236+ function MyCustomComponent ( { as, ...otherProps } : { as : React . ElementType } ) {
237+ const Component = as || 'div' ;
238+ return < Component { ...otherProps } /> ;
239+ }
240+
241+ // @ts -expect-error-next-line
242+ < MyCustomComponent as = { MyButton } type = "submit" /> ;
243+ } ) ;
244+
245+ it ( 'should not allow invalid values for as' , ( ) => {
246+ // @ts -expect-error-next-line
247+ < AsyncButton { ...defaultProps } as = { 5 } type = "submit" /> ;
248+
249+ // Sanity check
250+ function MyCustomComponent ( { as } : { as : React . ElementType } ) {
251+ const Component = as || 'div' ;
252+ return < Component /> ;
253+ }
254+
255+ // @ts -expect-error-next-line
256+ < MyCustomComponent as = { 5 } /> ;
257+ } ) ;
187258} ) ;
0 commit comments