From 39663ba936910b23d249169808177cbc989a666f Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 22 Aug 2020 11:20:27 +0200 Subject: [PATCH] Migrated to TS first component where some dependency was being injected --- package-lock.json | 10 ++++ package.json | 1 + src/servers/helpers/ImportServersBtn.js | 48 ------------------- src/servers/helpers/ImportServersBtn.tsx | 46 ++++++++++++++++++ src/servers/services/ServersImporter.ts | 2 +- ...sBtn.test.js => ImportServersBtn.test.tsx} | 20 ++++---- 6 files changed, 68 insertions(+), 59 deletions(-) delete mode 100644 src/servers/helpers/ImportServersBtn.js create mode 100644 src/servers/helpers/ImportServersBtn.tsx rename test/servers/helpers/{ImportServersBtn.test.js => ImportServersBtn.test.tsx} (78%) diff --git a/package-lock.json b/package-lock.json index 3c9c4b58..f1535a30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3410,6 +3410,16 @@ "@types/react-router": "*" } }, + "@types/reactstrap": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@types/reactstrap/-/reactstrap-8.5.1.tgz", + "integrity": "sha512-oEedcEGoX8EqDymsjrjzTnmaf3FuDY9qKLZMA9cH1ZkkqBc2V4i2sJ6ssXEod+GHQ5XH2r52uvbMkjEkjEZHDQ==", + "dev": true, + "requires": { + "@types/react": "*", + "popper.js": "^1.14.1" + } + }, "@types/stack-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", diff --git a/package.json b/package.json index 6d8d8aea..e84df9f7 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "@types/react-dom": "^16.9.8", "@types/react-redux": "^7.1.9", "@types/react-router-dom": "^5.1.5", + "@types/reactstrap": "^8.5.1", "adm-zip": "^0.4.13", "autoprefixer": "^9.6.3", "babel-core": "7.0.0-bridge.0", diff --git a/src/servers/helpers/ImportServersBtn.js b/src/servers/helpers/ImportServersBtn.js deleted file mode 100644 index 7bde4df7..00000000 --- a/src/servers/helpers/ImportServersBtn.js +++ /dev/null @@ -1,48 +0,0 @@ -import React, { useRef } from 'react'; -import { UncontrolledTooltip } from 'reactstrap'; -import PropTypes from 'prop-types'; - -const propTypes = { - onImport: PropTypes.func, - createServers: PropTypes.func, - fileRef: PropTypes.oneOfType([ PropTypes.object, PropTypes.node ]), -}; - -// FIXME Replace with typescript: (ServersImporter) -const ImportServersBtn = ({ importServersFromFile }) => { - const ImportServersBtnComp = ({ createServers, fileRef, onImport = () => '' }) => { - const ref = fileRef || useRef(); - const onChange = ({ target }) => - importServersFromFile(target.files[0]) - .then(createServers) - .then(onImport) - .then(() => { - // Reset input after processing file - target.value = null; - }); - - return ( - - - - You can create servers by importing a CSV file with columns name, apiKey and url. - - - - - ); - }; - - ImportServersBtnComp.propTypes = propTypes; - - return ImportServersBtnComp; -}; - -export default ImportServersBtn; diff --git a/src/servers/helpers/ImportServersBtn.tsx b/src/servers/helpers/ImportServersBtn.tsx new file mode 100644 index 00000000..e77d69d2 --- /dev/null +++ b/src/servers/helpers/ImportServersBtn.tsx @@ -0,0 +1,46 @@ +import React, { useRef, RefObject, ChangeEvent, MutableRefObject } from 'react'; +import { UncontrolledTooltip } from 'reactstrap'; +import ServersImporter from '../services/ServersImporter'; +import { Server } from '../data'; + +type Ref = RefObject | MutableRefObject; + +interface ImportServersBtnProps { + createServers: (servers: Server[]) => void; + fileRef: Ref; + onImport?: () => void; +} + +const ImportServersBtn = ({ importServersFromFile }: ServersImporter) => ( + { createServers, fileRef, onImport = () => {} }: ImportServersBtnProps, +) => { + const ref = fileRef ?? useRef(); + const onChange = async ({ target }: ChangeEvent) => + importServersFromFile(target.files?.[0]) + .then(createServers) + .then(onImport) + .then(() => { + // Reset input after processing file + (target as { value: string | null }).value = null; + }); + + return ( + + + + You can create servers by importing a CSV file with columns name, apiKey and url. + + + + + ); +}; + +export default ImportServersBtn; diff --git a/src/servers/services/ServersImporter.ts b/src/servers/services/ServersImporter.ts index d65be66b..17ab38e3 100644 --- a/src/servers/services/ServersImporter.ts +++ b/src/servers/services/ServersImporter.ts @@ -6,7 +6,7 @@ const CSV_MIME_TYPE = 'text/csv'; export default class ServersImporter { public constructor(private readonly csvjson: CsvJson, private readonly fileReaderFactory: () => FileReader) {} - public importServersFromFile = async (file?: File): Promise => { + public importServersFromFile = async (file?: File | null): Promise => { if (!file || file.type !== CSV_MIME_TYPE) { throw new Error('No file provided or file is not a CSV'); } diff --git a/test/servers/helpers/ImportServersBtn.test.js b/test/servers/helpers/ImportServersBtn.test.tsx similarity index 78% rename from test/servers/helpers/ImportServersBtn.test.js rename to test/servers/helpers/ImportServersBtn.test.tsx index fc203d28..7f373fbb 100644 --- a/test/servers/helpers/ImportServersBtn.test.js +++ b/test/servers/helpers/ImportServersBtn.test.tsx @@ -1,24 +1,24 @@ import React from 'react'; -import { shallow } from 'enzyme'; +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'; describe('', () => { - let wrapper; + let wrapper: ShallowWrapper; const onImportMock = jest.fn(); const createServersMock = jest.fn(); - const serversImporterMock = { + const serversImporterMock = Mock.of({ importServersFromFile: jest.fn().mockResolvedValue([]), - }; + }); + const click = jest.fn(); const fileRef = { - current: { click: jest.fn() }, + current: Mock.of({ click }), }; beforeEach(() => { - onImportMock.mockReset(); - createServersMock.mockReset(); - serversImporterMock.importServersFromFile.mockClear(); - fileRef.current.click.mockReset(); + jest.clearAllMocks(); const ImportServersBtn = importServersBtnConstruct(serversImporterMock); @@ -39,7 +39,7 @@ describe('', () => { btn.simulate('click'); - expect(fileRef.current.click).toHaveBeenCalledTimes(1); + expect(click).toHaveBeenCalledTimes(1); }); it('imports servers when file input changes', (done) => {