Added logic to detect duplicated servers when importing a servers list

This commit is contained in:
Alejandro Celaya
2022-01-01 12:20:09 +01:00
parent 3cb066f5f5
commit 98398a048b
10 changed files with 128 additions and 73 deletions

View File

@@ -4,7 +4,7 @@ import { History } from 'history';
import createServerConstruct from '../../src/servers/CreateServer';
import { ServerForm } from '../../src/servers/helpers/ServerForm';
import { ServerWithId } from '../../src/servers/data';
import { DuplicatedServerModal } from '../../src/servers/helpers/DuplicatedServerModal';
import { DuplicatedServersModal } from '../../src/servers/helpers/DuplicatedServersModal';
describe('<CreateServer />', () => {
let wrapper: ShallowWrapper;
@@ -52,20 +52,20 @@ describe('<CreateServer />', () => {
expect(result.prop('type')).toEqual('error');
});
it('creates server data form is submitted', () => {
it('creates server data when form is submitted', () => {
const wrapper = createWrapper();
const form = wrapper.find(ServerForm);
expect(wrapper.find(DuplicatedServerModal).prop('serverData')).not.toBeDefined();
expect(wrapper.find(DuplicatedServersModal).prop('duplicatedServers')).toEqual([]);
form.simulate('submit', {});
expect(wrapper.find(DuplicatedServerModal).prop('serverData')).toEqual({});
expect(wrapper.find(DuplicatedServersModal).prop('duplicatedServers')).toEqual([{}]);
});
it('saves server and redirects on modal save', () => {
const wrapper = createWrapper();
wrapper.find(ServerForm).simulate('submit', {});
wrapper.find(DuplicatedServerModal).simulate('save');
wrapper.find(DuplicatedServersModal).simulate('save');
expect(createServerMock).toHaveBeenCalledTimes(1);
expect(push).toHaveBeenCalledTimes(1);
@@ -74,7 +74,7 @@ describe('<CreateServer />', () => {
it('goes back on modal discard', () => {
const wrapper = createWrapper();
wrapper.find(DuplicatedServerModal).simulate('discard');
wrapper.find(DuplicatedServersModal).simulate('discard');
expect(goBack).toHaveBeenCalledTimes(1);
});

View File

@@ -1,16 +1,16 @@
import { shallow, ShallowWrapper } from 'enzyme';
import { Mock } from 'ts-mockery';
import { Button } from 'reactstrap';
import { DuplicatedServerModal } from '../../../src/servers/helpers/DuplicatedServerModal';
import { DuplicatedServersModal } from '../../../src/servers/helpers/DuplicatedServersModal';
import { ServerData } from '../../../src/servers/data';
describe('<DuplicatedServerModal />', () => {
describe('<DuplicatedServersModal />', () => {
const onDiscard = jest.fn();
const onSave = jest.fn();
let wrapper: ShallowWrapper;
const createWrapper = (serverData?: ServerData) => {
const createWrapper = (duplicatedServers: ServerData[] = []) => {
wrapper = shallow(
<DuplicatedServerModal isOpen serverData={serverData} toggle={jest.fn()} onDiscard={onDiscard} onSave={onSave} />,
<DuplicatedServersModal isOpen duplicatedServers={duplicatedServers} onDiscard={onDiscard} onSave={onSave} />,
);
return wrapper;
@@ -20,14 +20,18 @@ describe('<DuplicatedServerModal />', () => {
afterEach(() => wrapper?.unmount());
it.each([
[ undefined ],
[ Mock.of<ServerData>({ url: 'url', apiKey: 'apiKey' }) ],
])('displays provided server data', (serverData) => {
const wrapper = createWrapper(serverData);
[[]],
[[ Mock.of<ServerData>({ url: 'url', apiKey: 'apiKey' }) ]],
])('displays provided server data', (duplicatedServers) => {
const wrapper = createWrapper(duplicatedServers);
const li = wrapper.find('li');
expect(li.first().find('b').html()).toEqual(`<b>${serverData?.url ?? ''}</b>`);
expect(li.last().find('b').html()).toEqual(`<b>${serverData?.apiKey ?? ''}</b>`);
if (duplicatedServers.length === 0) {
expect(li).toHaveLength(0);
} else {
expect(li.first().find('b').html()).toEqual(`<b>${duplicatedServers[0].url}</b>`);
expect(li.last().find('b').html()).toEqual(`<b>${duplicatedServers[0].apiKey}</b>`);
}
});
it('invokes onDiscard when appropriate button is clicked', () => {

View File

@@ -2,8 +2,9 @@ import { ReactNode } from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { UncontrolledTooltip } from 'reactstrap';
import { Mock } from 'ts-mockery';
import importServersBtnConstruct from '../../../src/servers/helpers/ImportServersBtn';
import ServersImporter from '../../../src/servers/services/ServersImporter';
import importServersBtnConstruct, { ImportServersBtnProps } from '../../../src/servers/helpers/ImportServersBtn';
import { ServersImporter } from '../../../src/servers/services/ServersImporter';
import { DuplicatedServersModal } from '../../../src/servers/helpers/DuplicatedServersModal';
describe('<ImportServersBtn />', () => {
let wrapper: ShallowWrapper;
@@ -12,17 +13,15 @@ describe('<ImportServersBtn />', () => {
const importServersFromFile = jest.fn().mockResolvedValue([]);
const serversImporterMock = Mock.of<ServersImporter>({ importServersFromFile });
const click = jest.fn();
const fileRef = {
current: Mock.of<HTMLInputElement>({ click }),
};
const fileRef = { current: Mock.of<HTMLInputElement>({ click }) };
const ImportServersBtn = importServersBtnConstruct(serversImporterMock);
const createWrapper = (className?: string, children?: ReactNode) => {
const createWrapper = (props: Partial<ImportServersBtnProps & { children: ReactNode }> = {}) => {
wrapper = shallow(
<ImportServersBtn
createServers={createServersMock}
className={className}
servers={{}}
{...props}
fileRef={fileRef}
children={children}
createServers={createServersMock}
onImport={onImportMock}
/>,
);
@@ -46,7 +45,7 @@ describe('<ImportServersBtn />', () => {
[ 'foo', 'foo' ],
[ 'bar', 'bar' ],
])('allows a class name to be provided', (providedClassName, expectedClassName) => {
const wrapper = createWrapper(providedClassName);
const wrapper = createWrapper({ className: providedClassName });
expect(wrapper.find('#importBtn').prop('className')).toEqual(expectedClassName);
});
@@ -56,7 +55,7 @@ describe('<ImportServersBtn />', () => {
[ 'foo', false ],
[ 'bar', false ],
])('has expected text', (children, expectToHaveDefaultText) => {
const wrapper = createWrapper(undefined, children);
const wrapper = createWrapper({ children });
if (expectToHaveDefaultText) {
expect(wrapper.find('#importBtn').html()).toContain('Import from file');
@@ -82,6 +81,16 @@ describe('<ImportServersBtn />', () => {
await file.simulate('change', { target: { files: [ '' ] } }); // eslint-disable-line @typescript-eslint/await-thenable
expect(importServersFromFile).toHaveBeenCalledTimes(1);
});
it.each([
[ 'discard' ],
[ 'save' ],
])('invokes callback in DuplicatedServersModal events', (event) => {
const wrapper = createWrapper();
wrapper.find(DuplicatedServersModal).simulate(event);
expect(createServersMock).toHaveBeenCalledTimes(1);
expect(onImportMock).toHaveBeenCalledTimes(1);
});

View File

@@ -1,6 +1,6 @@
import { Mock } from 'ts-mockery';
import { CsvJson } from 'csvjson';
import ServersImporter from '../../../src/servers/services/ServersImporter';
import { ServersImporter } from '../../../src/servers/services/ServersImporter';
import { RegularServer } from '../../../src/servers/data';
describe('ServersImporter', () => {