| 1 | import type { Middleware } from 'redux'
|
|---|
| 2 | import { createDynamicMiddleware } from '../index'
|
|---|
| 3 | import { configureStore } from '../../configureStore'
|
|---|
| 4 | import type { BaseActionCreator, PayloadAction } from '../../createAction'
|
|---|
| 5 | import { createAction } from '../../createAction'
|
|---|
| 6 | import { isAllOf } from '../../matchers'
|
|---|
| 7 |
|
|---|
| 8 | const probeType = 'probeableMW/probe'
|
|---|
| 9 |
|
|---|
| 10 | export interface ProbeMiddleware
|
|---|
| 11 | extends BaseActionCreator<number, typeof probeType> {
|
|---|
| 12 | <Id extends number>(id: Id): PayloadAction<Id, typeof probeType>
|
|---|
| 13 | }
|
|---|
| 14 |
|
|---|
| 15 | export const probeMiddleware = createAction(probeType) as ProbeMiddleware
|
|---|
| 16 |
|
|---|
| 17 | const matchId =
|
|---|
| 18 | <Id extends number>(id: Id) =>
|
|---|
| 19 | (action: any): action is PayloadAction<Id> =>
|
|---|
| 20 | action.payload === id
|
|---|
| 21 |
|
|---|
| 22 | export const makeProbeableMiddleware = <Id extends number>(
|
|---|
| 23 | id: Id,
|
|---|
| 24 | ): Middleware<{
|
|---|
| 25 | (action: PayloadAction<Id, typeof probeType>): Id
|
|---|
| 26 | }> => {
|
|---|
| 27 | const isMiddlewareAction = isAllOf(probeMiddleware, matchId(id))
|
|---|
| 28 | return (api) => (next) => (action) => {
|
|---|
| 29 | if (isMiddlewareAction(action)) {
|
|---|
| 30 | return id
|
|---|
| 31 | }
|
|---|
| 32 | return next(action)
|
|---|
| 33 | }
|
|---|
| 34 | }
|
|---|
| 35 |
|
|---|
| 36 | const staticMiddleware = makeProbeableMiddleware(1)
|
|---|
| 37 |
|
|---|
| 38 | describe('createDynamicMiddleware', () => {
|
|---|
| 39 | it('allows injecting middleware after store instantiation', () => {
|
|---|
| 40 | const dynamicInstance = createDynamicMiddleware()
|
|---|
| 41 | const store = configureStore({
|
|---|
| 42 | reducer: () => 0,
|
|---|
| 43 | middleware: (gDM) =>
|
|---|
| 44 | gDM().prepend(dynamicInstance.middleware).concat(staticMiddleware),
|
|---|
| 45 | })
|
|---|
| 46 | // normal, pre-inject
|
|---|
| 47 | expect(store.dispatch(probeMiddleware(2))).toEqual(probeMiddleware(2))
|
|---|
| 48 | // static
|
|---|
| 49 | expect(store.dispatch(probeMiddleware(1))).toBe(1)
|
|---|
| 50 |
|
|---|
| 51 | // inject
|
|---|
| 52 | dynamicInstance.addMiddleware(makeProbeableMiddleware(2))
|
|---|
| 53 |
|
|---|
| 54 | // injected
|
|---|
| 55 | expect(store.dispatch(probeMiddleware(2))).toBe(2)
|
|---|
| 56 | })
|
|---|
| 57 | it('returns dispatch when withMiddleware is dispatched', () => {
|
|---|
| 58 | const dynamicInstance = createDynamicMiddleware()
|
|---|
| 59 | const store = configureStore({
|
|---|
| 60 | reducer: () => 0,
|
|---|
| 61 | middleware: (gDM) => gDM().prepend(dynamicInstance.middleware),
|
|---|
| 62 | })
|
|---|
| 63 |
|
|---|
| 64 | // normal, pre-inject
|
|---|
| 65 | expect(store.dispatch(probeMiddleware(2))).toEqual(probeMiddleware(2))
|
|---|
| 66 |
|
|---|
| 67 | const dispatch = store.dispatch(
|
|---|
| 68 | dynamicInstance.withMiddleware(makeProbeableMiddleware(2)),
|
|---|
| 69 | )
|
|---|
| 70 | expect(dispatch).toEqual(expect.any(Function))
|
|---|
| 71 |
|
|---|
| 72 | expect(dispatch(probeMiddleware(2))).toBe(2)
|
|---|
| 73 | })
|
|---|
| 74 | })
|
|---|