source: node_modules/@reduxjs/toolkit/src/tests/getDefaultMiddleware.test.ts

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

Added visualizations

  • Property mode set to 100644
File size: 8.9 KB
Line 
1import { Tuple } from '@internal/utils'
2import type {
3 Action,
4 Middleware,
5 ThunkAction,
6 UnknownAction,
7} from '@reduxjs/toolkit'
8import { configureStore } from '@reduxjs/toolkit'
9import { thunk } from 'redux-thunk'
10import { vi } from 'vitest'
11
12import { buildGetDefaultMiddleware } from '@internal/getDefaultMiddleware'
13
14const getDefaultMiddleware = buildGetDefaultMiddleware()
15
16describe('getDefaultMiddleware', () => {
17 afterEach(() => {
18 vi.unstubAllEnvs()
19 })
20
21 describe('Production behavior', () => {
22 beforeEach(() => {
23 vi.resetModules()
24 })
25
26 it('returns an array with only redux-thunk in production', async () => {
27 vi.stubEnv('NODE_ENV', 'production')
28
29 const { thunk } = await import('redux-thunk')
30 const { buildGetDefaultMiddleware } = await import(
31 '@internal/getDefaultMiddleware'
32 )
33
34 const middleware = buildGetDefaultMiddleware()()
35 expect(middleware).toContain(thunk)
36 expect(middleware.length).toBe(1)
37 })
38 })
39
40 it('returns an array with additional middleware in development', () => {
41 const middleware = getDefaultMiddleware()
42 expect(middleware).toContain(thunk)
43 expect(middleware.length).toBeGreaterThan(1)
44 })
45
46 const defaultMiddleware = getDefaultMiddleware()
47
48 it('removes the thunk middleware if disabled', () => {
49 const middleware = getDefaultMiddleware({ thunk: false })
50 // @ts-ignore
51 expect(middleware.includes(thunk)).toBe(false)
52 expect(middleware.length).toBe(defaultMiddleware.length - 1)
53 })
54
55 it('removes the immutable middleware if disabled', () => {
56 const middleware = getDefaultMiddleware({ immutableCheck: false })
57 expect(middleware.length).toBe(defaultMiddleware.length - 1)
58 })
59
60 it('removes the serializable middleware if disabled', () => {
61 const middleware = getDefaultMiddleware({ serializableCheck: false })
62 expect(middleware.length).toBe(defaultMiddleware.length - 1)
63 })
64
65 it('removes the action creator middleware if disabled', () => {
66 const middleware = getDefaultMiddleware({ actionCreatorCheck: false })
67 expect(middleware.length).toBe(defaultMiddleware.length - 1)
68 })
69
70 it('allows passing options to thunk', () => {
71 const extraArgument = 42 as const
72
73 const m2 = getDefaultMiddleware({
74 thunk: false,
75 })
76
77 const dummyMiddleware: Middleware<
78 {
79 (action: Action<'actionListenerMiddleware/add'>): () => void
80 },
81 { counter: number }
82 > = (storeApi) => (next) => (action) => {
83 return next(action)
84 }
85
86 const dummyMiddleware2: Middleware<{}, { counter: number }> =
87 (storeApi) => (next) => (action) => {}
88
89 const testThunk: ThunkAction<
90 void,
91 { counter: number },
92 number,
93 UnknownAction
94 > = (dispatch, getState, extraArg) => {
95 expect(extraArg).toBe(extraArgument)
96 }
97
98 const reducer = () => ({ counter: 123 })
99
100 const store = configureStore({
101 reducer,
102 middleware: (gDM) => {
103 const middleware = gDM({
104 thunk: { extraArgument },
105 immutableCheck: false,
106 serializableCheck: false,
107 actionCreatorCheck: false,
108 })
109
110 const m3 = middleware.concat(dummyMiddleware, dummyMiddleware2)
111
112 return m3
113 },
114 })
115
116 store.dispatch(testThunk)
117 })
118
119 it('allows passing options to immutableCheck', () => {
120 let immutableCheckWasCalled = false
121
122 const middleware = () =>
123 getDefaultMiddleware({
124 thunk: false,
125 immutableCheck: {
126 isImmutable: () => {
127 immutableCheckWasCalled = true
128 return true
129 },
130 },
131 serializableCheck: false,
132 actionCreatorCheck: false,
133 })
134
135 const reducer = () => ({})
136
137 const store = configureStore({
138 reducer,
139 middleware,
140 })
141
142 expect(immutableCheckWasCalled).toBe(true)
143 })
144
145 it('allows passing options to serializableCheck', () => {
146 let serializableCheckWasCalled = false
147
148 const middleware = () =>
149 getDefaultMiddleware({
150 thunk: false,
151 immutableCheck: false,
152 serializableCheck: {
153 isSerializable: () => {
154 serializableCheckWasCalled = true
155 return true
156 },
157 },
158 actionCreatorCheck: false,
159 })
160
161 const reducer = () => ({})
162
163 const store = configureStore({
164 reducer,
165 middleware,
166 })
167
168 store.dispatch({ type: 'TEST_ACTION' })
169
170 expect(serializableCheckWasCalled).toBe(true)
171 })
172})
173
174it('allows passing options to actionCreatorCheck', () => {
175 let actionCreatorCheckWasCalled = false
176
177 const middleware = () =>
178 getDefaultMiddleware({
179 thunk: false,
180 immutableCheck: false,
181 serializableCheck: false,
182 actionCreatorCheck: {
183 isActionCreator: (action: unknown): action is Function => {
184 actionCreatorCheckWasCalled = true
185 return false
186 },
187 },
188 })
189
190 const reducer = () => ({})
191
192 const store = configureStore({
193 reducer,
194 middleware,
195 })
196
197 store.dispatch({ type: 'TEST_ACTION' })
198
199 expect(actionCreatorCheckWasCalled).toBe(true)
200})
201
202describe('Tuple functionality', () => {
203 const middleware1: Middleware = () => (next) => (action) => next(action)
204 const middleware2: Middleware = () => (next) => (action) => next(action)
205 const defaultMiddleware = getDefaultMiddleware()
206 const originalDefaultMiddleware = [...defaultMiddleware]
207
208 test('allows to prepend a single value', () => {
209 const prepended = defaultMiddleware.prepend(middleware1)
210
211 // value is prepended
212 expect(prepended).toEqual([middleware1, ...defaultMiddleware])
213 // returned value is of correct type
214 expect(prepended).toBeInstanceOf(Tuple)
215 // prepended is a new array
216 expect(prepended).not.toEqual(defaultMiddleware)
217 // defaultMiddleware is not modified
218 expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
219 })
220
221 test('allows to prepend multiple values (array as first argument)', () => {
222 const prepended = defaultMiddleware.prepend([middleware1, middleware2])
223
224 // value is prepended
225 expect(prepended).toEqual([middleware1, middleware2, ...defaultMiddleware])
226 // returned value is of correct type
227 expect(prepended).toBeInstanceOf(Tuple)
228 // prepended is a new array
229 expect(prepended).not.toEqual(defaultMiddleware)
230 // defaultMiddleware is not modified
231 expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
232 })
233
234 test('allows to prepend multiple values (rest)', () => {
235 const prepended = defaultMiddleware.prepend(middleware1, middleware2)
236
237 // value is prepended
238 expect(prepended).toEqual([middleware1, middleware2, ...defaultMiddleware])
239 // returned value is of correct type
240 expect(prepended).toBeInstanceOf(Tuple)
241 // prepended is a new array
242 expect(prepended).not.toEqual(defaultMiddleware)
243 // defaultMiddleware is not modified
244 expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
245 })
246
247 test('allows to concat a single value', () => {
248 const concatenated = defaultMiddleware.concat(middleware1)
249
250 // value is concatenated
251 expect(concatenated).toEqual([...defaultMiddleware, middleware1])
252 // returned value is of correct type
253 expect(concatenated).toBeInstanceOf(Tuple)
254 // concatenated is a new array
255 expect(concatenated).not.toEqual(defaultMiddleware)
256 // defaultMiddleware is not modified
257 expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
258 })
259
260 test('allows to concat multiple values (array as first argument)', () => {
261 const concatenated = defaultMiddleware.concat([middleware1, middleware2])
262
263 // value is concatenated
264 expect(concatenated).toEqual([
265 ...defaultMiddleware,
266 middleware1,
267 middleware2,
268 ])
269 // returned value is of correct type
270 expect(concatenated).toBeInstanceOf(Tuple)
271 // concatenated is a new array
272 expect(concatenated).not.toEqual(defaultMiddleware)
273 // defaultMiddleware is not modified
274 expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
275 })
276
277 test('allows to concat multiple values (rest)', () => {
278 const concatenated = defaultMiddleware.concat(middleware1, middleware2)
279
280 // value is concatenated
281 expect(concatenated).toEqual([
282 ...defaultMiddleware,
283 middleware1,
284 middleware2,
285 ])
286 // returned value is of correct type
287 expect(concatenated).toBeInstanceOf(Tuple)
288 // concatenated is a new array
289 expect(concatenated).not.toEqual(defaultMiddleware)
290 // defaultMiddleware is not modified
291 expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
292 })
293
294 test('allows to concat and then prepend', () => {
295 const concatenated = defaultMiddleware
296 .concat(middleware1)
297 .prepend(middleware2)
298
299 expect(concatenated).toEqual([
300 middleware2,
301 ...defaultMiddleware,
302 middleware1,
303 ])
304 })
305
306 test('allows to prepend and then concat', () => {
307 const concatenated = defaultMiddleware
308 .prepend(middleware2)
309 .concat(middleware1)
310
311 expect(concatenated).toEqual([
312 middleware2,
313 ...defaultMiddleware,
314 middleware1,
315 ])
316 })
317})
Note: See TracBrowser for help on using the repository browser.