mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-09 09:47:28 +03:00
Removed remaining usages of sinon
This commit is contained in:
parent
f8de069567
commit
28ca54547e
24 changed files with 231 additions and 402 deletions
103
package-lock.json
generated
103
package-lock.json
generated
|
@ -921,43 +921,6 @@
|
||||||
"integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=",
|
"integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@sinonjs/commons": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.3.0.tgz",
|
|
||||||
"integrity": "sha1-UKJ1QBa28wqZTO2m2aCow2rdqEk=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"type-detect": "4.0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@sinonjs/formatio": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.1.0.tgz",
|
|
||||||
"integrity": "sha1-asnR6xghmE2ExJlnJuRdFkbYzOU=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@sinonjs/samsam": "^2 || ^3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@sinonjs/samsam": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.0.2.tgz",
|
|
||||||
"integrity": "sha1-ME+zO9VYWgst+KTIAfy0f6hNjkM=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@sinonjs/commons": "^1.0.2",
|
|
||||||
"array-from": "^2.1.1",
|
|
||||||
"lodash.get": "^4.4.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@sinonjs/samsam": {
|
|
||||||
"version": "2.1.3",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-2.1.3.tgz",
|
|
||||||
"integrity": "sha1-Ys8qm2JO3HlRNBNf43/Cro6ja+M=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@svgr/core": {
|
"@svgr/core": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.yarnpkg.com/@svgr/core/-/core-2.4.1.tgz",
|
"resolved": "https://registry.yarnpkg.com/@svgr/core/-/core-2.4.1.tgz",
|
||||||
|
@ -1468,12 +1431,6 @@
|
||||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
|
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"array-from": {
|
|
||||||
"version": "2.1.1",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz",
|
|
||||||
"integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"array-includes": {
|
"array-includes": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz",
|
"resolved": "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz",
|
||||||
|
@ -10255,12 +10212,6 @@
|
||||||
"resolved": "https://registry.yarnpkg.com/just-curry-it/-/just-curry-it-3.1.0.tgz",
|
"resolved": "https://registry.yarnpkg.com/just-curry-it/-/just-curry-it-3.1.0.tgz",
|
||||||
"integrity": "sha1-q1na7TCKWLhHraFm7dCi1Adm+8U="
|
"integrity": "sha1-q1na7TCKWLhHraFm7dCi1Adm+8U="
|
||||||
},
|
},
|
||||||
"just-extend": {
|
|
||||||
"version": "4.0.2",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/just-extend/-/just-extend-4.0.2.tgz",
|
|
||||||
"integrity": "sha1-8/R/ffyg+YnFVBCn68iFSwcQivw=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"killable": {
|
"killable": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz",
|
"resolved": "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz",
|
||||||
|
@ -10496,12 +10447,6 @@
|
||||||
"integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
|
"integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"lodash.get": {
|
|
||||||
"version": "4.4.2",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz",
|
|
||||||
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"lodash.isequal": {
|
"lodash.isequal": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
"resolved": "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||||
|
@ -10587,12 +10532,6 @@
|
||||||
"integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=",
|
"integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"lolex": {
|
|
||||||
"version": "2.7.5",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz",
|
|
||||||
"integrity": "sha1-ETAB1Wv8fgLVbjYpHMXEE9GqBzM=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"longest-streak": {
|
"longest-streak": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz",
|
"resolved": "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz",
|
||||||
|
@ -11256,19 +11195,6 @@
|
||||||
"integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=",
|
"integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"nise": {
|
|
||||||
"version": "1.4.8",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/nise/-/nise-1.4.8.tgz",
|
|
||||||
"integrity": "sha1-zpHDHobPmyxMrEnX/Nf1Z3m/1rA=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@sinonjs/formatio": "^3.1.0",
|
|
||||||
"just-extend": "^4.0.2",
|
|
||||||
"lolex": "^2.3.2",
|
|
||||||
"path-to-regexp": "^1.7.0",
|
|
||||||
"text-encoding": "^0.6.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"no-case": {
|
"no-case": {
|
||||||
"version": "2.3.2",
|
"version": "2.3.2",
|
||||||
"resolved": "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz",
|
"resolved": "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz",
|
||||||
|
@ -15199,23 +15125,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sinon": {
|
|
||||||
"version": "6.3.5",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/sinon/-/sinon-6.3.5.tgz",
|
|
||||||
"integrity": "sha1-D21qW066rR9ujgGTlVQtHQLBRKA=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@sinonjs/commons": "^1.0.2",
|
|
||||||
"@sinonjs/formatio": "^3.0.0",
|
|
||||||
"@sinonjs/samsam": "^2.1.2",
|
|
||||||
"diff": "^3.5.0",
|
|
||||||
"lodash.get": "^4.4.2",
|
|
||||||
"lolex": "^2.7.5",
|
|
||||||
"nise": "^1.4.5",
|
|
||||||
"supports-color": "^5.5.0",
|
|
||||||
"type-detect": "^4.0.8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sisteransi": {
|
"sisteransi": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz",
|
"resolved": "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz",
|
||||||
|
@ -16374,12 +16283,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"text-encoding": {
|
|
||||||
"version": "0.6.4",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz",
|
|
||||||
"integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"text-table": {
|
"text-table": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz",
|
"resolved": "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz",
|
||||||
|
@ -16668,12 +16571,6 @@
|
||||||
"prelude-ls": "~1.1.2"
|
"prelude-ls": "~1.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type-detect": {
|
|
||||||
"version": "4.0.8",
|
|
||||||
"resolved": "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz",
|
|
||||||
"integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"type-is": {
|
"type-is": {
|
||||||
"version": "1.6.16",
|
"version": "1.6.16",
|
||||||
"resolved": "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz",
|
"resolved": "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz",
|
||||||
|
|
|
@ -113,7 +113,6 @@
|
||||||
"resolve": "^1.8.1",
|
"resolve": "^1.8.1",
|
||||||
"sass-loader": "^7.1.0",
|
"sass-loader": "^7.1.0",
|
||||||
"serve": "^10.0.0",
|
"serve": "^10.0.0",
|
||||||
"sinon": "^6.1.5",
|
|
||||||
"style-loader": "^0.23.0",
|
"style-loader": "^0.23.0",
|
||||||
"stylelint": "^9.9.0",
|
"stylelint": "^9.9.0",
|
||||||
"stylelint-config-adidas": "^1.2.1",
|
"stylelint-config-adidas": "^1.2.1",
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import createShortUrlsCreator from '../../src/short-urls/CreateShortUrl';
|
import createShortUrlsCreator from '../../src/short-urls/CreateShortUrl';
|
||||||
import DateInput from '../../src/utils/DateInput';
|
import DateInput from '../../src/utils/DateInput';
|
||||||
|
@ -12,7 +11,7 @@ describe('<CreateShortUrl />', () => {
|
||||||
const shortUrlCreationResult = {
|
const shortUrlCreationResult = {
|
||||||
loading: false,
|
loading: false,
|
||||||
};
|
};
|
||||||
const createShortUrl = sinon.spy();
|
const createShortUrl = jest.fn();
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const CreateShortUrl = createShortUrlsCreator(TagsSelector, () => '');
|
const CreateShortUrl = createShortUrlsCreator(TagsSelector, () => '');
|
||||||
|
@ -23,7 +22,7 @@ describe('<CreateShortUrl />', () => {
|
||||||
});
|
});
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
createShortUrl.resetHistory();
|
createShortUrl.mockReset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('saves short URL with data set in form controls', (done) => {
|
it('saves short URL with data set in form controls', (done) => {
|
||||||
|
@ -49,8 +48,8 @@ describe('<CreateShortUrl />', () => {
|
||||||
const form = wrapper.find('form');
|
const form = wrapper.find('form');
|
||||||
|
|
||||||
form.simulate('submit', { preventDefault: identity });
|
form.simulate('submit', { preventDefault: identity });
|
||||||
expect(createShortUrl.callCount).toEqual(1);
|
expect(createShortUrl).toHaveBeenCalledTimes(1);
|
||||||
expect(createShortUrl.getCall(0).args).toEqual(
|
expect(createShortUrl.mock.calls[0]).toEqual(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
longUrl: 'https://long-domain.com/foo/bar',
|
longUrl: 'https://long-domain.com/foo/bar',
|
||||||
|
|
|
@ -1,21 +1,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import sinon from 'sinon';
|
|
||||||
import searchBarCreator from '../../src/short-urls/SearchBar';
|
import searchBarCreator from '../../src/short-urls/SearchBar';
|
||||||
import SearchField from '../../src/utils/SearchField';
|
import SearchField from '../../src/utils/SearchField';
|
||||||
import Tag from '../../src/tags/helpers/Tag';
|
import Tag from '../../src/tags/helpers/Tag';
|
||||||
|
|
||||||
describe('<SearchBar />', () => {
|
describe('<SearchBar />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
const listShortUrlsMock = sinon.spy();
|
const listShortUrlsMock = jest.fn();
|
||||||
const SearchBar = searchBarCreator({});
|
const SearchBar = searchBarCreator({});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
listShortUrlsMock.resetHistory();
|
listShortUrlsMock.mockReset();
|
||||||
|
wrapper && wrapper.unmount();
|
||||||
if (wrapper) {
|
|
||||||
wrapper.unmount();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a SearchField', () => {
|
it('renders a SearchField', () => {
|
||||||
|
@ -42,9 +38,9 @@ describe('<SearchBar />', () => {
|
||||||
wrapper = shallow(<SearchBar shortUrlsListParams={{}} listShortUrls={listShortUrlsMock} />);
|
wrapper = shallow(<SearchBar shortUrlsListParams={{}} listShortUrls={listShortUrlsMock} />);
|
||||||
const searchField = wrapper.find(SearchField);
|
const searchField = wrapper.find(SearchField);
|
||||||
|
|
||||||
expect(listShortUrlsMock.callCount).toEqual(0);
|
expect(listShortUrlsMock).not.toHaveBeenCalled();
|
||||||
searchField.simulate('change');
|
searchField.simulate('change');
|
||||||
expect(listShortUrlsMock.callCount).toEqual(1);
|
expect(listShortUrlsMock).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates short URLs list when a tag is removed', () => {
|
it('updates short URLs list when a tag is removed', () => {
|
||||||
|
@ -53,8 +49,8 @@ describe('<SearchBar />', () => {
|
||||||
);
|
);
|
||||||
const tag = wrapper.find(Tag).first();
|
const tag = wrapper.find(Tag).first();
|
||||||
|
|
||||||
expect(listShortUrlsMock.callCount).toEqual(0);
|
expect(listShortUrlsMock).not.toHaveBeenCalled();
|
||||||
tag.simulate('close');
|
tag.simulate('close');
|
||||||
expect(listShortUrlsMock.callCount).toEqual(1);
|
expect(listShortUrlsMock).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,12 +3,11 @@ import { shallow } from 'enzyme';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||||
import { Tooltip } from 'reactstrap';
|
import { Tooltip } from 'reactstrap';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import createCreateShortUrlResult from '../../../src/short-urls/helpers/CreateShortUrlResult';
|
import createCreateShortUrlResult from '../../../src/short-urls/helpers/CreateShortUrlResult';
|
||||||
|
|
||||||
describe('<CreateShortUrlResult />', () => {
|
describe('<CreateShortUrlResult />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
const stateFlagTimeout = sinon.spy();
|
const stateFlagTimeout = jest.fn();
|
||||||
const createWrapper = (result, error = false) => {
|
const createWrapper = (result, error = false) => {
|
||||||
const CreateShortUrlResult = createCreateShortUrlResult(stateFlagTimeout);
|
const CreateShortUrlResult = createCreateShortUrlResult(stateFlagTimeout);
|
||||||
|
|
||||||
|
@ -18,7 +17,7 @@ describe('<CreateShortUrlResult />', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
stateFlagTimeout.resetHistory();
|
stateFlagTimeout.mockReset();
|
||||||
wrapper && wrapper.unmount();
|
wrapper && wrapper.unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -48,8 +47,8 @@ describe('<CreateShortUrlResult />', () => {
|
||||||
const wrapper = createWrapper({ shortUrl: 'https://doma.in/abc123' });
|
const wrapper = createWrapper({ shortUrl: 'https://doma.in/abc123' });
|
||||||
const copyBtn = wrapper.find(CopyToClipboard);
|
const copyBtn = wrapper.find(CopyToClipboard);
|
||||||
|
|
||||||
expect(stateFlagTimeout.callCount).toEqual(0);
|
expect(stateFlagTimeout).not.toHaveBeenCalled();
|
||||||
copyBtn.simulate('copy');
|
copyBtn.simulate('copy');
|
||||||
expect(stateFlagTimeout.callCount).toEqual(1);
|
expect(stateFlagTimeout).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import DeleteShortUrlModal from '../../../src/short-urls/helpers/DeleteShortUrlModal';
|
import DeleteShortUrlModal from '../../../src/short-urls/helpers/DeleteShortUrlModal';
|
||||||
|
|
||||||
describe('<DeleteShortUrlModal />', () => {
|
describe('<DeleteShortUrlModal />', () => {
|
||||||
|
@ -11,7 +10,7 @@ describe('<DeleteShortUrlModal />', () => {
|
||||||
shortCode: 'abc123',
|
shortCode: 'abc123',
|
||||||
originalUrl: 'https://long-domain.com/foo/bar',
|
originalUrl: 'https://long-domain.com/foo/bar',
|
||||||
};
|
};
|
||||||
const deleteShortUrl = sinon.fake.returns(Promise.resolve());
|
const deleteShortUrl = jest.fn(() => Promise.resolve());
|
||||||
const createWrapper = (shortUrlDeletion) => {
|
const createWrapper = (shortUrlDeletion) => {
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
<DeleteShortUrlModal
|
<DeleteShortUrlModal
|
||||||
|
@ -30,7 +29,7 @@ describe('<DeleteShortUrlModal />', () => {
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
wrapper && wrapper.unmount();
|
wrapper && wrapper.unmount();
|
||||||
deleteShortUrl.resetHistory();
|
deleteShortUrl.mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows threshold error message when threshold error occurs', () => {
|
it('shows threshold error message when threshold error occurs', () => {
|
||||||
|
@ -106,9 +105,9 @@ describe('<DeleteShortUrlModal />', () => {
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
const form = wrapper.find('form');
|
const form = wrapper.find('form');
|
||||||
|
|
||||||
expect(deleteShortUrl.callCount).toEqual(0);
|
expect(deleteShortUrl).not.toHaveBeenCalled();
|
||||||
form.simulate('submit', { preventDefault: identity });
|
form.simulate('submit', { preventDefault: identity });
|
||||||
expect(deleteShortUrl.callCount).toEqual(1);
|
expect(deleteShortUrl).toHaveBeenCalledTimes(1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import { Modal } from 'reactstrap';
|
import { Modal } from 'reactstrap';
|
||||||
import createEditTagsModal from '../../../src/short-urls/helpers/EditTagsModal';
|
import createEditTagsModal from '../../../src/short-urls/helpers/EditTagsModal';
|
||||||
|
|
||||||
|
@ -8,10 +7,10 @@ describe('<EditTagsModal />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
const shortCode = 'abc123';
|
const shortCode = 'abc123';
|
||||||
const TagsSelector = () => '';
|
const TagsSelector = () => '';
|
||||||
const editShortUrlTags = sinon.fake.resolves();
|
const editShortUrlTags = jest.fn(() => Promise.resolve());
|
||||||
const shortUrlTagsEdited = sinon.fake();
|
const shortUrlTagsEdited = jest.fn();
|
||||||
const resetShortUrlsTags = sinon.fake();
|
const resetShortUrlsTags = jest.fn();
|
||||||
const toggle = sinon.fake();
|
const toggle = jest.fn();
|
||||||
const createWrapper = (shortUrlTags) => {
|
const createWrapper = (shortUrlTags) => {
|
||||||
const EditTagsModal = createEditTagsModal(TagsSelector);
|
const EditTagsModal = createEditTagsModal(TagsSelector);
|
||||||
|
|
||||||
|
@ -37,10 +36,10 @@ describe('<EditTagsModal />', () => {
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
wrapper && wrapper.unmount();
|
wrapper && wrapper.unmount();
|
||||||
editShortUrlTags.resetHistory();
|
editShortUrlTags.mockClear();
|
||||||
shortUrlTagsEdited.resetHistory();
|
shortUrlTagsEdited.mockReset();
|
||||||
resetShortUrlsTags.resetHistory();
|
resetShortUrlsTags.mockReset();
|
||||||
toggle.resetHistory();
|
toggle.mockReset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('resets tags when component is mounted', () => {
|
it('resets tags when component is mounted', () => {
|
||||||
|
@ -51,7 +50,7 @@ describe('<EditTagsModal />', () => {
|
||||||
error: false,
|
error: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(resetShortUrlsTags.callCount).toEqual(1);
|
expect(resetShortUrlsTags).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders tags selector and save button when loaded', () => {
|
it('renders tags selector and save button when loaded', () => {
|
||||||
|
@ -92,12 +91,12 @@ describe('<EditTagsModal />', () => {
|
||||||
|
|
||||||
saveBtn.simulate('click');
|
saveBtn.simulate('click');
|
||||||
|
|
||||||
expect(editShortUrlTags.callCount).toEqual(1);
|
expect(editShortUrlTags).toHaveBeenCalledTimes(1);
|
||||||
expect(editShortUrlTags.getCall(0).args).toEqual([ shortCode, []]);
|
expect(editShortUrlTags.mock.calls[0]).toEqual([ shortCode, []]);
|
||||||
|
|
||||||
// Wrap this expect in a setImmediate since it is called as a result of an inner promise
|
// Wrap this expect in a setImmediate since it is called as a result of an inner promise
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
expect(toggle.callCount).toEqual(1);
|
expect(toggle).toHaveBeenCalledTimes(1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -112,7 +111,7 @@ describe('<EditTagsModal />', () => {
|
||||||
const modal = wrapper.find(Modal);
|
const modal = wrapper.find(Modal);
|
||||||
|
|
||||||
modal.simulate('closed');
|
modal.simulate('closed');
|
||||||
expect(shortUrlTagsEdited.callCount).toEqual(0);
|
expect(shortUrlTagsEdited).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('notifies tags have been edited when window is closed after saving', (done) => {
|
it('notifies tags have been edited when window is closed after saving', (done) => {
|
||||||
|
@ -130,8 +129,8 @@ describe('<EditTagsModal />', () => {
|
||||||
// Wrap this expect in a setImmediate since it is called as a result of an inner promise
|
// Wrap this expect in a setImmediate since it is called as a result of an inner promise
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
modal.simulate('closed');
|
modal.simulate('closed');
|
||||||
expect(shortUrlTagsEdited.callCount).toEqual(1);
|
expect(shortUrlTagsEdited).toHaveBeenCalledTimes(1);
|
||||||
expect(shortUrlTagsEdited.getCall(0).args).toEqual([ shortCode, []]);
|
expect(shortUrlTagsEdited.mock.calls[0]).toEqual([ shortCode, []]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -146,6 +145,6 @@ describe('<EditTagsModal />', () => {
|
||||||
const cancelBtn = wrapper.find('.btn-link');
|
const cancelBtn = wrapper.find('.btn-link');
|
||||||
|
|
||||||
cancelBtn.simulate('click');
|
cancelBtn.simulate('click');
|
||||||
expect(toggle.callCount).toEqual(1);
|
expect(toggle).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { shallow } from 'enzyme';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import Moment from 'react-moment';
|
import Moment from 'react-moment';
|
||||||
import { assoc, toString } from 'ramda';
|
import { assoc, toString } from 'ramda';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import createShortUrlsRow from '../../../src/short-urls/helpers/ShortUrlsRow';
|
import createShortUrlsRow from '../../../src/short-urls/helpers/ShortUrlsRow';
|
||||||
import ExternalLink from '../../../src/utils/ExternalLink';
|
import ExternalLink from '../../../src/utils/ExternalLink';
|
||||||
import Tag from '../../../src/tags/helpers/Tag';
|
import Tag from '../../../src/tags/helpers/Tag';
|
||||||
|
@ -12,7 +11,7 @@ describe('<ShortUrlsRow />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
const mockFunction = () => '';
|
const mockFunction = () => '';
|
||||||
const ShortUrlsRowMenu = mockFunction;
|
const ShortUrlsRowMenu = mockFunction;
|
||||||
const stateFlagTimeout = sinon.spy();
|
const stateFlagTimeout = jest.fn();
|
||||||
const colorGenerator = {
|
const colorGenerator = {
|
||||||
getColorForKey: mockFunction,
|
getColorForKey: mockFunction,
|
||||||
setColorForKey: mockFunction,
|
setColorForKey: mockFunction,
|
||||||
|
@ -92,9 +91,9 @@ describe('<ShortUrlsRow />', () => {
|
||||||
const menu = col.find(ShortUrlsRowMenu);
|
const menu = col.find(ShortUrlsRowMenu);
|
||||||
|
|
||||||
expect(menu).toHaveLength(1);
|
expect(menu).toHaveLength(1);
|
||||||
expect(stateFlagTimeout.called).toEqual(false);
|
expect(stateFlagTimeout).not.toHaveBeenCalled();
|
||||||
menu.simulate('copyToClipboard');
|
menu.simulate('copyToClipboard');
|
||||||
expect(stateFlagTimeout.calledOnce).toEqual(true);
|
expect(stateFlagTimeout).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows copy hint when state prop is true', () => {
|
it('shows copy hint when state prop is true', () => {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import { ButtonDropdown, DropdownItem } from 'reactstrap';
|
import { ButtonDropdown, DropdownItem } from 'reactstrap';
|
||||||
import createShortUrlsRowMenu from '../../../src/short-urls/helpers/ShortUrlsRowMenu';
|
import createShortUrlsRowMenu from '../../../src/short-urls/helpers/ShortUrlsRowMenu';
|
||||||
import PreviewModal from '../../../src/short-urls/helpers/PreviewModal';
|
import PreviewModal from '../../../src/short-urls/helpers/PreviewModal';
|
||||||
|
@ -10,7 +9,7 @@ describe('<ShortUrlsRowMenu />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
const DeleteShortUrlModal = () => '';
|
const DeleteShortUrlModal = () => '';
|
||||||
const EditTagsModal = () => '';
|
const EditTagsModal = () => '';
|
||||||
const onCopyToClipboard = sinon.spy();
|
const onCopyToClipboard = jest.fn();
|
||||||
const selectedServer = { id: 'abc123' };
|
const selectedServer = { id: 'abc123' };
|
||||||
const shortUrl = {
|
const shortUrl = {
|
||||||
shortCode: 'abc123',
|
shortCode: 'abc123',
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import reducer, {
|
import reducer, {
|
||||||
CREATE_SHORT_URL_START,
|
CREATE_SHORT_URL_START,
|
||||||
CREATE_SHORT_URL_ERROR,
|
CREATE_SHORT_URL_ERROR,
|
||||||
|
@ -48,12 +47,12 @@ describe('shortUrlCreationReducer', () => {
|
||||||
|
|
||||||
describe('createShortUrl', () => {
|
describe('createShortUrl', () => {
|
||||||
const createApiClientMock = (result) => ({
|
const createApiClientMock = (result) => ({
|
||||||
createShortUrl: sinon.fake.returns(result),
|
createShortUrl: jest.fn(() => result),
|
||||||
});
|
});
|
||||||
const dispatch = sinon.spy();
|
const dispatch = jest.fn();
|
||||||
const getState = () => ({});
|
const getState = () => ({});
|
||||||
|
|
||||||
afterEach(() => dispatch.resetHistory());
|
afterEach(() => dispatch.mockReset());
|
||||||
|
|
||||||
it('calls API on success', async () => {
|
it('calls API on success', async () => {
|
||||||
const expectedDispatchCalls = 2;
|
const expectedDispatchCalls = 2;
|
||||||
|
@ -62,12 +61,12 @@ describe('shortUrlCreationReducer', () => {
|
||||||
const dispatchable = createShortUrl(() => apiClientMock)({});
|
const dispatchable = createShortUrl(() => apiClientMock)({});
|
||||||
|
|
||||||
await dispatchable(dispatch, getState);
|
await dispatchable(dispatch, getState);
|
||||||
|
const [ firstDispatchCallArgs, secondDispatchCallArgs ] = dispatch.mock.calls;
|
||||||
|
|
||||||
expect(apiClientMock.createShortUrl.callCount).toEqual(1);
|
expect(apiClientMock.createShortUrl).toHaveBeenCalledTimes(1);
|
||||||
|
expect(dispatch).toHaveBeenCalledTimes(expectedDispatchCalls);
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(firstDispatchCallArgs).toEqual([{ type: CREATE_SHORT_URL_START }]);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: CREATE_SHORT_URL_START }]);
|
expect(secondDispatchCallArgs).toEqual([{ type: CREATE_SHORT_URL, result }]);
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: CREATE_SHORT_URL, result }]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws on error', async () => {
|
it('throws on error', async () => {
|
||||||
|
@ -81,12 +80,12 @@ describe('shortUrlCreationReducer', () => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
expect(e).toEqual(error);
|
expect(e).toEqual(error);
|
||||||
}
|
}
|
||||||
|
const [ firstDispatchCallArgs, secondDispatchCallArgs ] = dispatch.mock.calls;
|
||||||
|
|
||||||
expect(apiClientMock.createShortUrl.callCount).toEqual(1);
|
expect(apiClientMock.createShortUrl).toHaveBeenCalledTimes(1);
|
||||||
|
expect(dispatch).toHaveBeenCalledTimes(expectedDispatchCalls);
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(firstDispatchCallArgs).toEqual([{ type: CREATE_SHORT_URL_START }]);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: CREATE_SHORT_URL_START }]);
|
expect(secondDispatchCallArgs).toEqual([{ type: CREATE_SHORT_URL_ERROR }]);
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: CREATE_SHORT_URL_ERROR }]);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import reducer, {
|
import reducer, {
|
||||||
DELETE_SHORT_URL, DELETE_SHORT_URL_ERROR,
|
DELETE_SHORT_URL, DELETE_SHORT_URL_ERROR,
|
||||||
DELETE_SHORT_URL_START,
|
DELETE_SHORT_URL_START,
|
||||||
|
@ -58,36 +57,37 @@ describe('shortUrlDeletionReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deleteShortUrl', () => {
|
describe('deleteShortUrl', () => {
|
||||||
const dispatch = sinon.spy();
|
const dispatch = jest.fn();
|
||||||
const getState = sinon.fake.returns({ selectedServer: {} });
|
const getState = jest.fn().mockReturnValue({ selectedServer: {} });
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
dispatch.resetHistory();
|
dispatch.mockReset();
|
||||||
getState.resetHistory();
|
getState.mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches proper actions if API client request succeeds', async () => {
|
it('dispatches proper actions if API client request succeeds', async () => {
|
||||||
const apiClientMock = {
|
const apiClientMock = {
|
||||||
deleteShortUrl: sinon.fake.resolves(''),
|
deleteShortUrl: jest.fn(() => ''),
|
||||||
};
|
};
|
||||||
const shortCode = 'abc123';
|
const shortCode = 'abc123';
|
||||||
const expectedDispatchCalls = 2;
|
const expectedDispatchCalls = 2;
|
||||||
|
|
||||||
await deleteShortUrl(() => apiClientMock)(shortCode)(dispatch, getState);
|
await deleteShortUrl(() => apiClientMock)(shortCode)(dispatch, getState);
|
||||||
|
const [ firstDispatchCallArgs, secondDispatchCallArgs ] = dispatch.mock.calls;
|
||||||
|
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(dispatch).toHaveBeenCalledTimes(expectedDispatchCalls);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: DELETE_SHORT_URL_START }]);
|
expect(firstDispatchCallArgs).toEqual([{ type: DELETE_SHORT_URL_START }]);
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: DELETE_SHORT_URL, shortCode }]);
|
expect(secondDispatchCallArgs).toEqual([{ type: DELETE_SHORT_URL, shortCode }]);
|
||||||
|
|
||||||
expect(apiClientMock.deleteShortUrl.callCount).toEqual(1);
|
expect(apiClientMock.deleteShortUrl).toHaveBeenCalledTimes(1);
|
||||||
expect(apiClientMock.deleteShortUrl.getCall(0).args).toEqual([ shortCode ]);
|
expect(apiClientMock.deleteShortUrl.mock.calls[0]).toEqual([ shortCode ]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches proper actions if API client request fails', async () => {
|
it('dispatches proper actions if API client request fails', async () => {
|
||||||
const data = { foo: 'bar' };
|
const data = { foo: 'bar' };
|
||||||
const error = { response: { data } };
|
const error = { response: { data } };
|
||||||
const apiClientMock = {
|
const apiClientMock = {
|
||||||
deleteShortUrl: sinon.fake.returns(Promise.reject(error)),
|
deleteShortUrl: jest.fn(() => Promise.reject(error)),
|
||||||
};
|
};
|
||||||
const shortCode = 'abc123';
|
const shortCode = 'abc123';
|
||||||
const expectedDispatchCalls = 2;
|
const expectedDispatchCalls = 2;
|
||||||
|
@ -97,13 +97,14 @@ describe('shortUrlDeletionReducer', () => {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
expect(e).toEqual(error);
|
expect(e).toEqual(error);
|
||||||
}
|
}
|
||||||
|
const [ firstDispatchCallArgs, secondDispatchCallArgs ] = dispatch.mock.calls;
|
||||||
|
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(dispatch).toHaveBeenCalledTimes(expectedDispatchCalls);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: DELETE_SHORT_URL_START }]);
|
expect(firstDispatchCallArgs).toEqual([{ type: DELETE_SHORT_URL_START }]);
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: DELETE_SHORT_URL_ERROR, errorData: data }]);
|
expect(secondDispatchCallArgs).toEqual([{ type: DELETE_SHORT_URL_ERROR, errorData: data }]);
|
||||||
|
|
||||||
expect(apiClientMock.deleteShortUrl.callCount).toEqual(1);
|
expect(apiClientMock.deleteShortUrl).toHaveBeenCalledTimes(1);
|
||||||
expect(apiClientMock.deleteShortUrl.getCall(0).args).toEqual([ shortCode ]);
|
expect(apiClientMock.deleteShortUrl.mock.calls[0]).toEqual([ shortCode ]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import reducer, {
|
import reducer, {
|
||||||
LIST_SHORT_URLS,
|
LIST_SHORT_URLS,
|
||||||
LIST_SHORT_URLS_ERROR,
|
LIST_SHORT_URLS_ERROR,
|
||||||
|
@ -73,42 +72,44 @@ describe('shortUrlsListReducer', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('listShortUrls', () => {
|
describe('listShortUrls', () => {
|
||||||
const dispatch = sinon.spy();
|
const dispatch = jest.fn();
|
||||||
const getState = sinon.fake.returns({ selectedServer: {} });
|
const getState = jest.fn().mockReturnValue({ selectedServer: {} });
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
dispatch.resetHistory();
|
dispatch.mockReset();
|
||||||
getState.resetHistory();
|
getState.mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches proper actions if API client request succeeds', async () => {
|
it('dispatches proper actions if API client request succeeds', async () => {
|
||||||
const apiClientMock = {
|
const apiClientMock = {
|
||||||
listShortUrls: sinon.fake.resolves([]),
|
listShortUrls: jest.fn().mockResolvedValue([]),
|
||||||
};
|
};
|
||||||
const expectedDispatchCalls = 2;
|
const expectedDispatchCalls = 2;
|
||||||
|
|
||||||
await listShortUrls(() => apiClientMock)()(dispatch, getState);
|
await listShortUrls(() => apiClientMock)()(dispatch, getState);
|
||||||
|
const [ firstDispatchCallArgs, secondDispatchCallArgs ] = dispatch.mock.calls;
|
||||||
|
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(dispatch).toHaveBeenCalledTimes(expectedDispatchCalls);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: LIST_SHORT_URLS_START }]);
|
expect(firstDispatchCallArgs).toEqual([{ type: LIST_SHORT_URLS_START }]);
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: LIST_SHORT_URLS, shortUrls: [], params: {} }]);
|
expect(secondDispatchCallArgs).toEqual([{ type: LIST_SHORT_URLS, shortUrls: [], params: {} }]);
|
||||||
|
|
||||||
expect(apiClientMock.listShortUrls.callCount).toEqual(1);
|
expect(apiClientMock.listShortUrls).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches proper actions if API client request fails', async () => {
|
it('dispatches proper actions if API client request fails', async () => {
|
||||||
const apiClientMock = {
|
const apiClientMock = {
|
||||||
listShortUrls: sinon.fake.rejects(),
|
listShortUrls: jest.fn().mockRejectedValue(),
|
||||||
};
|
};
|
||||||
const expectedDispatchCalls = 2;
|
const expectedDispatchCalls = 2;
|
||||||
|
|
||||||
await listShortUrls(() => apiClientMock)()(dispatch, getState);
|
await listShortUrls(() => apiClientMock)()(dispatch, getState);
|
||||||
|
const [ firstDispatchCallArgs, secondDispatchCallArgs ] = dispatch.mock.calls;
|
||||||
|
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(dispatch).toHaveBeenCalledTimes(expectedDispatchCalls);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: LIST_SHORT_URLS_START }]);
|
expect(firstDispatchCallArgs).toEqual([{ type: LIST_SHORT_URLS_START }]);
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: LIST_SHORT_URLS_ERROR, params: {} }]);
|
expect(secondDispatchCallArgs).toEqual([{ type: LIST_SHORT_URLS_ERROR, params: {} }]);
|
||||||
|
|
||||||
expect(apiClientMock.listShortUrls.callCount).toEqual(1);
|
expect(apiClientMock.listShortUrls).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import createTagsList from '../../src/tags/TagsList';
|
import createTagsList from '../../src/tags/TagsList';
|
||||||
import MuttedMessage from '../../src/utils/MuttedMessage';
|
import MuttedMessage from '../../src/utils/MuttedMessage';
|
||||||
import SearchField from '../../src/utils/SearchField';
|
import SearchField from '../../src/utils/SearchField';
|
||||||
|
@ -9,7 +8,7 @@ import { rangeOf } from '../../src/utils/utils';
|
||||||
|
|
||||||
describe('<TagsList />', () => {
|
describe('<TagsList />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
const filterTags = sinon.spy();
|
const filterTags = jest.fn();
|
||||||
const TagCard = () => '';
|
const TagCard = () => '';
|
||||||
const createWrapper = (tagsList) => {
|
const createWrapper = (tagsList) => {
|
||||||
const params = { serverId: '1' };
|
const params = { serverId: '1' };
|
||||||
|
@ -24,7 +23,7 @@ describe('<TagsList />', () => {
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
wrapper && wrapper.unmount();
|
wrapper && wrapper.unmount();
|
||||||
filterTags.resetHistory();
|
filterTags.mockReset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows a loading message when tags are being loaded', () => {
|
it('shows a loading message when tags are being loaded', () => {
|
||||||
|
@ -67,11 +66,11 @@ describe('<TagsList />', () => {
|
||||||
const searchField = wrapper.find(SearchField);
|
const searchField = wrapper.find(SearchField);
|
||||||
|
|
||||||
expect(searchField).toHaveLength(1);
|
expect(searchField).toHaveLength(1);
|
||||||
expect(filterTags.callCount).toEqual(0);
|
expect(filterTags).not.toHaveBeenCalled();
|
||||||
searchField.simulate('change');
|
searchField.simulate('change');
|
||||||
|
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
expect(filterTags.callCount).toEqual(1);
|
expect(filterTags).toHaveBeenCalledTimes(1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import { Modal, ModalBody, ModalFooter } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter } from 'reactstrap';
|
||||||
import DeleteTagConfirmModal from '../../../src/tags/helpers/DeleteTagConfirmModal';
|
import DeleteTagConfirmModal from '../../../src/tags/helpers/DeleteTagConfirmModal';
|
||||||
|
|
||||||
describe('<DeleteTagConfirmModal />', () => {
|
describe('<DeleteTagConfirmModal />', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
const tag = 'nodejs';
|
const tag = 'nodejs';
|
||||||
const deleteTag = sinon.spy();
|
const deleteTag = jest.fn();
|
||||||
const tagDeleted = sinon.spy();
|
const tagDeleted = jest.fn();
|
||||||
const createWrapper = (tagDelete) => {
|
const createWrapper = (tagDelete) => {
|
||||||
wrapper = shallow(
|
wrapper = shallow(
|
||||||
<DeleteTagConfirmModal
|
<DeleteTagConfirmModal
|
||||||
|
@ -26,8 +25,8 @@ describe('<DeleteTagConfirmModal />', () => {
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
wrapper && wrapper.unmount();
|
wrapper && wrapper.unmount();
|
||||||
deleteTag.resetHistory();
|
deleteTag.mockReset();
|
||||||
tagDeleted.resetHistory();
|
tagDeleted.mockReset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('asks confirmation for provided tag to be deleted', () => {
|
it('asks confirmation for provided tag to be deleted', () => {
|
||||||
|
@ -63,8 +62,8 @@ describe('<DeleteTagConfirmModal />', () => {
|
||||||
const delBtn = footer.find('.btn-danger');
|
const delBtn = footer.find('.btn-danger');
|
||||||
|
|
||||||
delBtn.simulate('click');
|
delBtn.simulate('click');
|
||||||
expect(deleteTag.calledOnce).toEqual(true);
|
expect(deleteTag).toHaveBeenCalledTimes(1);
|
||||||
expect(deleteTag.calledWith(tag)).toEqual(true);
|
expect(deleteTag).toHaveBeenCalledWith(tag);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does no further actions when modal is closed without deleting tag', () => {
|
it('does no further actions when modal is closed without deleting tag', () => {
|
||||||
|
@ -72,7 +71,7 @@ describe('<DeleteTagConfirmModal />', () => {
|
||||||
const modal = wrapper.find(Modal);
|
const modal = wrapper.find(Modal);
|
||||||
|
|
||||||
modal.simulate('closed');
|
modal.simulate('closed');
|
||||||
expect(tagDeleted.called).toEqual(false);
|
expect(tagDeleted).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('notifies tag to be deleted when modal is closed after deleting tag', () => {
|
it('notifies tag to be deleted when modal is closed after deleting tag', () => {
|
||||||
|
@ -81,7 +80,7 @@ describe('<DeleteTagConfirmModal />', () => {
|
||||||
|
|
||||||
wrapper.instance().tagWasDeleted = true;
|
wrapper.instance().tagWasDeleted = true;
|
||||||
modal.simulate('closed');
|
modal.simulate('closed');
|
||||||
expect(tagDeleted.calledOnce).toEqual(true);
|
expect(tagDeleted).toHaveBeenCalledTimes(1);
|
||||||
expect(tagDeleted.calledWith(tag)).toEqual(true);
|
expect(tagDeleted).toHaveBeenCalledWith(tag);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import reducer, {
|
import reducer, {
|
||||||
DELETE_TAG_START,
|
DELETE_TAG_START,
|
||||||
DELETE_TAG_ERROR,
|
DELETE_TAG_ERROR,
|
||||||
|
@ -42,12 +41,12 @@ describe('tagDeleteReducer', () => {
|
||||||
|
|
||||||
describe('deleteTag', () => {
|
describe('deleteTag', () => {
|
||||||
const createApiClientMock = (result) => ({
|
const createApiClientMock = (result) => ({
|
||||||
deleteTags: sinon.fake.returns(result),
|
deleteTags: jest.fn(() => result),
|
||||||
});
|
});
|
||||||
const dispatch = sinon.spy();
|
const dispatch = jest.fn();
|
||||||
const getState = () => ({});
|
const getState = () => ({});
|
||||||
|
|
||||||
afterEach(() => dispatch.resetHistory());
|
afterEach(() => dispatch.mockReset());
|
||||||
|
|
||||||
it('calls API on success', async () => {
|
it('calls API on success', async () => {
|
||||||
const expectedDispatchCalls = 2;
|
const expectedDispatchCalls = 2;
|
||||||
|
@ -57,12 +56,12 @@ describe('tagDeleteReducer', () => {
|
||||||
|
|
||||||
await dispatchable(dispatch, getState);
|
await dispatchable(dispatch, getState);
|
||||||
|
|
||||||
expect(apiClientMock.deleteTags.callCount).toEqual(1);
|
expect(apiClientMock.deleteTags).toHaveBeenCalledTimes(1);
|
||||||
expect(apiClientMock.deleteTags.getCall(0).args).toEqual([[ tag ]]);
|
expect(apiClientMock.deleteTags).toHaveBeenNthCalledWith(1, [ tag ]);
|
||||||
|
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(dispatch).toHaveBeenCalledTimes(expectedDispatchCalls);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: DELETE_TAG_START }]);
|
expect(dispatch).toHaveBeenNthCalledWith(1, { type: DELETE_TAG_START });
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: DELETE_TAG }]);
|
expect(dispatch).toHaveBeenNthCalledWith(2, { type: DELETE_TAG });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws on error', async () => {
|
it('throws on error', async () => {
|
||||||
|
@ -78,12 +77,12 @@ describe('tagDeleteReducer', () => {
|
||||||
expect(e).toEqual(error);
|
expect(e).toEqual(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(apiClientMock.deleteTags.callCount).toEqual(1);
|
expect(apiClientMock.deleteTags).toHaveBeenCalledTimes(1);
|
||||||
expect(apiClientMock.deleteTags.getCall(0).args).toEqual([[ tag ]]);
|
expect(apiClientMock.deleteTags).toHaveBeenNthCalledWith(1, [ tag ]);
|
||||||
|
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(dispatch).toHaveBeenCalledTimes(expectedDispatchCalls);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: DELETE_TAG_START }]);
|
expect(dispatch).toHaveBeenNthCalledWith(1, { type: DELETE_TAG_START });
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: DELETE_TAG_ERROR }]);
|
expect(dispatch).toHaveBeenNthCalledWith(2, { type: DELETE_TAG_ERROR });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import reducer, {
|
import reducer, {
|
||||||
EDIT_TAG_START,
|
EDIT_TAG_START,
|
||||||
EDIT_TAG_ERROR,
|
EDIT_TAG_ERROR,
|
||||||
|
@ -46,17 +45,17 @@ describe('tagEditReducer', () => {
|
||||||
|
|
||||||
describe('editTag', () => {
|
describe('editTag', () => {
|
||||||
const createApiClientMock = (result) => ({
|
const createApiClientMock = (result) => ({
|
||||||
editTag: sinon.fake.returns(result),
|
editTag: jest.fn(() => result),
|
||||||
});
|
});
|
||||||
const colorGenerator = {
|
const colorGenerator = {
|
||||||
setColorForKey: sinon.spy(),
|
setColorForKey: jest.fn(),
|
||||||
};
|
};
|
||||||
const dispatch = sinon.spy();
|
const dispatch = jest.fn();
|
||||||
const getState = () => ({});
|
const getState = () => ({});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
colorGenerator.setColorForKey.resetHistory();
|
colorGenerator.setColorForKey.mockReset();
|
||||||
dispatch.resetHistory();
|
dispatch.mockReset();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calls API on success', async () => {
|
it('calls API on success', async () => {
|
||||||
|
@ -69,19 +68,18 @@ describe('tagEditReducer', () => {
|
||||||
|
|
||||||
await dispatchable(dispatch, getState);
|
await dispatchable(dispatch, getState);
|
||||||
|
|
||||||
expect(apiClientMock.editTag.callCount).toEqual(1);
|
expect(apiClientMock.editTag).toHaveBeenCalledTimes(1);
|
||||||
expect(apiClientMock.editTag.getCall(0).args).toEqual([ oldName, newName ]);
|
expect(apiClientMock.editTag).toHaveBeenCalledWith(oldName, newName);
|
||||||
|
|
||||||
expect(colorGenerator.setColorForKey.callCount).toEqual(1);
|
expect(colorGenerator.setColorForKey).toHaveBeenCalledTimes(1);
|
||||||
expect(colorGenerator.setColorForKey.getCall(0).args).toEqual([ newName, color ]);
|
expect(colorGenerator.setColorForKey).toHaveBeenCalledWith(newName, color);
|
||||||
|
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(dispatch).toHaveBeenCalledTimes(expectedDispatchCalls);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: EDIT_TAG_START }]);
|
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_TAG_START });
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: EDIT_TAG, oldName, newName }]);
|
expect(dispatch).toHaveBeenNthCalledWith(2, { type: EDIT_TAG, oldName, newName });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws on error', async () => {
|
it('throws on error', async () => {
|
||||||
const expectedDispatchCalls = 2;
|
|
||||||
const error = 'Error';
|
const error = 'Error';
|
||||||
const oldName = 'foo';
|
const oldName = 'foo';
|
||||||
const newName = 'bar';
|
const newName = 'bar';
|
||||||
|
@ -95,14 +93,14 @@ describe('tagEditReducer', () => {
|
||||||
expect(e).toEqual(error);
|
expect(e).toEqual(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(apiClientMock.editTag.callCount).toEqual(1);
|
expect(apiClientMock.editTag).toHaveBeenCalledTimes(1);
|
||||||
expect(apiClientMock.editTag.getCall(0).args).toEqual([ oldName, newName ]);
|
expect(apiClientMock.editTag).toHaveBeenCalledWith(oldName, newName);
|
||||||
|
|
||||||
expect(colorGenerator.setColorForKey.callCount).toEqual(0);
|
expect(colorGenerator.setColorForKey).not.toHaveBeenCalled();
|
||||||
|
|
||||||
expect(dispatch.callCount).toEqual(expectedDispatchCalls);
|
expect(dispatch).toHaveBeenCalledTimes(2);
|
||||||
expect(dispatch.getCall(0).args).toEqual([{ type: EDIT_TAG_START }]);
|
expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_TAG_START });
|
||||||
expect(dispatch.getCall(1).args).toEqual([{ type: EDIT_TAG_ERROR }]);
|
expect(dispatch).toHaveBeenNthCalledWith(2, { type: EDIT_TAG_ERROR });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { DropdownItem } from 'reactstrap';
|
||||||
import { identity, values } from 'ramda';
|
import { identity, values } from 'ramda';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faSortAmountDown as caretDownIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faSortAmountDown as caretDownIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import SortingDropdown from '../../src/utils/SortingDropdown';
|
import SortingDropdown from '../../src/utils/SortingDropdown';
|
||||||
|
|
||||||
describe('<SortingDropdown />', () => {
|
describe('<SortingDropdown />', () => {
|
||||||
|
@ -44,35 +43,35 @@ describe('<SortingDropdown />', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('triggers change function when item is clicked and no order field was provided', () => {
|
it('triggers change function when item is clicked and no order field was provided', () => {
|
||||||
const onChange = sinon.spy();
|
const onChange = jest.fn();
|
||||||
const wrapper = createWrapper({ onChange });
|
const wrapper = createWrapper({ onChange });
|
||||||
const firstItem = wrapper.find(DropdownItem).first();
|
const firstItem = wrapper.find(DropdownItem).first();
|
||||||
|
|
||||||
firstItem.simulate('click');
|
firstItem.simulate('click');
|
||||||
|
|
||||||
expect(onChange.callCount).toEqual(1);
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
expect(onChange.calledWith('foo', 'ASC')).toEqual(true);
|
expect(onChange).toHaveBeenCalledWith('foo', 'ASC');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('triggers change function when item is clicked and an order field was provided', () => {
|
it('triggers change function when item is clicked and an order field was provided', () => {
|
||||||
const onChange = sinon.spy();
|
const onChange = jest.fn();
|
||||||
const wrapper = createWrapper({ onChange, orderField: 'baz', orderDir: 'ASC' });
|
const wrapper = createWrapper({ onChange, orderField: 'baz', orderDir: 'ASC' });
|
||||||
const firstItem = wrapper.find(DropdownItem).first();
|
const firstItem = wrapper.find(DropdownItem).first();
|
||||||
|
|
||||||
firstItem.simulate('click');
|
firstItem.simulate('click');
|
||||||
|
|
||||||
expect(onChange.callCount).toEqual(1);
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
expect(onChange.calledWith('foo', 'ASC')).toEqual(true);
|
expect(onChange).toHaveBeenCalledWith('foo', 'ASC');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('updates order dir when already selected item is clicked', () => {
|
it('updates order dir when already selected item is clicked', () => {
|
||||||
const onChange = sinon.spy();
|
const onChange = jest.fn();
|
||||||
const wrapper = createWrapper({ onChange, orderField: 'foo', orderDir: 'ASC' });
|
const wrapper = createWrapper({ onChange, orderField: 'foo', orderDir: 'ASC' });
|
||||||
const firstItem = wrapper.find(DropdownItem).first();
|
const firstItem = wrapper.find(DropdownItem).first();
|
||||||
|
|
||||||
firstItem.simulate('click');
|
firstItem.simulate('click');
|
||||||
|
|
||||||
expect(onChange.callCount).toEqual(1);
|
expect(onChange).toHaveBeenCalledTimes(1);
|
||||||
expect(onChange.calledWith('foo', 'DESC')).toEqual(true);
|
expect(onChange).toHaveBeenCalledWith('foo', 'DESC');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import ColorGenerator from '../../../src/utils/services/ColorGenerator';
|
import ColorGenerator from '../../../src/utils/services/ColorGenerator';
|
||||||
|
|
||||||
describe('ColorGenerator', () => {
|
describe('ColorGenerator', () => {
|
||||||
let colorGenerator;
|
let colorGenerator;
|
||||||
const storageMock = {
|
const storageMock = {
|
||||||
set: sinon.fake(),
|
set: jest.fn(),
|
||||||
get: sinon.fake.returns(undefined),
|
get: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
storageMock.set.resetHistory();
|
storageMock.set.mockReset();
|
||||||
storageMock.get.resetHistory();
|
storageMock.get.mockReset();
|
||||||
|
|
||||||
colorGenerator = new ColorGenerator(storageMock);
|
colorGenerator = new ColorGenerator(storageMock);
|
||||||
});
|
});
|
||||||
|
@ -21,14 +20,14 @@ describe('ColorGenerator', () => {
|
||||||
colorGenerator.setColorForKey('foo', color);
|
colorGenerator.setColorForKey('foo', color);
|
||||||
|
|
||||||
expect(colorGenerator.getColorForKey('foo')).toEqual(color);
|
expect(colorGenerator.getColorForKey('foo')).toEqual(color);
|
||||||
expect(storageMock.set.callCount).toEqual(1);
|
expect(storageMock.set).toHaveBeenCalledTimes(1);
|
||||||
expect(storageMock.get.callCount).toEqual(1);
|
expect(storageMock.get).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('generates a random color when none is available for requested key', () => {
|
it('generates a random color when none is available for requested key', () => {
|
||||||
expect(colorGenerator.getColorForKey('bar')).toEqual(expect.stringMatching(/^#(?:[0-9a-fA-F]{6})$/));
|
expect(colorGenerator.getColorForKey('bar')).toEqual(expect.stringMatching(/^#(?:[0-9a-fA-F]{6})$/));
|
||||||
expect(storageMock.set.callCount).toEqual(1);
|
expect(storageMock.set).toHaveBeenCalledTimes(1);
|
||||||
expect(storageMock.get.callCount).toEqual(1);
|
expect(storageMock.get).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('trims and lower cases keys before trying to match', () => {
|
it('trims and lower cases keys before trying to match', () => {
|
||||||
|
@ -42,7 +41,7 @@ describe('ColorGenerator', () => {
|
||||||
expect(colorGenerator.getColorForKey('FOO')).toEqual(color);
|
expect(colorGenerator.getColorForKey('FOO')).toEqual(color);
|
||||||
expect(colorGenerator.getColorForKey('FOO ')).toEqual(color);
|
expect(colorGenerator.getColorForKey('FOO ')).toEqual(color);
|
||||||
expect(colorGenerator.getColorForKey(' FoO ')).toEqual(color);
|
expect(colorGenerator.getColorForKey(' FoO ')).toEqual(color);
|
||||||
expect(storageMock.set.callCount).toEqual(1);
|
expect(storageMock.set).toHaveBeenCalledTimes(1);
|
||||||
expect(storageMock.get.callCount).toEqual(1);
|
expect(storageMock.get).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import sinon from 'sinon';
|
|
||||||
import { head, last } from 'ramda';
|
|
||||||
import ShlinkApiClient from '../../../src/utils/services/ShlinkApiClient';
|
import ShlinkApiClient from '../../../src/utils/services/ShlinkApiClient';
|
||||||
|
|
||||||
describe('ShlinkApiClient', () => {
|
describe('ShlinkApiClient', () => {
|
||||||
|
@ -35,23 +33,21 @@ describe('ShlinkApiClient', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('removes all empty options', async () => {
|
it('removes all empty options', async () => {
|
||||||
const axiosSpy = sinon.spy(createAxiosMock({ data: shortUrl }));
|
const axiosSpy = jest.fn(createAxiosMock({ data: shortUrl }));
|
||||||
const { createShortUrl } = new ShlinkApiClient(axiosSpy);
|
const { createShortUrl } = new ShlinkApiClient(axiosSpy);
|
||||||
|
|
||||||
await createShortUrl(
|
await createShortUrl(
|
||||||
{ foo: 'bar', empty: undefined, anotherEmpty: null }
|
{ foo: 'bar', empty: undefined, anotherEmpty: null }
|
||||||
);
|
);
|
||||||
const lastAxiosCall = last(axiosSpy.getCalls());
|
|
||||||
const axiosArgs = head(lastAxiosCall.args);
|
|
||||||
|
|
||||||
expect(axiosArgs.data).toEqual({ foo: 'bar' });
|
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({ data: { foo: 'bar' } }));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getShortUrlVisits', () => {
|
describe('getShortUrlVisits', () => {
|
||||||
it('properly returns short URL visits', async () => {
|
it('properly returns short URL visits', async () => {
|
||||||
const expectedVisits = [ 'foo', 'bar' ];
|
const expectedVisits = [ 'foo', 'bar' ];
|
||||||
const axiosSpy = sinon.spy(createAxiosMock({
|
const axiosSpy = jest.fn(createAxiosMock({
|
||||||
data: {
|
data: {
|
||||||
visits: {
|
visits: {
|
||||||
data: expectedVisits,
|
data: expectedVisits,
|
||||||
|
@ -61,55 +57,55 @@ describe('ShlinkApiClient', () => {
|
||||||
const { getShortUrlVisits } = new ShlinkApiClient(axiosSpy);
|
const { getShortUrlVisits } = new ShlinkApiClient(axiosSpy);
|
||||||
|
|
||||||
const actualVisits = await getShortUrlVisits('abc123', {});
|
const actualVisits = await getShortUrlVisits('abc123', {});
|
||||||
const lastAxiosCall = last(axiosSpy.getCalls());
|
|
||||||
const axiosArgs = head(lastAxiosCall.args);
|
|
||||||
|
|
||||||
expect({ data: expectedVisits }).toEqual(actualVisits);
|
expect({ data: expectedVisits }).toEqual(actualVisits);
|
||||||
expect(axiosArgs.url).toContain('/short-urls/abc123/visits');
|
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||||
expect(axiosArgs.method).toEqual('GET');
|
url: '/short-urls/abc123/visits',
|
||||||
|
method: 'GET',
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getShortUrl', () => {
|
describe('getShortUrl', () => {
|
||||||
it('properly returns short URL', async () => {
|
it('properly returns short URL', async () => {
|
||||||
const expectedShortUrl = { foo: 'bar' };
|
const expectedShortUrl = { foo: 'bar' };
|
||||||
const axiosSpy = sinon.spy(createAxiosMock({
|
const axiosSpy = jest.fn(createAxiosMock({
|
||||||
data: expectedShortUrl,
|
data: expectedShortUrl,
|
||||||
}));
|
}));
|
||||||
const { getShortUrl } = new ShlinkApiClient(axiosSpy);
|
const { getShortUrl } = new ShlinkApiClient(axiosSpy);
|
||||||
|
|
||||||
const result = await getShortUrl('abc123');
|
const result = await getShortUrl('abc123');
|
||||||
const lastAxiosCall = last(axiosSpy.getCalls());
|
|
||||||
const axiosArgs = head(lastAxiosCall.args);
|
|
||||||
|
|
||||||
expect(expectedShortUrl).toEqual(result);
|
expect(expectedShortUrl).toEqual(result);
|
||||||
expect(axiosArgs.url).toContain('/short-urls/abc123');
|
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||||
expect(axiosArgs.method).toEqual('GET');
|
url: '/short-urls/abc123',
|
||||||
|
method: 'GET',
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('updateShortUrlTags', () => {
|
describe('updateShortUrlTags', () => {
|
||||||
it('properly updates short URL tags', async () => {
|
it('properly updates short URL tags', async () => {
|
||||||
const expectedTags = [ 'foo', 'bar' ];
|
const expectedTags = [ 'foo', 'bar' ];
|
||||||
const axiosSpy = sinon.spy(createAxiosMock({
|
const axiosSpy = jest.fn(createAxiosMock({
|
||||||
data: { tags: expectedTags },
|
data: { tags: expectedTags },
|
||||||
}));
|
}));
|
||||||
const { updateShortUrlTags } = new ShlinkApiClient(axiosSpy);
|
const { updateShortUrlTags } = new ShlinkApiClient(axiosSpy);
|
||||||
|
|
||||||
const result = await updateShortUrlTags('abc123', expectedTags);
|
const result = await updateShortUrlTags('abc123', expectedTags);
|
||||||
const lastAxiosCall = last(axiosSpy.getCalls());
|
|
||||||
const axiosArgs = head(lastAxiosCall.args);
|
|
||||||
|
|
||||||
expect(expectedTags).toEqual(result);
|
expect(expectedTags).toEqual(result);
|
||||||
expect(axiosArgs.url).toContain('/short-urls/abc123/tags');
|
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||||
expect(axiosArgs.method).toEqual('PUT');
|
url: '/short-urls/abc123/tags',
|
||||||
|
method: 'PUT',
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('listTags', () => {
|
describe('listTags', () => {
|
||||||
it('properly returns list of tags', async () => {
|
it('properly returns list of tags', async () => {
|
||||||
const expectedTags = [ 'foo', 'bar' ];
|
const expectedTags = [ 'foo', 'bar' ];
|
||||||
const axiosSpy = sinon.spy(createAxiosMock({
|
const axiosSpy = jest.fn(createAxiosMock({
|
||||||
data: {
|
data: {
|
||||||
tags: { data: expectedTags },
|
tags: { data: expectedTags },
|
||||||
},
|
},
|
||||||
|
@ -117,28 +113,25 @@ describe('ShlinkApiClient', () => {
|
||||||
const { listTags } = new ShlinkApiClient(axiosSpy);
|
const { listTags } = new ShlinkApiClient(axiosSpy);
|
||||||
|
|
||||||
const result = await listTags();
|
const result = await listTags();
|
||||||
const lastAxiosCall = last(axiosSpy.getCalls());
|
|
||||||
const axiosArgs = head(lastAxiosCall.args);
|
|
||||||
|
|
||||||
expect(expectedTags).toEqual(result);
|
expect(expectedTags).toEqual(result);
|
||||||
expect(axiosArgs.url).toContain('/tags');
|
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({ url: '/tags', method: 'GET' }));
|
||||||
expect(axiosArgs.method).toEqual('GET');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deleteTags', () => {
|
describe('deleteTags', () => {
|
||||||
it('properly deletes provided tags', async () => {
|
it('properly deletes provided tags', async () => {
|
||||||
const tags = [ 'foo', 'bar' ];
|
const tags = [ 'foo', 'bar' ];
|
||||||
const axiosSpy = sinon.spy(createAxiosMock({}));
|
const axiosSpy = jest.fn(createAxiosMock({}));
|
||||||
const { deleteTags } = new ShlinkApiClient(axiosSpy);
|
const { deleteTags } = new ShlinkApiClient(axiosSpy);
|
||||||
|
|
||||||
await deleteTags(tags);
|
await deleteTags(tags);
|
||||||
const lastAxiosCall = last(axiosSpy.getCalls());
|
|
||||||
const axiosArgs = head(lastAxiosCall.args);
|
|
||||||
|
|
||||||
expect(axiosArgs.url).toContain('/tags');
|
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||||
expect(axiosArgs.method).toEqual('DELETE');
|
url: '/tags',
|
||||||
expect(axiosArgs.params).toEqual({ tags });
|
method: 'DELETE',
|
||||||
|
params: { tags },
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -146,30 +139,30 @@ describe('ShlinkApiClient', () => {
|
||||||
it('properly edits provided tag', async () => {
|
it('properly edits provided tag', async () => {
|
||||||
const oldName = 'foo';
|
const oldName = 'foo';
|
||||||
const newName = 'bar';
|
const newName = 'bar';
|
||||||
const axiosSpy = sinon.spy(createAxiosMock({}));
|
const axiosSpy = jest.fn(createAxiosMock({}));
|
||||||
const { editTag } = new ShlinkApiClient(axiosSpy);
|
const { editTag } = new ShlinkApiClient(axiosSpy);
|
||||||
|
|
||||||
await editTag(oldName, newName);
|
await editTag(oldName, newName);
|
||||||
const lastAxiosCall = last(axiosSpy.getCalls());
|
|
||||||
const axiosArgs = head(lastAxiosCall.args);
|
|
||||||
|
|
||||||
expect(axiosArgs.url).toContain('/tags');
|
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||||
expect(axiosArgs.method).toEqual('PUT');
|
url: '/tags',
|
||||||
expect(axiosArgs.data).toEqual({ oldName, newName });
|
method: 'PUT',
|
||||||
|
data: { oldName, newName },
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deleteShortUrl', () => {
|
describe('deleteShortUrl', () => {
|
||||||
it('properly deletes provided short URL', async () => {
|
it('properly deletes provided short URL', async () => {
|
||||||
const axiosSpy = sinon.spy(createAxiosMock({}));
|
const axiosSpy = jest.fn(createAxiosMock({}));
|
||||||
const { deleteShortUrl } = new ShlinkApiClient(axiosSpy);
|
const { deleteShortUrl } = new ShlinkApiClient(axiosSpy);
|
||||||
|
|
||||||
await deleteShortUrl('abc123');
|
await deleteShortUrl('abc123');
|
||||||
const lastAxiosCall = last(axiosSpy.getCalls());
|
|
||||||
const axiosArgs = head(lastAxiosCall.args);
|
|
||||||
|
|
||||||
expect(axiosArgs.url).toContain('/short-urls/abc123');
|
expect(axiosSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||||
expect(axiosArgs.method).toEqual('DELETE');
|
url: '/short-urls/abc123',
|
||||||
|
method: 'DELETE',
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import Storage from '../../../src/utils/services/Storage';
|
import Storage from '../../../src/utils/services/Storage';
|
||||||
|
|
||||||
describe('Storage', () => {
|
describe('Storage', () => {
|
||||||
const localStorageMock = {
|
const localStorageMock = {
|
||||||
getItem: sinon.fake((key) => key === 'shlink.foo' ? JSON.stringify({ foo: 'bar' }) : null),
|
getItem: jest.fn((key) => key === 'shlink.foo' ? JSON.stringify({ foo: 'bar' }) : null),
|
||||||
setItem: sinon.spy(),
|
setItem: jest.fn(),
|
||||||
};
|
};
|
||||||
let storage;
|
let storage;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
localStorageMock.getItem.resetHistory();
|
localStorageMock.getItem.mockClear();
|
||||||
localStorageMock.setItem.resetHistory();
|
localStorageMock.setItem.mockReset();
|
||||||
|
|
||||||
storage = new Storage(localStorageMock);
|
storage = new Storage(localStorageMock);
|
||||||
});
|
});
|
||||||
|
@ -21,18 +20,15 @@ describe('Storage', () => {
|
||||||
|
|
||||||
storage.set('foo', value);
|
storage.set('foo', value);
|
||||||
|
|
||||||
expect(localStorageMock.setItem.callCount).toEqual(1);
|
expect(localStorageMock.setItem).toHaveBeenCalledTimes(1);
|
||||||
expect(localStorageMock.setItem.getCall(0).args).toEqual([
|
expect(localStorageMock.setItem).toHaveBeenCalledWith('shlink.foo', JSON.stringify(value));
|
||||||
'shlink.foo',
|
|
||||||
JSON.stringify(value),
|
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('get', () => {
|
describe('get', () => {
|
||||||
it('fetches item from local storage', () => {
|
it('fetches item from local storage', () => {
|
||||||
storage.get('foo');
|
storage.get('foo');
|
||||||
expect(localStorageMock.getItem.callCount).toEqual(1);
|
expect(localStorageMock.getItem).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns parsed value when requested value is found in local storage', () => {
|
it('returns parsed value when requested value is found in local storage', () => {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import L from 'leaflet';
|
import L from 'leaflet';
|
||||||
import marker2x from 'leaflet/dist/images/marker-icon-2x.png';
|
import marker2x from 'leaflet/dist/images/marker-icon-2x.png';
|
||||||
import marker from 'leaflet/dist/images/marker-icon.png';
|
import marker from 'leaflet/dist/images/marker-icon.png';
|
||||||
|
@ -14,19 +13,18 @@ import {
|
||||||
describe('utils', () => {
|
describe('utils', () => {
|
||||||
describe('stateFlagTimeout', () => {
|
describe('stateFlagTimeout', () => {
|
||||||
it('sets state and initializes timeout with provided delay', () => {
|
it('sets state and initializes timeout with provided delay', () => {
|
||||||
const setTimeout = sinon.fake((callback) => callback());
|
const setTimeout = jest.fn((callback) => callback());
|
||||||
const setState = sinon.spy();
|
const setState = jest.fn();
|
||||||
const stateFlagTimeout = stateFlagTimeoutFactory(setTimeout);
|
const stateFlagTimeout = stateFlagTimeoutFactory(setTimeout);
|
||||||
const delay = 5000;
|
const delay = 5000;
|
||||||
const expectedSetStateCalls = 2;
|
|
||||||
|
|
||||||
stateFlagTimeout(setState, 'foo', false, delay);
|
stateFlagTimeout(setState, 'foo', false, delay);
|
||||||
|
|
||||||
expect(setState.callCount).toEqual(expectedSetStateCalls);
|
expect(setState).toHaveBeenCalledTimes(2);
|
||||||
expect(setState.getCall(0).args).toEqual([{ foo: false }]);
|
expect(setState).toHaveBeenNthCalledWith(1, { foo: false });
|
||||||
expect(setState.getCall(1).args).toEqual([{ foo: true }]);
|
expect(setState).toHaveBeenNthCalledWith(2, { foo: true });
|
||||||
expect(setTimeout.callCount).toEqual(1);
|
expect(setTimeout).toHaveBeenCalledTimes(1);
|
||||||
expect(setTimeout.getCall(0).args[1]).toEqual(delay);
|
expect(setTimeout).toHaveBeenCalledWith(expect.anything(), delay);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import { Card } from 'reactstrap';
|
import { Card } from 'reactstrap';
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import createShortUrlVisits from '../../src/visits/ShortUrlVisits';
|
import createShortUrlVisits from '../../src/visits/ShortUrlVisits';
|
||||||
import MutedMessage from '../../src/utils/MuttedMessage';
|
import MutedMessage from '../../src/utils/MuttedMessage';
|
||||||
import GraphCard from '../../src/visits/GraphCard';
|
import GraphCard from '../../src/visits/GraphCard';
|
||||||
|
@ -14,7 +13,7 @@ describe('<ShortUrlVisits />', () => {
|
||||||
const processStatsFromVisits = () => (
|
const processStatsFromVisits = () => (
|
||||||
{ os: {}, browsers: {}, referrers: {}, countries: {}, cities: {}, citiesForMap: {} }
|
{ os: {}, browsers: {}, referrers: {}, countries: {}, cities: {}, citiesForMap: {} }
|
||||||
);
|
);
|
||||||
const getShortUrlVisitsMock = sinon.spy();
|
const getShortUrlVisitsMock = jest.fn();
|
||||||
const match = {
|
const match = {
|
||||||
params: { shortCode: 'abc123' },
|
params: { shortCode: 'abc123' },
|
||||||
};
|
};
|
||||||
|
@ -37,11 +36,8 @@ describe('<ShortUrlVisits />', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
getShortUrlVisitsMock.resetHistory();
|
getShortUrlVisitsMock.mockReset();
|
||||||
|
wrapper && wrapper.unmount();
|
||||||
if (wrapper) {
|
|
||||||
wrapper.unmount();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders a preloader when visits are loading', () => {
|
it('renders a preloader when visits are loading', () => {
|
||||||
|
@ -88,13 +84,12 @@ describe('<ShortUrlVisits />', () => {
|
||||||
it('reloads visits when selected dates change', () => {
|
it('reloads visits when selected dates change', () => {
|
||||||
const wrapper = createComponent({ loading: false, error: false, visits: [{}, {}, {}] });
|
const wrapper = createComponent({ loading: false, error: false, visits: [{}, {}, {}] });
|
||||||
const dateInput = wrapper.find(DateInput).first();
|
const dateInput = wrapper.find(DateInput).first();
|
||||||
const expectedGetShortUrlVisitsCalls = 4;
|
|
||||||
|
|
||||||
dateInput.simulate('change', '2016-01-01T00:00:00+01:00');
|
dateInput.simulate('change', '2016-01-01T00:00:00+01:00');
|
||||||
dateInput.simulate('change', '2016-01-02T00:00:00+01:00');
|
dateInput.simulate('change', '2016-01-02T00:00:00+01:00');
|
||||||
dateInput.simulate('change', '2016-01-03T00:00:00+01:00');
|
dateInput.simulate('change', '2016-01-03T00:00:00+01:00');
|
||||||
|
|
||||||
expect(getShortUrlVisitsMock.callCount).toEqual(expectedGetShortUrlVisitsCalls);
|
expect(getShortUrlVisitsMock).toHaveBeenCalledTimes(4);
|
||||||
expect(wrapper.state('startDate')).toEqual('2016-01-03T00:00:00+01:00');
|
expect(wrapper.state('startDate')).toEqual('2016-01-03T00:00:00+01:00');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import reducer, {
|
import reducer, {
|
||||||
getShortUrlDetail,
|
getShortUrlDetail,
|
||||||
GET_SHORT_URL_DETAIL_START,
|
GET_SHORT_URL_DETAIL_START,
|
||||||
|
@ -36,49 +35,34 @@ describe('shortUrlDetailReducer', () => {
|
||||||
|
|
||||||
describe('getShortUrlDetail', () => {
|
describe('getShortUrlDetail', () => {
|
||||||
const buildApiClientMock = (returned) => ({
|
const buildApiClientMock = (returned) => ({
|
||||||
getShortUrl: sinon.fake.returns(returned),
|
getShortUrl: jest.fn(() => returned),
|
||||||
});
|
});
|
||||||
const dispatchMock = sinon.spy();
|
const dispatchMock = jest.fn();
|
||||||
const getState = () => ({});
|
const getState = () => ({});
|
||||||
|
|
||||||
beforeEach(() => dispatchMock.resetHistory());
|
beforeEach(() => dispatchMock.mockReset());
|
||||||
|
|
||||||
it('dispatches start and error when promise is rejected', async () => {
|
it('dispatches start and error when promise is rejected', async () => {
|
||||||
const ShlinkApiClient = buildApiClientMock(Promise.reject());
|
const ShlinkApiClient = buildApiClientMock(Promise.reject());
|
||||||
const expectedDispatchCalls = 2;
|
|
||||||
|
|
||||||
await getShortUrlDetail(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
await getShortUrlDetail(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
||||||
|
|
||||||
const [ firstCallArg ] = dispatchMock.getCall(0).args;
|
expect(dispatchMock).toHaveBeenCalledTimes(2);
|
||||||
const { type: firstCallType } = firstCallArg;
|
expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_SHORT_URL_DETAIL_START });
|
||||||
|
expect(dispatchMock).toHaveBeenNthCalledWith(2, { type: GET_SHORT_URL_DETAIL_ERROR });
|
||||||
const [ secondCallArg ] = dispatchMock.getCall(1).args;
|
expect(ShlinkApiClient.getShortUrl).toHaveBeenCalledTimes(1);
|
||||||
const { type: secondCallType } = secondCallArg;
|
|
||||||
|
|
||||||
expect(dispatchMock.callCount).toEqual(expectedDispatchCalls);
|
|
||||||
expect(ShlinkApiClient.getShortUrl.callCount).toEqual(1);
|
|
||||||
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 () => {
|
it('dispatches start and success when promise is resolved', async () => {
|
||||||
const resolvedShortUrl = { longUrl: 'foo', shortCode: 'bar' };
|
const resolvedShortUrl = { longUrl: 'foo', shortCode: 'bar' };
|
||||||
const ShlinkApiClient = buildApiClientMock(Promise.resolve(resolvedShortUrl));
|
const ShlinkApiClient = buildApiClientMock(Promise.resolve(resolvedShortUrl));
|
||||||
const expectedDispatchCalls = 2;
|
|
||||||
|
|
||||||
await getShortUrlDetail(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
await getShortUrlDetail(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
||||||
|
|
||||||
const [ firstCallArg ] = dispatchMock.getCall(0).args;
|
expect(dispatchMock).toHaveBeenCalledTimes(2);
|
||||||
const { type: firstCallType } = firstCallArg;
|
expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_SHORT_URL_DETAIL_START });
|
||||||
|
expect(dispatchMock).toHaveBeenNthCalledWith(2, { type: GET_SHORT_URL_DETAIL, shortUrl: resolvedShortUrl });
|
||||||
const [ secondCallArg ] = dispatchMock.getCall(1).args;
|
expect(ShlinkApiClient.getShortUrl).toHaveBeenCalledTimes(1);
|
||||||
const { type: secondCallType, shortUrl } = secondCallArg;
|
|
||||||
|
|
||||||
expect(dispatchMock.callCount).toEqual(expectedDispatchCalls);
|
|
||||||
expect(ShlinkApiClient.getShortUrl.callCount).toEqual(1);
|
|
||||||
expect(firstCallType).toEqual(GET_SHORT_URL_DETAIL_START);
|
|
||||||
expect(secondCallType).toEqual(GET_SHORT_URL_DETAIL);
|
|
||||||
expect(shortUrl).toEqual(resolvedShortUrl);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import * as sinon from 'sinon';
|
|
||||||
import reducer, {
|
import reducer, {
|
||||||
getShortUrlVisits,
|
getShortUrlVisits,
|
||||||
cancelGetShortUrlVisits,
|
cancelGetShortUrlVisits,
|
||||||
|
@ -53,57 +52,42 @@ describe('shortUrlVisitsReducer', () => {
|
||||||
|
|
||||||
describe('getShortUrlVisits', () => {
|
describe('getShortUrlVisits', () => {
|
||||||
const buildApiClientMock = (returned) => ({
|
const buildApiClientMock = (returned) => ({
|
||||||
getShortUrlVisits: typeof returned === 'function' ? sinon.fake(returned) : sinon.fake.returns(returned),
|
getShortUrlVisits: jest.fn(typeof returned === 'function' ? returned : () => returned),
|
||||||
});
|
});
|
||||||
const dispatchMock = sinon.spy();
|
const dispatchMock = jest.fn();
|
||||||
const getState = () => ({
|
const getState = () => ({
|
||||||
shortUrlVisits: { cancelVisits: false },
|
shortUrlVisits: { cancelVisits: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => dispatchMock.resetHistory());
|
beforeEach(() => dispatchMock.mockReset());
|
||||||
|
|
||||||
it('dispatches start and error when promise is rejected', async () => {
|
it('dispatches start and error when promise is rejected', async () => {
|
||||||
const ShlinkApiClient = buildApiClientMock(Promise.reject());
|
const ShlinkApiClient = buildApiClientMock(Promise.reject());
|
||||||
const expectedDispatchCalls = 2;
|
|
||||||
|
|
||||||
await getShortUrlVisits(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
await getShortUrlVisits(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
||||||
|
|
||||||
const [ firstCallArg ] = dispatchMock.getCall(0).args;
|
expect(dispatchMock).toHaveBeenCalledTimes(2);
|
||||||
const { type: firstCallType } = firstCallArg;
|
expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_SHORT_URL_VISITS_START });
|
||||||
|
expect(dispatchMock).toHaveBeenNthCalledWith(2, { type: GET_SHORT_URL_VISITS_ERROR });
|
||||||
const [ secondCallArg ] = dispatchMock.getCall(1).args;
|
expect(ShlinkApiClient.getShortUrlVisits).toHaveBeenCalledTimes(1);
|
||||||
const { type: secondCallType } = secondCallArg;
|
|
||||||
|
|
||||||
expect(dispatchMock.callCount).toEqual(expectedDispatchCalls);
|
|
||||||
expect(ShlinkApiClient.getShortUrlVisits.callCount).toEqual(1);
|
|
||||||
expect(firstCallType).toEqual(GET_SHORT_URL_VISITS_START);
|
|
||||||
expect(secondCallType).toEqual(GET_SHORT_URL_VISITS_ERROR);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('dispatches start and success when promise is resolved', async () => {
|
it('dispatches start and success when promise is resolved', async () => {
|
||||||
const resolvedVisits = [{}, {}];
|
const visits = [{}, {}];
|
||||||
const ShlinkApiClient = buildApiClientMock(Promise.resolve({
|
const ShlinkApiClient = buildApiClientMock(Promise.resolve({
|
||||||
data: resolvedVisits,
|
data: visits,
|
||||||
pagination: {
|
pagination: {
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pagesCount: 1,
|
pagesCount: 1,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
const expectedDispatchCalls = 2;
|
|
||||||
|
|
||||||
await getShortUrlVisits(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
await getShortUrlVisits(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
||||||
|
|
||||||
const [ firstCallArg ] = dispatchMock.getCall(0).args;
|
expect(dispatchMock).toHaveBeenCalledTimes(2);
|
||||||
const { type: firstCallType } = firstCallArg;
|
expect(dispatchMock).toHaveBeenNthCalledWith(1, { type: GET_SHORT_URL_VISITS_START });
|
||||||
|
expect(dispatchMock).toHaveBeenNthCalledWith(2, { type: GET_SHORT_URL_VISITS, visits });
|
||||||
const [ secondCallArg ] = dispatchMock.getCall(1).args;
|
expect(ShlinkApiClient.getShortUrlVisits).toHaveBeenCalledTimes(1);
|
||||||
const { type: secondCallType, visits } = secondCallArg;
|
|
||||||
|
|
||||||
expect(dispatchMock.callCount).toEqual(expectedDispatchCalls);
|
|
||||||
expect(ShlinkApiClient.getShortUrlVisits.callCount).toEqual(1);
|
|
||||||
expect(firstCallType).toEqual(GET_SHORT_URL_VISITS_START);
|
|
||||||
expect(secondCallType).toEqual(GET_SHORT_URL_VISITS);
|
|
||||||
expect(visits).toEqual(resolvedVisits);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('performs multiple API requests when response contains more pages', async () => {
|
it('performs multiple API requests when response contains more pages', async () => {
|
||||||
|
@ -119,11 +103,10 @@ describe('shortUrlVisitsReducer', () => {
|
||||||
|
|
||||||
await getShortUrlVisits(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
await getShortUrlVisits(() => ShlinkApiClient)('abc123')(dispatchMock, getState);
|
||||||
|
|
||||||
const [ secondCallArg ] = dispatchMock.getCall(1).args;
|
expect(ShlinkApiClient.getShortUrlVisits).toHaveBeenCalledTimes(expectedRequests);
|
||||||
const { visits } = secondCallArg;
|
expect(dispatchMock).toHaveBeenNthCalledWith(2, expect.objectContaining({
|
||||||
|
visits: [{}, {}, {}, {}, {}, {}],
|
||||||
expect(ShlinkApiClient.getShortUrlVisits.callCount).toEqual(expectedRequests);
|
}));
|
||||||
expect(visits).toEqual([{}, {}, {}, {}, {}, {}]);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue