UNPKG

redux-promise-middleware-actions

Version:

Redux action creator for making async actions with redux-promise-middleware

215 lines (184 loc) 6.16 kB
import assert from 'assert'; import { createAction, createAsyncAction, onFulfilled, onPending, onRejected, } from '../src/actions'; describe('actions', () => { const TYPE = 'TEST_ACTION'; describe('createAction', () => { it('should create an action object with type and no payload', () => { const action = createAction(TYPE); assert.deepEqual(action(), { type: TYPE }); }); it('should output action name on toString()', () => { const action = createAction(TYPE); assert.strictEqual(action.toString(), TYPE); }); it('should add the input to the payload', () => { const action = createAction(TYPE, (input: number) => input); assert.strictEqual(action(1234).payload, 1234); }); it('should execute the action creator and add it to the payload', () => { const action = createAction(TYPE, (a: number, b: number) => a + b); assert.strictEqual(action(40, 2).payload, 42); }); describe('metadataCreator', () => { it('should not have metadata', () => { const action = createAction(TYPE, (n: number) => ({ n })); assert.strictEqual('meta' in action(42), false); }); it('should forward same payload and metadata', () => { const action = createAction( TYPE, (n: number) => ({ n }), (n: number) => ({ n }) ); assert.deepEqual(action(42), { type: TYPE, payload: { n: 42 }, meta: { n: 42 }, }); }); it('should have different payload and metadata', () => { const action = createAction( TYPE, (n: number) => ({ n }), () => ({ asdf: 1234 }) ); assert.deepEqual(action(42), { type: TYPE, payload: { n: 42 }, meta: { asdf: 1234 }, }); }); it('should have only metadata', () => { const action = createAction( TYPE, () => undefined, () => ({ asdf: 1234 }) ); assert.deepEqual(action(), { type: TYPE, payload: undefined, meta: { asdf: 1234 }, }); }); }); }); describe('createAsyncAction', () => { const action = createAsyncAction(TYPE, (s: string) => Promise.resolve(s)); it('should create an action with correct type', () => { assert.strictEqual(action('x').type, TYPE); }); it('should create an action with Promise payload', async () => { assert(action('x').payload instanceof Promise); }); it('should create an action with correct payload', async () => { assert.strictEqual(await action('x').payload, 'x'); }); it('should throw on toString()', () => { assert.throws( () => action.toString(), new RegExp( `Async action ${TYPE} must be handled with pending, fulfilled or rejected` ) ); }); it('should create action with 0 arguments', async () => { const action0 = createAsyncAction(TYPE, () => Promise.resolve(42)); assert.strictEqual(await action0().payload, 42); }); it('should create action with 1 arguments', async () => { const action1 = createAsyncAction(TYPE, (n: number) => Promise.resolve(n) ); assert.strictEqual(await action1(42).payload, 42); }); it('should create action with 2 arguments', async () => { const action1 = createAsyncAction(TYPE, (n: number, s: string) => Promise.resolve({ n, s }) ); assert.deepEqual(await action1(42, 'hello').payload, { n: 42, s: 'hello', }); }); it('should create action with 3 arguments', async () => { const action1 = createAsyncAction( TYPE, (n: number, s: string, b: boolean) => Promise.resolve({ n, s, b }) ); assert.deepEqual(await action1(42, 'hello', true).payload, { n: 42, s: 'hello', b: true, }); }); describe('pending', () => { it('should have a pending action prop', () => { assert('pending' in action); }); it('should output pending action name on toString()', () => { assert.strictEqual(action.pending.toString(), onPending(TYPE)); }); }); describe('fulfilled', () => { it('should have a fulfilled action prop', () => { assert('fulfilled' in action); }); it('should output fulfilled action name on toString()', () => { assert.strictEqual(action.fulfilled.toString(), onFulfilled(TYPE)); }); it('should create a fulfilled action with payload', () => { assert.deepEqual(action.fulfilled('payload'), { type: onFulfilled(TYPE), payload: 'payload', }); }); }); describe('rejected', () => { it('should have a rejected action prop', () => { assert('rejected' in action); }); it('should output rejected action name on toString()', () => { assert.strictEqual(action.rejected.toString(), onRejected(TYPE)); }); it('should create a rejected action with payload', () => { const err = new Error('error'); assert.deepEqual(action.rejected(err), { type: onRejected(TYPE), payload: err, }); }); }); describe('promiseTypeDelimiter', () => { const actionDelimiter = createAsyncAction( TYPE, (s: string) => Promise.resolve(s), undefined, { promiseTypeDelimiter: '#' } ); it('should use custom delimiter in pending action type', () => { assert.strictEqual( actionDelimiter.pending.toString(), onPending(TYPE, '#') ); }); it('should use custom delimiter in fulfilled action type', () => { assert.strictEqual( actionDelimiter.fulfilled.toString(), onFulfilled(TYPE, '#') ); }); it('should use custom delimiter in rejected action type', () => { assert.strictEqual( actionDelimiter.rejected.toString(), onRejected(TYPE, '#') ); }); }); }); });