import { Mock } from 'ts-mockery'; import reducer, { CREATE_SHORT_URL_START, CREATE_SHORT_URL_ERROR, CREATE_SHORT_URL, RESET_CREATE_SHORT_URL, createShortUrl, resetCreateShortUrl, CreateShortUrlAction, } from '../../../src/short-urls/reducers/shortUrlCreation'; import { ShortUrl } from '../../../src/short-urls/data'; import ShlinkApiClient from '../../../src/utils/services/ShlinkApiClient'; import { ShlinkState } from '../../../src/container/types'; describe('shortUrlCreationReducer', () => { const shortUrl = Mock.all(); describe('reducer', () => { const action = (type: string, args: Partial = {}) => Mock.of( { type, ...args }, ); it('returns loading on CREATE_SHORT_URL_START', () => { expect(reducer(undefined, action(CREATE_SHORT_URL_START))).toEqual({ result: null, saving: true, error: false, }); }); it('returns error on CREATE_SHORT_URL_ERROR', () => { expect(reducer(undefined, action(CREATE_SHORT_URL_ERROR))).toEqual({ result: null, saving: false, error: true, }); }); it('returns result on CREATE_SHORT_URL', () => { expect(reducer(undefined, action(CREATE_SHORT_URL, { result: shortUrl }))).toEqual({ result: shortUrl, saving: false, error: false, }); }); it('returns default state on RESET_CREATE_SHORT_URL', () => { expect(reducer(undefined, action(RESET_CREATE_SHORT_URL))).toEqual({ result: null, saving: false, error: false, }); }); }); describe('resetCreateShortUrl', () => { it('returns proper action', () => expect(resetCreateShortUrl()).toEqual({ type: RESET_CREATE_SHORT_URL })); }); describe('createShortUrl', () => { const createApiClientMock = (result: Promise) => Mock.of({ createShortUrl: jest.fn().mockReturnValue(result), }); const dispatch = jest.fn(); const getState = () => Mock.all(); afterEach(jest.resetAllMocks); it('calls API on success', async () => { const apiClientMock = createApiClientMock(Promise.resolve(shortUrl)); const dispatchable = createShortUrl(() => apiClientMock)({ longUrl: 'foo' }); await dispatchable(dispatch, getState); expect(apiClientMock.createShortUrl).toHaveBeenCalledTimes(1); expect(dispatch).toHaveBeenCalledTimes(2); expect(dispatch).toHaveBeenNthCalledWith(1, { type: CREATE_SHORT_URL_START }); expect(dispatch).toHaveBeenNthCalledWith(2, { type: CREATE_SHORT_URL, result: shortUrl }); }); it('throws on error', async () => { const error = 'Error'; const apiClientMock = createApiClientMock(Promise.reject(error)); const dispatchable = createShortUrl(() => apiClientMock)({ longUrl: 'foo' }); expect.assertions(5); try { await dispatchable(dispatch, getState); } catch (e) { expect(e).toEqual(error); } expect(apiClientMock.createShortUrl).toHaveBeenCalledTimes(1); expect(dispatch).toHaveBeenCalledTimes(2); expect(dispatch).toHaveBeenNthCalledWith(1, { type: CREATE_SHORT_URL_START }); expect(dispatch).toHaveBeenNthCalledWith(2, { type: CREATE_SHORT_URL_ERROR }); }); }); });