rondo-framework/packages/client/src/middleware/PromiseMiddleware.test.ts
Jerko Steiner 8b6f90235e Use default action type and add status to async actions
Since TypeScript can infer types based on string types, it has became
easier to define a single constant of an action that returns a promise,
and then dispatch actions with different statuses: pending, resolved,
and/or rejected. This seems like more typing at first, but in the long
run it will become easier to write generic reducer methods, and the
names of reduced types will not have to be repeated every time.

For example, previously we had to write:

    type MyActionTypes =
      IAsyncAction<IUser, 'LOGIN_PENDING', 'LOGIN_RESOLVED', 'LOGIN_REJECTED'>
      | ...

And now we can write:

    type MyActionTypes =
      IAsyncAction<IUser, 'LOGIN'>
      | ...
2019-04-01 15:20:42 +08:00

74 lines
1.7 KiB
TypeScript

import {createStore, applyMiddleware, Store} from 'redux'
import {PromiseMiddleware} from './PromiseMiddleware'
import {getError} from '../test-utils'
describe('PromiseMiddleware', () => {
let store!: Store
beforeEach(() => {
const middleware = new PromiseMiddleware()
store = createStore((state: any[] = [], action) => {
state.push(action)
return state
}, applyMiddleware(middleware.handle))
})
it('does nothing when payload is not a promise', () => {
const action = {type: 'test'}
const result = store.dispatch(action)
expect(result).toBe(action)
expect(store.getState().slice(1)).toEqual([{
type: action.type,
}])
})
it('dispatches pending and resolved action', async () => {
const value = 123
const type = 'TEST'
const action = {
payload: Promise.resolve(value),
type,
}
const result = store.dispatch(action)
expect(result).toEqual({
...action,
status: 'pending',
})
await result.payload
expect(store.getState().slice(1)).toEqual([{
...action,
status: 'pending',
}, {
payload: value,
status: 'resolved',
type,
}])
})
it('dispatches pending and rejected action on error', async () => {
const error = new Error('test')
const type = 'TEST'
const action = {
payload: Promise.reject(error),
type,
}
const result = store.dispatch(action)
expect(result).toEqual({
...action,
status: 'pending',
})
const err = await getError(result.payload)
expect(err).toBe(error)
expect(store.getState().slice(1)).toEqual([{
payload: action.payload,
status: 'pending',
type,
}, {
error,
status: 'rejected',
type,
}])
})
})