UNPKG

7.46 kBPlain TextView Raw
1import type { AnyAction, Middleware, ThunkAction } from '@reduxjs/toolkit'
2import {
3 getDefaultMiddleware,
4 MiddlewareArray,
5 configureStore,
6} from '@reduxjs/toolkit'
7import thunk from 'redux-thunk'
8
9describe('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]) // @remap-prod-remove-line
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
123describe('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 // value is prepended
133 expect(prepended).toEqual([middleware1, ...defaultMiddleware])
134 // returned value is of correct type
135 expect(prepended).toBeInstanceOf(MiddlewareArray)
136 // prepended is a new array
137 expect(prepended).not.toEqual(defaultMiddleware)
138 // defaultMiddleware is not modified
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 // value is prepended
146 expect(prepended).toEqual([middleware1, middleware2, ...defaultMiddleware])
147 // returned value is of correct type
148 expect(prepended).toBeInstanceOf(MiddlewareArray)
149 // prepended is a new array
150 expect(prepended).not.toEqual(defaultMiddleware)
151 // defaultMiddleware is not modified
152 expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
153 })
154
155 test('allows to prepend multiple values (rest)', () => {
156 const prepended = defaultMiddleware.prepend(middleware1, middleware2)
157
158 // value is prepended
159 expect(prepended).toEqual([middleware1, middleware2, ...defaultMiddleware])
160 // returned value is of correct type
161 expect(prepended).toBeInstanceOf(MiddlewareArray)
162 // prepended is a new array
163 expect(prepended).not.toEqual(defaultMiddleware)
164 // defaultMiddleware is not modified
165 expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
166 })
167
168 test('allows to concat a single value', () => {
169 const concatenated = defaultMiddleware.concat(middleware1)
170
171 // value is concatenated
172 expect(concatenated).toEqual([...defaultMiddleware, middleware1])
173 // returned value is of correct type
174 expect(concatenated).toBeInstanceOf(MiddlewareArray)
175 // concatenated is a new array
176 expect(concatenated).not.toEqual(defaultMiddleware)
177 // defaultMiddleware is not modified
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 // value is concatenated
185 expect(concatenated).toEqual([
186 ...defaultMiddleware,
187 middleware1,
188 middleware2,
189 ])
190 // returned value is of correct type
191 expect(concatenated).toBeInstanceOf(MiddlewareArray)
192 // concatenated is a new array
193 expect(concatenated).not.toEqual(defaultMiddleware)
194 // defaultMiddleware is not modified
195 expect(defaultMiddleware).toEqual(originalDefaultMiddleware)
196 })
197
198 test('allows to concat multiple values (rest)', () => {
199 const concatenated = defaultMiddleware.concat(middleware1, middleware2)
200
201 // value is concatenated
202 expect(concatenated).toEqual([
203 ...defaultMiddleware,
204 middleware1,
205 middleware2,
206 ])
207 // returned value is of correct type
208 expect(concatenated).toBeInstanceOf(MiddlewareArray)
209 // concatenated is a new array
210 expect(concatenated).not.toEqual(defaultMiddleware)
211 // defaultMiddleware is not modified
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})