source: node_modules/@reduxjs/toolkit/src/query/tests/buildCreateApi.test.tsx

Last change on this file was a762898, checked in by istevanoska <ilinastevanoska@…>, 5 months ago

Added visualizations

  • Property mode set to 100644
File size: 4.5 KB
Line 
1import { createSelectorCreator, lruMemoize } from '@reduxjs/toolkit'
2import {
3 buildCreateApi,
4 coreModule,
5 reactHooksModule,
6} from '@reduxjs/toolkit/query/react'
7import { render, screen, waitFor } from '@testing-library/react'
8import { delay } from 'msw'
9import * as React from 'react'
10import type { ReactReduxContextValue } from 'react-redux'
11import {
12 Provider,
13 createDispatchHook,
14 createSelectorHook,
15 createStoreHook,
16} from 'react-redux'
17import { setupApiStore, useRenderCounter } from '../../tests/utils/helpers'
18
19const MyContext = React.createContext<ReactReduxContextValue | null>(null)
20
21describe('buildCreateApi', () => {
22 test('Works with all hooks provided', async () => {
23 const customCreateApi = buildCreateApi(
24 coreModule(),
25 reactHooksModule({
26 hooks: {
27 useDispatch: createDispatchHook(MyContext),
28 useSelector: createSelectorHook(MyContext),
29 useStore: createStoreHook(MyContext),
30 },
31 }),
32 )
33
34 const api = customCreateApi({
35 baseQuery: async (arg: any) => {
36 await delay(150)
37
38 return {
39 data: arg?.body ? { ...arg.body } : {},
40 }
41 },
42 endpoints: (build) => ({
43 getUser: build.query<{ name: string }, number>({
44 query: () => ({
45 body: { name: 'Timmy' },
46 }),
47 }),
48 }),
49 })
50
51 let getRenderCount: () => number = () => 0
52
53 const storeRef = setupApiStore(api, {}, { withoutTestLifecycles: true })
54
55 // Copy of 'useQuery hook basic render count assumptions' from `buildHooks.test.tsx`
56 function User() {
57 const { isFetching } = api.endpoints.getUser.useQuery(1)
58 getRenderCount = useRenderCounter()
59
60 return (
61 <div>
62 <div data-testid="isFetching">{String(isFetching)}</div>
63 </div>
64 )
65 }
66
67 function Wrapper({ children }: any) {
68 return (
69 <Provider store={storeRef.store} context={MyContext}>
70 {children}
71 </Provider>
72 )
73 }
74
75 render(<User />, { wrapper: Wrapper })
76 // By the time this runs, the initial render will happen, and the query
77 // will start immediately running by the time we can expect this
78 expect(getRenderCount()).toBe(2)
79
80 await waitFor(() =>
81 expect(screen.getByTestId('isFetching').textContent).toBe('false'),
82 )
83 expect(getRenderCount()).toBe(3)
84 })
85
86 test("Throws an error if you don't provide all hooks", async () => {
87 const callBuildCreateApi = () => {
88 const customCreateApi = buildCreateApi(
89 coreModule(),
90 reactHooksModule({
91 // @ts-ignore
92 hooks: {
93 useDispatch: createDispatchHook(MyContext),
94 useSelector: createSelectorHook(MyContext),
95 },
96 }),
97 )
98 }
99
100 expect(callBuildCreateApi).toThrowErrorMatchingInlineSnapshot(
101 `
102 [Error: When using custom hooks for context, all 3 hooks need to be provided: useDispatch, useSelector, useStore.
103 Hook useStore was either not provided or not a function.]
104 `,
105 )
106 })
107 test('allows passing createSelector instance', async () => {
108 const memoize = vi.fn(lruMemoize)
109 const createSelector = createSelectorCreator(memoize)
110 const createApi = buildCreateApi(
111 coreModule({ createSelector }),
112 reactHooksModule({ createSelector }),
113 )
114 const api = createApi({
115 baseQuery: async (arg: any) => {
116 await delay(150)
117
118 return {
119 data: arg?.body ? { ...arg.body } : {},
120 }
121 },
122 endpoints: (build) => ({
123 getUser: build.query<{ name: string }, number>({
124 query: () => ({
125 body: { name: 'Timmy' },
126 }),
127 }),
128 }),
129 })
130
131 const storeRef = setupApiStore(api, {}, { withoutTestLifecycles: true })
132
133 await storeRef.store.dispatch(api.endpoints.getUser.initiate(1))
134
135 const selectUser = api.endpoints.getUser.select(1)
136
137 expect(selectUser(storeRef.store.getState()).data).toEqual({
138 name: 'Timmy',
139 })
140
141 expect(memoize).toHaveBeenCalledTimes(4)
142
143 memoize.mockClear()
144
145 function User() {
146 const { isFetching } = api.endpoints.getUser.useQuery(1)
147
148 return (
149 <div>
150 <div data-testid="isFetching">{String(isFetching)}</div>
151 </div>
152 )
153 }
154
155 function Wrapper({ children }: any) {
156 return <Provider store={storeRef.store}>{children}</Provider>
157 }
158
159 render(<User />, { wrapper: Wrapper })
160
161 await waitFor(() =>
162 expect(screen.getByTestId('isFetching').textContent).toBe('false'),
163 )
164
165 // select() + selectFromResult
166 expect(memoize).toHaveBeenCalledTimes(8)
167 })
168})
Note: See TracBrowser for help on using the repository browser.