Skip to content

Commit 63f708f

Browse files
committed
add custom context test for apiprovider
1 parent 7e854c4 commit 63f708f

File tree

1 file changed

+93
-2
lines changed

1 file changed

+93
-2
lines changed

packages/toolkit/src/query/tests/apiProvider.test.tsx

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
import { configureStore } from '@reduxjs/toolkit'
2-
import { ApiProvider, createApi } from '@reduxjs/toolkit/query/react'
2+
import {
3+
ApiProvider,
4+
buildCreateApi,
5+
coreModule,
6+
createApi,
7+
reactHooksModule,
8+
} from '@reduxjs/toolkit/query/react'
39
import { fireEvent, render, waitFor } from '@testing-library/react'
410
import { delay } from 'msw'
511
import * as React from 'react'
6-
import { Provider } from 'react-redux'
12+
import type { ReactReduxContextValue } from 'react-redux'
13+
import {
14+
Provider,
15+
createDispatchHook,
16+
createSelectorHook,
17+
createStoreHook,
18+
} from 'react-redux'
719

820
const api = createApi({
921
baseQuery: async (arg: any) => {
@@ -70,4 +82,83 @@ describe('ApiProvider', () => {
7082
`[Error: Existing Redux context detected. If you already have a store set up, please use the traditional Redux setup.]`,
7183
)
7284
})
85+
test('ApiProvider allows a custom context', async () => {
86+
const customContext = React.createContext<ReactReduxContextValue | null>(
87+
null,
88+
)
89+
90+
const createApiWithCustomContext = buildCreateApi(
91+
coreModule(),
92+
reactHooksModule({
93+
hooks: {
94+
useStore: createStoreHook(customContext),
95+
useSelector: createSelectorHook(customContext),
96+
useDispatch: createDispatchHook(customContext),
97+
},
98+
}),
99+
)
100+
101+
const customApi = createApiWithCustomContext({
102+
baseQuery: async (arg: any) => {
103+
await delay(150)
104+
return { data: arg?.body ? arg.body : null }
105+
},
106+
endpoints: (build) => ({
107+
getUser: build.query<any, number>({
108+
query: (arg) => arg,
109+
}),
110+
updateUser: build.mutation<any, { name: string }>({
111+
query: (update) => ({ body: update }),
112+
}),
113+
}),
114+
})
115+
116+
function User() {
117+
const [value, setValue] = React.useState(0)
118+
119+
const { isFetching } = customApi.endpoints.getUser.useQuery(1, {
120+
skip: value < 1,
121+
})
122+
123+
return (
124+
<div>
125+
<div data-testid="isFetching">{String(isFetching)}</div>
126+
<button onClick={() => setValue((val) => val + 1)}>
127+
Increment value
128+
</button>
129+
</div>
130+
)
131+
}
132+
133+
const { getByText, getByTestId } = render(
134+
<ApiProvider api={customApi} context={customContext}>
135+
<User />
136+
</ApiProvider>,
137+
)
138+
139+
await waitFor(() =>
140+
expect(getByTestId('isFetching').textContent).toBe('false'),
141+
)
142+
fireEvent.click(getByText('Increment value'))
143+
await waitFor(() =>
144+
expect(getByTestId('isFetching').textContent).toBe('true'),
145+
)
146+
await waitFor(() =>
147+
expect(getByTestId('isFetching').textContent).toBe('false'),
148+
)
149+
fireEvent.click(getByText('Increment value'))
150+
// Being that nothing has changed in the args, this should never fire.
151+
expect(getByTestId('isFetching').textContent).toBe('false')
152+
153+
// won't throw if nested, because context is different
154+
expect(() =>
155+
render(
156+
<Provider store={configureStore({ reducer: () => null })}>
157+
<ApiProvider api={customApi} context={customContext}>
158+
child
159+
</ApiProvider>
160+
</Provider>,
161+
),
162+
).not.toThrow()
163+
})
73164
})

0 commit comments

Comments
 (0)