Skip to content

Commit b342c1b

Browse files
author
Alex Cory
committed
added tests
1 parent b1ec226 commit b342c1b

File tree

4 files changed

+37
-53
lines changed

4 files changed

+37
-53
lines changed

src/__tests__/useFetch.test.tsx

Lines changed: 27 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ const fetch = global.fetch as FetchMock
1818

1919
const { NO_CACHE, NETWORK_ONLY } = CachePolicies
2020

21-
2221
describe('useFetch - BROWSER - basic functionality', (): void => {
2322
const expected = {
2423
name: 'Alex Cory',
@@ -742,11 +741,8 @@ describe('useFetch - BROWSER - retryOn & retryDelay', (): void => {
742741

743742
it('should retryOn specific error codes', async (): Promise<void> => {
744743
fetch.resetMocks()
745-
fetch.mockResponseOnce('fail', {
746-
status: 401
747-
}).mockResponseOnce('fail', {
748-
status: 400
749-
})
744+
fetch.mockResponseOnce('fail', { status: 401 })
745+
.mockResponseOnce('fail', { status: 400 })
750746
// should fail, then retry on 401, fail again, but not retry on 400
751747
const { result, waitForNextUpdate } = renderHook(
752748
() => useFetch('url', {
@@ -760,17 +756,14 @@ describe('useFetch - BROWSER - retryOn & retryDelay', (): void => {
760756

761757
it('should retryOn custom function', async (): Promise<void> => {
762758
fetch.resetMocks()
763-
fetch.mockResponseOnce('fail', {
764-
status: 401
765-
}).mockResponseOnce('fail', {
766-
status: 400
767-
})
759+
fetch.mockResponseOnce('fail', { status: 401 })
760+
.mockResponseOnce('fail', { status: 400 })
768761
// should fail, then retry on 401, fail again, but not retry on 400
769762
const { result, waitForNextUpdate } = renderHook(
770763
() => useFetch('url-2', {
771764
retryOn({ response }) {
772765
return !!(response && response.status === 401)
773-
},
766+
}
774767
}, [])
775768
)
776769
await waitForNextUpdate()
@@ -780,15 +773,13 @@ describe('useFetch - BROWSER - retryOn & retryDelay', (): void => {
780773

781774
it('should retry 3 times, fail all 3, then retry 3 more times when called again', async (): Promise<void> => {
782775
fetch.resetMocks()
783-
fetch.mockResponse('fail', {
784-
status: 400
785-
})
776+
fetch.mockResponse('fail', { status: 400 })
786777
const { result, waitForNextUpdate } = renderHook(
787778
() => useFetch('url-12', {
788779
retryOn({ response }) {
789780
return !!(response && response.status === 400)
790781
},
791-
cachePolicy: CachePolicies.NO_CACHE,
782+
cachePolicy: CachePolicies.NO_CACHE
792783
}, [])
793784
)
794785
await waitForNextUpdate()
@@ -799,13 +790,11 @@ describe('useFetch - BROWSER - retryOn & retryDelay', (): void => {
799790
expect(fetch.mock.calls.length).toBe(6)
800791
})
801792

802-
it('should retry with a `retryDelay` as a positive number 2', async (): Promise<void> => {
793+
it('should retry with a `retryDelay` as a positive number', async (): Promise<void> => {
803794
fetch.resetMocks()
804-
fetch.mockResponseOnce('fail', {
805-
status: 401
806-
}).mockResponseOnce('fail', {
807-
status: 400
808-
}).mockResponseOnce(JSON.stringify({ no: 'way' }))
795+
fetch.mockResponseOnce('fail', { status: 401 })
796+
.mockResponseOnce('fail', { status: 400 })
797+
.mockResponseOnce(JSON.stringify({ no: 'way' }))
809798

810799
const { result, waitForNextUpdate } = renderHook(
811800
() => useFetch('url-5', {
@@ -819,31 +808,26 @@ describe('useFetch - BROWSER - retryOn & retryDelay', (): void => {
819808
expect(fetch.mock.calls.length).toBe(3)
820809
})
821810

822-
it('should retry with a `retryDelay` as a positive number', async (): Promise<void> => {
811+
it('should retry with a `retryDelay` as a function', async (): Promise<void> => {
823812
fetch.resetMocks()
824-
fetch.mockResponseOnce('fail', {
825-
status: 401
826-
}).mockResponseOnce('fail', {
827-
status: 400
828-
})
829-
813+
fetch.mockResponse('fail', { status: 400 })
830814
const { result, waitForNextUpdate } = renderHook(
831-
() => useFetch('url-4', {
815+
() => useFetch('url-7', {
832816
retryOn: [401, 400],
833-
retryDelay: 100,
834-
retries: 1
817+
retryDelay() {
818+
return 100
819+
}
835820
}, [])
836821
)
837822
await waitForNextUpdate()
838823
expect(result.current.error).toEqual({ name: 400, message: 'Bad Request' })
839-
expect(fetch.mock.calls.length).toBe(2)
824+
expect(fetch.mock.calls.length).toBe(3)
840825
})
841826

842827
// TODO: there is an issue with error testing some things
843828
// see more detail here: https://github.com/testing-library/react-hooks-testing-library/issues/308
829+
// we basically want to test if when we call the `retry` function, if the `delay` is a positive number
844830
it('should error with a `retryDelay` that is not a postive # or a function returning a positive #', async (): Promise<void> => {
845-
expect(true).toBe(true)
846-
console.log('TODO: react-hooks-testing-library not handling errors properly')
847831
// fetch.resetMocks()
848832
// fetch.mockResponse('fail', {
849833
// status: 400
@@ -859,27 +843,21 @@ describe('useFetch - BROWSER - retryOn & retryDelay', (): void => {
859843
// }
860844
// render = () => !this.state.hasError && this.props.children
861845
// }
862-
863846
// const wrapper = ({ children }: { children?: ReactNode }): ReactElement => <ErrorBoundary>{children}</ErrorBoundary>
864-
865-
// const { result, waitForNextUpdate } = renderHook(() => useFetch('Z', { retryDelay: -1000 }, []), { wrapper })
866-
867-
// await waitForNextUpdate()
868-
// console.log('result.error', result.error)
869-
// console.log('caughtError', caughtError)
870-
})
871-
872-
it('should error if `retryDelay` is not a function returning a positive number', async (): Promise<void> => {
873-
expect(true).toBe(true)
874-
console.log('TODO: react-hooks-testing-library not handling errors properly')
847+
// const { result } = renderHook(() => useFetch('Z', { retryDelay: -1000 }, []), { wrapper })
848+
const { result } = renderHook(() => useFetch('url-123124', { retryDelay: -1000 }, []))
849+
expect(result.error.name).toBe('Invariant Violation')
875850
})
876851

877852
it('should error if `retryOn` is not a function or an array of positive numbers', async (): Promise<void> => {
878853
// TODO: should we check to see if they are valid http status codes?
879854
// - regex: /^[1-5][0-9][0-9]$/
880855
// - ts HttpStatusCodes enum: https://gist.github.com/RWOverdijk/6cef816cfdf5722228e01cc05fd4b094
881-
expect(true).toBe(true)
882-
console.log('TODO: react-hooks-testing-library not handling errors properly')
856+
var { result } = renderHook(() => useFetch('url-11211', { retryOn: 1000 as any }, []))
857+
expect(result.error.name).toBe('Invariant Violation')
858+
// eslint-disable-next-line
859+
var { result } = renderHook(() => useFetch('url-11211', { retryOn: ['c'] as any }, []))
860+
expect(result.error.name).toBe('Invariant Violation')
883861
})
884862
})
885863

src/useFetch.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
} from './types'
1717
import useFetchArgs from './useFetchArgs'
1818
import doFetchArgs from './doFetchArgs'
19-
import { invariant, tryGetData, toResponseObject, useDeepCallback, isFunction, sleep } from './utils'
19+
import { invariant, tryGetData, toResponseObject, useDeepCallback, isFunction, sleep, isPositiveNumber } from './utils'
2020
import useCache from './useCache'
2121

2222
const { CACHE_FIRST } = CachePolicies
@@ -164,8 +164,7 @@ function useFetch<TData = any>(...args: UseFetchArgs): UseFetch<TData> {
164164

165165
const retry = async (args, opts) => {
166166
const delay = (isFunction(retryDelay) ? (retryDelay as Function)(opts) : retryDelay) as number
167-
// invariant(Number.isInteger(delay) && delay >= 0, 'retryDelay must be a positive number! If you\'re using it as a function, it must also return a positive number.')
168-
if (!(Number.isInteger(delay) && delay >= 0)) {
167+
if (!isPositiveNumber(delay)) {
169168
console.error('retryDelay must be a positive number! If you\'re using it as a function, it must also return a positive number.')
170169
}
171170
attempt.current++

src/useFetchArgs.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { OptionsMaybeURL, NoUrlOptions, Flatten, CachePolicies, Interceptors, OverwriteGlobalOptions, Options, RetryOn, RetryDelay } from './types'
2-
import { isString, isObject, invariant, pullOutRequestInit, isFunction } from './utils'
2+
import { isString, isObject, invariant, pullOutRequestInit, isFunction, isPositiveNumber } from './utils'
33
import { useContext, useMemo } from 'react'
44
import FetchContext from './FetchContext'
55

@@ -129,7 +129,12 @@ export default function useFetchArgs(
129129
const suspense = useField<boolean>('suspense', urlOrOptions, optionsNoURLs)
130130
const retries = useField<number>('retries', urlOrOptions, optionsNoURLs)
131131
const retryOn = useField<RetryOn>('retryOn', urlOrOptions, optionsNoURLs)
132+
invariant(
133+
isFunction(retryOn) || (Array.isArray(retryOn) && retryOn.every(isPositiveNumber)),
134+
'`retryOn` must be an array of positive numbers or a function returning a boolean.'
135+
)
132136
const retryDelay = useField<RetryDelay>('retryDelay', urlOrOptions, optionsNoURLs)
137+
invariant(isFunction(retryDelay) || Number.isInteger(retryDelay as number) && retryDelay >= 0, '`retryDelay` must be a positive number or a function returning a positive number.')
133138

134139
const loading = useMemo((): boolean => {
135140
if (isObject(urlOrOptions)) return !!urlOrOptions.loading || Array.isArray(dependencies)

src/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,5 @@ function useDeepCompareMemoize(value: DependencyList) {
235235
export const useDeepCallback = (cb: (method: HTTPMethod) => (...args: any) => any, deps: DependencyList) => useCallback(cb, useDeepCompareMemoize(deps))
236236

237237
export const sleep = (ms: number) => new Promise((resolve: any) => setTimeout(resolve, ms))
238+
239+
export const isPositiveNumber = (n: number) => Number.isInteger(n) && n > 0

0 commit comments

Comments
 (0)