1 | import type { AnyAction, Middleware, ThunkAction } from '@reduxjs/toolkit'
|
2 | import {
|
3 | getDefaultMiddleware,
|
4 | MiddlewareArray,
|
5 | configureStore,
|
6 | } from '@reduxjs/toolkit'
|
7 | import thunk from 'redux-thunk'
|
8 |
|
9 | describe('getDefaultMiddleware', () => {
|
10 | const ORIGINAL_NODE_ENV = process.env.NODE_ENV
|
11 |
|
12 | afterEach(() => {
|
13 | process.env.NODE_ENV = ORIGINAL_NODE_ENV
|
14 | })
|
15 |
|
16 | it('returns an array with only redux-thunk in production', () => {
|
17 | process.env.NODE_ENV = 'production'
|
18 |
|
19 | expect(getDefaultMiddleware()).toEqual([thunk])
|
20 | })
|
21 |
|
22 | it('returns an array with additional middleware in development', () => {
|
23 | const middleware = getDefaultMiddleware()
|
24 | expect(middleware).toContain(thunk)
|
25 | expect(middleware.length).toBeGreaterThan(1)
|
26 | })
|
27 |
|
28 | it('removes the thunk middleware if disabled', () => {
|
29 | const middleware = getDefaultMiddleware({ thunk: false })
|
30 | expect(middleware.includes(thunk)).toBe(false)
|
31 | expect(middleware.length).toBe(2)
|
32 | })
|
33 |
|
34 | it('removes the immutable middleware if disabled', () => {
|
35 | const defaultMiddleware = getDefaultMiddleware()
|
36 | const middleware = getDefaultMiddleware({ immutableCheck: false })
|
37 | expect(middleware.length).toBe(defaultMiddleware.length - 1)
|
38 | })
|
39 |
|
40 | it('removes the serializable middleware if disabled', () => {
|
41 | const defaultMiddleware = getDefaultMiddleware()
|
42 | const middleware = getDefaultMiddleware({ serializableCheck: false })
|
43 | expect(middleware.length).toBe(defaultMiddleware.length - 1)
|
44 | })
|
45 |
|
46 | it('allows passing options to thunk', () => {
|
47 | const extraArgument = 42
|
48 | const middleware = getDefaultMiddleware({
|
49 | thunk: { extraArgument },
|
50 | immutableCheck: false,
|
51 | serializableCheck: false,
|
52 | })
|
53 |
|
54 | const testThunk: ThunkAction<void, {}, number, AnyAction> = (
|
55 | dispatch,
|
56 | getState,
|
57 | extraArg
|
58 | ) => {
|
59 | expect(extraArg).toBe(extraArgument)
|
60 | }
|
61 |
|
62 | const reducer = () => ({})
|
63 |
|
64 | const store = configureStore({
|
65 | reducer,
|
66 | middleware,
|
67 | })
|
68 |
|
69 | store.dispatch(testThunk)
|
70 | })
|
71 |
|
72 | it('allows passing options to immutableCheck', () => {
|
73 | let immutableCheckWasCalled = false
|
74 |
|
75 | const middleware = getDefaultMiddleware({
|
76 | thunk: false,
|
77 | immutableCheck: {
|
78 | isImmutable: () => {
|
79 | immutableCheckWasCalled = true
|
80 | return true
|
81 | },
|
82 | },
|
83 | serializableCheck: false,
|
84 | })
|
85 |
|
86 | const reducer = () => ({})
|
87 |
|
88 | const store = configureStore({
|
89 | reducer,
|
90 | middleware,
|
91 | })
|
92 |
|
93 | expect(immutableCheckWasCalled).toBe(true)
|
94 | })
|
95 |
|
96 | it('allows passing options to serializableCheck', () => {
|
97 | let serializableCheckWasCalled = false
|
98 |
|
99 | const middleware = getDefaultMiddleware({
|
100 | thunk: false,
|
101 | immutableCheck: false,
|
102 | serializableCheck: {
|
103 | isSerializable: () => {
|
104 | serializableCheckWasCalled = true
|
105 | return true
|
106 | },
|
107 | },
|
108 | })
|
109 |
|
110 | const reducer = () => ({})
|
111 |
|
112 | const store = configureStore({
|
113 | reducer,
|
114 | middleware,
|
115 | })
|
116 |
|
117 | store.dispatch({ type: 'TEST_ACTION' })
|
118 |
|
119 | expect(serializableCheckWasCalled).toBe(true)
|
120 | })
|
121 | })
|
122 |
|
123 | describe('MiddlewareArray functionality', () => {
|
124 | const middleware1: Middleware = () => (next) => (action) => next(action)
|
125 | const middleware2: Middleware = () => (next) => (action) => next(action)
|
126 | const defaultMiddleware = getDefaultMiddleware()
|
127 | const originalDefaultMiddleware = [...defaultMiddleware]
|
128 |
|
129 | test('allows to prepend a single value', () => {
|
130 | const prepended = defaultMiddleware.prepend(middleware1)
|
131 |
|
132 |
|
133 | expect(prepended).toEqual([middleware1, ...defaultMiddleware])
|
134 |
|
135 | expect(prepended).toBeInstanceOf(MiddlewareArray)
|
136 |
|
137 | expect(prepended).not.toEqual(defaultMiddleware)
|
138 |
|
139 | expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
|
140 | })
|
141 |
|
142 | test('allows to prepend multiple values (array as first argument)', () => {
|
143 | const prepended = defaultMiddleware.prepend([middleware1, middleware2])
|
144 |
|
145 |
|
146 | expect(prepended).toEqual([middleware1, middleware2, ...defaultMiddleware])
|
147 |
|
148 | expect(prepended).toBeInstanceOf(MiddlewareArray)
|
149 |
|
150 | expect(prepended).not.toEqual(defaultMiddleware)
|
151 |
|
152 | expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
|
153 | })
|
154 |
|
155 | test('allows to prepend multiple values (rest)', () => {
|
156 | const prepended = defaultMiddleware.prepend(middleware1, middleware2)
|
157 |
|
158 |
|
159 | expect(prepended).toEqual([middleware1, middleware2, ...defaultMiddleware])
|
160 |
|
161 | expect(prepended).toBeInstanceOf(MiddlewareArray)
|
162 |
|
163 | expect(prepended).not.toEqual(defaultMiddleware)
|
164 |
|
165 | expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
|
166 | })
|
167 |
|
168 | test('allows to concat a single value', () => {
|
169 | const concatenated = defaultMiddleware.concat(middleware1)
|
170 |
|
171 |
|
172 | expect(concatenated).toEqual([...defaultMiddleware, middleware1])
|
173 |
|
174 | expect(concatenated).toBeInstanceOf(MiddlewareArray)
|
175 |
|
176 | expect(concatenated).not.toEqual(defaultMiddleware)
|
177 |
|
178 | expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
|
179 | })
|
180 |
|
181 | test('allows to concat multiple values (array as first argument)', () => {
|
182 | const concatenated = defaultMiddleware.concat([middleware1, middleware2])
|
183 |
|
184 |
|
185 | expect(concatenated).toEqual([
|
186 | ...defaultMiddleware,
|
187 | middleware1,
|
188 | middleware2,
|
189 | ])
|
190 |
|
191 | expect(concatenated).toBeInstanceOf(MiddlewareArray)
|
192 |
|
193 | expect(concatenated).not.toEqual(defaultMiddleware)
|
194 |
|
195 | expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
|
196 | })
|
197 |
|
198 | test('allows to concat multiple values (rest)', () => {
|
199 | const concatenated = defaultMiddleware.concat(middleware1, middleware2)
|
200 |
|
201 |
|
202 | expect(concatenated).toEqual([
|
203 | ...defaultMiddleware,
|
204 | middleware1,
|
205 | middleware2,
|
206 | ])
|
207 |
|
208 | expect(concatenated).toBeInstanceOf(MiddlewareArray)
|
209 |
|
210 | expect(concatenated).not.toEqual(defaultMiddleware)
|
211 |
|
212 | expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
|
213 | })
|
214 |
|
215 | test('allows to concat and then prepend', () => {
|
216 | const concatenated = defaultMiddleware
|
217 | .concat(middleware1)
|
218 | .prepend(middleware2)
|
219 |
|
220 | expect(concatenated).toEqual([
|
221 | middleware2,
|
222 | ...defaultMiddleware,
|
223 | middleware1,
|
224 | ])
|
225 | })
|
226 |
|
227 | test('allows to prepend and then concat', () => {
|
228 | const concatenated = defaultMiddleware
|
229 | .prepend(middleware2)
|
230 | .concat(middleware1)
|
231 |
|
232 | expect(concatenated).toEqual([
|
233 | middleware2,
|
234 | ...defaultMiddleware,
|
235 | middleware1,
|
236 | ])
|
237 | })
|
238 | })
|