From bbce53ade6c7465d52b4039207459d4d0147b12b Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Fri, 7 Sep 2018 20:41:21 +0200 Subject: [PATCH] Created shortUrlDetail reducer test --- .eslintrc | 1 + src/visits/reducers/shortUrlDetail.js | 6 +- .../reducers/shortUrlsListParams.test.js | 2 +- test/visits/reducers/shortUrlDetail.test.js | 92 +++++++++++++++++++ 4 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 test/visits/reducers/shortUrlDetail.test.js diff --git a/.eslintrc b/.eslintrc index 7207fac3..7ac3f4ec 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,6 +2,7 @@ "extends": [ "adidas-env/browser", "adidas-env/module", + "adidas-env/node", "adidas-es6", "adidas-babel", "adidas-react" diff --git a/src/visits/reducers/shortUrlDetail.js b/src/visits/reducers/shortUrlDetail.js index e1a44261..cb86e040 100644 --- a/src/visits/reducers/shortUrlDetail.js +++ b/src/visits/reducers/shortUrlDetail.js @@ -4,9 +4,9 @@ import shlinkApiClient from '../../api/ShlinkApiClient'; import { shortUrlType } from '../../short-urls/reducers/shortUrlsList'; /* eslint-disable padding-line-between-statements, newline-after-var */ -const GET_SHORT_URL_DETAIL_START = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL_START'; -const GET_SHORT_URL_DETAIL_ERROR = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL_ERROR'; -const GET_SHORT_URL_DETAIL = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL'; +export const GET_SHORT_URL_DETAIL_START = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL_START'; +export const GET_SHORT_URL_DETAIL_ERROR = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL_ERROR'; +export const GET_SHORT_URL_DETAIL = 'shlink/shortUrlDetail/GET_SHORT_URL_DETAIL'; /* eslint-enable padding-line-between-statements, newline-after-var */ export const shortUrlDetailType = PropTypes.shape({ diff --git a/test/short-urls/reducers/shortUrlsListParams.test.js b/test/short-urls/reducers/shortUrlsListParams.test.js index 848691bc..334fdb71 100644 --- a/test/short-urls/reducers/shortUrlsListParams.test.js +++ b/test/short-urls/reducers/shortUrlsListParams.test.js @@ -5,7 +5,7 @@ import reducer, { import { LIST_SHORT_URLS } from '../../../src/short-urls/reducers/shortUrlsList'; describe('shortUrlsListParamsReducer', () => { - describe('reducerr', () => { + describe('reducer', () => { const defaultState = { page: '1' }; it('returns default value when action is unknown', () => diff --git a/test/visits/reducers/shortUrlDetail.test.js b/test/visits/reducers/shortUrlDetail.test.js new file mode 100644 index 00000000..d192e48f --- /dev/null +++ b/test/visits/reducers/shortUrlDetail.test.js @@ -0,0 +1,92 @@ +import * as sinon from 'sinon'; +import reducer, { + _getShortUrlDetail, + GET_SHORT_URL_DETAIL_START, + GET_SHORT_URL_DETAIL_ERROR, + GET_SHORT_URL_DETAIL, +} from '../../../src/visits/reducers/shortUrlDetail'; + +describe('shortUrlDetailReducer', () => { + describe('reducer', () => { + it('returns loading on GET_SHORT_URL_DETAIL_START', () => { + const state = reducer({ loading: false }, { type: GET_SHORT_URL_DETAIL_START }); + const { loading } = state; + + expect(loading).toEqual(true); + }); + + it('stops loading and returns error on GET_SHORT_URL_DETAIL_ERROR', () => { + const state = reducer({ loading: true, error: false }, { type: GET_SHORT_URL_DETAIL_ERROR }); + const { loading, error } = state; + + expect(loading).toEqual(false); + expect(error).toEqual(true); + }); + + it('return short URL on GET_SHORT_URL_DETAIL', () => { + const actionShortUrl = { longUrl: 'foo', shortCode: 'bar' }; + const state = reducer({ loading: true, error: false }, { type: GET_SHORT_URL_DETAIL, shortUrl: actionShortUrl }); + const { loading, error, shortUrl } = state; + + expect(loading).toEqual(false); + expect(error).toEqual(false); + expect(shortUrl).toEqual(actionShortUrl); + }); + + it('returns default state on unknown action', () => { + const defaultState = { + shortUrl: {}, + loading: false, + error: false, + }; + const state = reducer(defaultState, { type: 'unknown' }); + + expect(state).toEqual(defaultState); + }); + }); + + describe('getShortUrlDetail', () => { + const buildApiClientMock = (returned) => ({ + getShortUrl: sinon.fake.returns(returned), + }); + const dispatchMock = sinon.spy(); + + beforeEach(() => dispatchMock.resetHistory()); + + it('dispatches start and error when promise is rejected', async () => { + const ShlinkApiClient = buildApiClientMock(Promise.reject()); + const expectedDispatchCalls = 2; + + await _getShortUrlDetail(ShlinkApiClient, 'abc123')(dispatchMock); + + const [ firstCallArg ] = dispatchMock.getCall(0).args; + const { type: firstCallType } = firstCallArg; + + const [ secondCallArg ] = dispatchMock.getCall(1).args; + const { type: secondCallType } = secondCallArg; + + expect(dispatchMock.callCount).toEqual(expectedDispatchCalls); + expect(firstCallType).toEqual(GET_SHORT_URL_DETAIL_START); + expect(secondCallType).toEqual(GET_SHORT_URL_DETAIL_ERROR); + }); + + it('dispatches start and success when promise is resolved', async () => { + const resolvedShortUrl = { longUrl: 'foo', shortCode: 'bar' }; + const ShlinkApiClient = buildApiClientMock(Promise.resolve(resolvedShortUrl)); + const expectedDispatchCalls = 2; + + await _getShortUrlDetail(ShlinkApiClient, 'abc123')(dispatchMock); + + const [ firstCallArg ] = dispatchMock.getCall(0).args; + const { type: firstCallType } = firstCallArg; + + const [ secondCallArg ] = dispatchMock.getCall(1).args; + const { type: secondCallType, shortUrl } = secondCallArg; + + expect(dispatchMock.callCount).toEqual(expectedDispatchCalls); + expect(firstCallType).toEqual(GET_SHORT_URL_DETAIL_START); + expect(secondCallType).toEqual(GET_SHORT_URL_DETAIL); + expect(shortUrl).toEqual(resolvedShortUrl); + }); + }); +});