From e875e055386bad723fdc933d795583873084052f Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Thu, 31 Mar 2022 20:18:05 +0200 Subject: [PATCH] Replaced unmaintained dependency --- package-lock.json | 162 ++++++++++++++++-- package.json | 4 +- shlink-web-client.d.ts | 7 - src/common/services/ReportExporter.ts | 9 +- src/common/services/provideServices.ts | 2 +- src/servers/services/ServersExporter.ts | 6 +- src/servers/services/ServersImporter.ts | 8 +- src/servers/services/provideServices.ts | 6 +- src/utils/helpers/csvjson.ts | 12 ++ src/utils/services/provideServices.ts | 4 + test/common/services/ReportExporter.test.ts | 15 +- test/servers/services/ServersExporter.test.ts | 5 +- test/servers/services/ServersImporter.test.ts | 14 +- 13 files changed, 189 insertions(+), 65 deletions(-) create mode 100644 src/utils/helpers/csvjson.ts diff --git a/package-lock.json b/package-lock.json index 0d6b632c..10c0bc09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,9 +19,10 @@ "chart.js": "^3.7.1", "classnames": "^2.3.1", "compare-versions": "^4.1.3", - "csvjson": "^5.1.0", + "csvtojson": "^2.0.10", "date-fns": "^2.28.0", "event-source-polyfill": "^1.0.25", + "json2csv": "^5.0.7", "leaflet": "^1.7.1", "qs": "^6.9.6", "ramda": "^0.27.2", @@ -57,6 +58,7 @@ "@types/classnames": "^2.3.1", "@types/enzyme": "^3.10.11", "@types/jest": "^27.4.1", + "@types/json2csv": "^5.0.3", "@types/leaflet": "^1.7.9", "@types/qs": "^6.9.7", "@types/ramda": "0.27.38", @@ -4754,6 +4756,15 @@ "integrity": "sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A==", "dev": true }, + "node_modules/@types/json2csv": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/json2csv/-/json2csv-5.0.3.tgz", + "integrity": "sha512-ZJEv6SzhPhgpBpxZU4n/TZekbZqI4EcyXXRwms1lAITG2kIAtj85PfNYafUOY1zy8bWs5ujaub0GU4copaA0sw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -6843,8 +6854,7 @@ "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "node_modules/body-parser": { "version": "1.19.0", @@ -8101,10 +8111,32 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz", "integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==" }, - "node_modules/csvjson": { - "version": "5.1.0", - "resolved": "https://registry.yarnpkg.com/csvjson/-/csvjson-5.1.0.tgz", - "integrity": "sha1-8FVmCCTr+0TcCJ2QEmf9xdnoQUo=" + "node_modules/csvtojson": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/csvtojson/-/csvtojson-2.0.10.tgz", + "integrity": "sha512-lUWFxGKyhraKCW8Qghz6Z0f2l/PqB1W3AO0HKJzGIQ5JRSlR651ekJDiGJbBT4sRNNv5ddnSGVEnsxP9XRCVpQ==", + "dependencies": { + "bluebird": "^3.5.1", + "lodash": "^4.17.3", + "strip-bom": "^2.0.0" + }, + "bin": { + "csvtojson": "bin/csvtojson" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/csvtojson/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -12942,6 +12974,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -15622,6 +15659,31 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "node_modules/json2csv": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.7.tgz", + "integrity": "sha512-YRZbUnyaJZLZUJSRi2G/MqahCyRv9n/ds+4oIetjDF3jWQA7AG7iSeKTiZiCNqtMZM7HDyt0e/W6lEnoGEmMGA==", + "dependencies": { + "commander": "^6.1.0", + "jsonparse": "^1.3.1", + "lodash.get": "^4.4.2" + }, + "bin": { + "json2csv": "bin/json2csv.js" + }, + "engines": { + "node": ">= 10", + "npm": ">= 6.13.0" + } + }, + "node_modules/json2csv/node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -15637,6 +15699,14 @@ "node": ">=6" } }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "engines": [ + "node >= 0.2.0" + ] + }, "node_modules/jsonpointer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.0.tgz", @@ -15777,8 +15847,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -15804,6 +15873,11 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, "node_modules/lodash.groupby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", @@ -30221,6 +30295,15 @@ "integrity": "sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A==", "dev": true }, + "@types/json2csv": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/json2csv/-/json2csv-5.0.3.tgz", + "integrity": "sha512-ZJEv6SzhPhgpBpxZU4n/TZekbZqI4EcyXXRwms1lAITG2kIAtj85PfNYafUOY1zy8bWs5ujaub0GU4copaA0sw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -31855,8 +31938,7 @@ "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "body-parser": { "version": "1.19.0", @@ -32853,10 +32935,25 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz", "integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==" }, - "csvjson": { - "version": "5.1.0", - "resolved": "https://registry.yarnpkg.com/csvjson/-/csvjson-5.1.0.tgz", - "integrity": "sha1-8FVmCCTr+0TcCJ2QEmf9xdnoQUo=" + "csvtojson": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/csvtojson/-/csvtojson-2.0.10.tgz", + "integrity": "sha512-lUWFxGKyhraKCW8Qghz6Z0f2l/PqB1W3AO0HKJzGIQ5JRSlR651ekJDiGJbBT4sRNNv5ddnSGVEnsxP9XRCVpQ==", + "requires": { + "bluebird": "^3.5.1", + "lodash": "^4.17.3", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } + } + } }, "damerau-levenshtein": { "version": "1.0.8", @@ -36568,6 +36665,11 @@ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -38514,6 +38616,23 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json2csv": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.7.tgz", + "integrity": "sha512-YRZbUnyaJZLZUJSRi2G/MqahCyRv9n/ds+4oIetjDF3jWQA7AG7iSeKTiZiCNqtMZM7HDyt0e/W6lEnoGEmMGA==", + "requires": { + "commander": "^6.1.0", + "jsonparse": "^1.3.1", + "lodash.get": "^4.4.2" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==" + } + } + }, "json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -38523,6 +38642,11 @@ "minimist": "^1.2.5" } }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + }, "jsonpointer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.0.tgz", @@ -38633,8 +38757,7 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.debounce": { "version": "4.0.8", @@ -38660,6 +38783,11 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, "lodash.groupby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz", diff --git a/package.json b/package.json index 9655a4a9..d52a4f3f 100644 --- a/package.json +++ b/package.json @@ -35,9 +35,10 @@ "chart.js": "^3.7.1", "classnames": "^2.3.1", "compare-versions": "^4.1.3", - "csvjson": "^5.1.0", + "csvtojson": "^2.0.10", "date-fns": "^2.28.0", "event-source-polyfill": "^1.0.25", + "json2csv": "^5.0.7", "leaflet": "^1.7.1", "qs": "^6.9.6", "ramda": "^0.27.2", @@ -73,6 +74,7 @@ "@types/classnames": "^2.3.1", "@types/enzyme": "^3.10.11", "@types/jest": "^27.4.1", + "@types/json2csv": "^5.0.3", "@types/leaflet": "^1.7.9", "@types/qs": "^6.9.7", "@types/ramda": "0.27.38", diff --git a/shlink-web-client.d.ts b/shlink-web-client.d.ts index a1713f06..1a746c6e 100644 --- a/shlink-web-client.d.ts +++ b/shlink-web-client.d.ts @@ -7,11 +7,4 @@ declare module 'event-source-polyfill' { } } -declare module 'csvjson' { - export declare class CsvJson { - public toObject(content: string): T[]; - public toCSV(data: T[], options: { headers: 'full' | 'none' | 'relative' | 'key'; wrap?: true }): string; - } -} - declare module '*.png' diff --git a/src/common/services/ReportExporter.ts b/src/common/services/ReportExporter.ts index a80cdded..8976e9d9 100644 --- a/src/common/services/ReportExporter.ts +++ b/src/common/services/ReportExporter.ts @@ -1,13 +1,10 @@ -import { CsvJson } from 'csvjson'; import { NormalizedVisit } from '../../visits/types'; import { ExportableShortUrl } from '../../short-urls/data'; import { saveCsv } from '../../utils/helpers/files'; +import { JsonToCsv } from '../../utils/helpers/csvjson'; export class ReportExporter { - public constructor( - private readonly window: Window, - private readonly csvjson: CsvJson, - ) {} + public constructor(private readonly window: Window, private readonly jsonToCsv: JsonToCsv) {} public readonly exportVisits = (filename: string, visits: NormalizedVisit[]) => { if (!visits.length) { @@ -26,7 +23,7 @@ export class ReportExporter { }; private readonly exportCsv = (filename: string, rows: object[]) => { - const csv = this.csvjson.toCSV(rows, { headers: 'key', wrap: true }); + const csv = this.jsonToCsv(rows); saveCsv(this.window, csv, filename); }; diff --git a/src/common/services/provideServices.ts b/src/common/services/provideServices.ts index 73f230a4..687b9d26 100644 --- a/src/common/services/provideServices.ts +++ b/src/common/services/provideServices.ts @@ -20,7 +20,7 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => { bottle.constant('axios', axios); bottle.service('ImageDownloader', ImageDownloader, 'axios', 'window'); - bottle.service('ReportExporter', ReportExporter, 'window', 'csvjson'); + bottle.service('ReportExporter', ReportExporter, 'window', 'jsonToCsv'); // Components bottle.serviceFactory('ScrollToTop', ScrollToTop); diff --git a/src/servers/services/ServersExporter.ts b/src/servers/services/ServersExporter.ts index 08874cff..54e2ccf7 100644 --- a/src/servers/services/ServersExporter.ts +++ b/src/servers/services/ServersExporter.ts @@ -1,8 +1,8 @@ import { values } from 'ramda'; -import { CsvJson } from 'csvjson'; import LocalStorage from '../../utils/services/LocalStorage'; import { ServersMap, serverWithIdToServerData } from '../data'; import { saveCsv } from '../../utils/helpers/files'; +import { JsonToCsv } from '../../utils/helpers/csvjson'; const SERVERS_FILENAME = 'shlink-servers.csv'; @@ -10,14 +10,14 @@ export default class ServersExporter { public constructor( private readonly storage: LocalStorage, private readonly window: Window, - private readonly csvjson: CsvJson, + private readonly jsonToCsv: JsonToCsv, ) {} public readonly exportServers = async () => { const servers = values(this.storage.get('servers') ?? {}).map(serverWithIdToServerData); try { - const csv = this.csvjson.toCSV(servers, { headers: 'key' }); + const csv = this.jsonToCsv(servers); saveCsv(this.window, csv, SERVERS_FILENAME); } catch (e) { diff --git a/src/servers/services/ServersImporter.ts b/src/servers/services/ServersImporter.ts index 256c028a..8fb560b7 100644 --- a/src/servers/services/ServersImporter.ts +++ b/src/servers/services/ServersImporter.ts @@ -1,5 +1,5 @@ -import { CsvJson } from 'csvjson'; import { ServerData } from '../data'; +import { CsvToJson } from '../../utils/helpers/csvjson'; const validateServer = (server: any): server is ServerData => typeof server.url === 'string' && typeof server.apiKey === 'string' && typeof server.name === 'string'; @@ -8,7 +8,7 @@ const validateServers = (servers: any): servers is ServerData[] => Array.isArray(servers) && servers.every(validateServer); export class ServersImporter { - public constructor(private readonly csvJson: CsvJson, private readonly fileReaderFactory: () => FileReader) {} + public constructor(private readonly csvToJson: CsvToJson, private readonly fileReaderFactory: () => FileReader) {} public readonly importServersFromFile = async (file?: File | null): Promise => { if (!file) { @@ -18,11 +18,11 @@ export class ServersImporter { const reader = this.fileReaderFactory(); return new Promise((resolve, reject) => { - reader.addEventListener('loadend', (e: ProgressEvent) => { + reader.addEventListener('loadend', async (e: ProgressEvent) => { try { // TODO Read as stream, otherwise, if the file is too big, this will block the browser tab const content = e.target?.result?.toString() ?? ''; - const servers = this.csvJson.toObject(content); + const servers = await this.csvToJson(content); if (!validateServers(servers)) { throw new Error('Provided file does not have the right format.'); diff --git a/src/servers/services/provideServices.ts b/src/servers/services/provideServices.ts index 422708dd..a4cbd9db 100644 --- a/src/servers/services/provideServices.ts +++ b/src/servers/services/provideServices.ts @@ -1,4 +1,3 @@ -import csvjson from 'csvjson'; import Bottle from 'bottlejs'; import CreateServer from '../CreateServer'; import ServersDropdown from '../ServersDropdown'; @@ -69,10 +68,9 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => { )); // Services - bottle.constant('csvjson', csvjson); bottle.constant('fileReaderFactory', () => new FileReader()); - bottle.service('ServersImporter', ServersImporter, 'csvjson', 'fileReaderFactory'); - bottle.service('ServersExporter', ServersExporter, 'Storage', 'window', 'csvjson'); + bottle.service('ServersImporter', ServersImporter, 'csvToJson', 'fileReaderFactory'); + bottle.service('ServersExporter', ServersExporter, 'Storage', 'window', 'jsonToCsv'); // Actions bottle.serviceFactory('selectServer', selectServer, 'buildShlinkApiClient', 'loadMercureInfo'); diff --git a/src/utils/helpers/csvjson.ts b/src/utils/helpers/csvjson.ts new file mode 100644 index 00000000..8d4f8a6d --- /dev/null +++ b/src/utils/helpers/csvjson.ts @@ -0,0 +1,12 @@ +import csv from 'csvtojson'; +import { parse } from 'json2csv'; + +export const csvToJson = (csvContent: string) => new Promise((resolve) => { + csv().fromString(csvContent).then(resolve); +}); + +export type CsvToJson = typeof csvToJson; + +export const jsonToCsv = (data: T[]): string => parse(data); + +export type JsonToCsv = typeof jsonToCsv; diff --git a/src/utils/services/provideServices.ts b/src/utils/services/provideServices.ts index e0788915..f9fdce0e 100644 --- a/src/utils/services/provideServices.ts +++ b/src/utils/services/provideServices.ts @@ -2,12 +2,16 @@ import Bottle from 'bottlejs'; import { useStateFlagTimeout } from '../helpers/hooks'; import LocalStorage from './LocalStorage'; import ColorGenerator from './ColorGenerator'; +import { csvToJson, jsonToCsv } from '../helpers/csvjson'; const provideServices = (bottle: Bottle) => { bottle.constant('localStorage', (global as any).localStorage); bottle.service('Storage', LocalStorage, 'localStorage'); bottle.service('ColorGenerator', ColorGenerator, 'Storage'); + bottle.constant('csvToJson', csvToJson); + bottle.constant('jsonToCsv', jsonToCsv); + bottle.constant('setTimeout', global.setTimeout); bottle.constant('clearTimeout', global.clearTimeout); bottle.serviceFactory('useStateFlagTimeout', useStateFlagTimeout, 'setTimeout', 'clearTimeout'); diff --git a/test/common/services/ReportExporter.test.ts b/test/common/services/ReportExporter.test.ts index 7c530175..5fd5f941 100644 --- a/test/common/services/ReportExporter.test.ts +++ b/test/common/services/ReportExporter.test.ts @@ -1,13 +1,10 @@ -import { Mock } from 'ts-mockery'; -import { CsvJson } from 'csvjson'; import { ReportExporter } from '../../../src/common/services/ReportExporter'; import { NormalizedVisit } from '../../../src/visits/types'; import { windowMock } from '../../mocks/WindowMock'; import { ExportableShortUrl } from '../../../src/short-urls/data'; describe('ReportExporter', () => { - const toCSV = jest.fn(); - const csvToJsonMock = Mock.of({ toCSV }); + const jsonToCsv = jest.fn(); let exporter: ReportExporter; beforeEach(jest.clearAllMocks); @@ -15,7 +12,7 @@ describe('ReportExporter', () => { (global as any).Blob = class Blob {}; (global as any).URL = { createObjectURL: () => '' }; - exporter = new ReportExporter(windowMock, csvToJsonMock); + exporter = new ReportExporter(windowMock, jsonToCsv); }); describe('exportVisits', () => { @@ -36,13 +33,13 @@ describe('ReportExporter', () => { exporter.exportVisits('my_visits.csv', visits); - expect(toCSV).toHaveBeenCalledWith(visits, { headers: 'key', wrap: true }); + expect(jsonToCsv).toHaveBeenCalledWith(visits); }); it('skips execution when list of visits is empty', () => { exporter.exportVisits('my_visits.csv', []); - expect(toCSV).not.toHaveBeenCalled(); + expect(jsonToCsv).not.toHaveBeenCalled(); }); }); @@ -61,13 +58,13 @@ describe('ReportExporter', () => { exporter.exportShortUrls(shortUrls); - expect(toCSV).toHaveBeenCalledWith(shortUrls, { headers: 'key', wrap: true }); + expect(jsonToCsv).toHaveBeenCalledWith(shortUrls); }); it('skips execution when list of visits is empty', () => { exporter.exportShortUrls([]); - expect(toCSV).not.toHaveBeenCalled(); + expect(jsonToCsv).not.toHaveBeenCalled(); }); }); }); diff --git a/test/servers/services/ServersExporter.test.ts b/test/servers/services/ServersExporter.test.ts index e5d250d5..ffe7596a 100644 --- a/test/servers/services/ServersExporter.test.ts +++ b/test/servers/services/ServersExporter.test.ts @@ -1,5 +1,4 @@ import { Mock } from 'ts-mockery'; -import { CsvJson } from 'csvjson'; import ServersExporter from '../../../src/servers/services/ServersExporter'; import LocalStorage from '../../../src/utils/services/LocalStorage'; import { appendChild, removeChild, windowMock } from '../../mocks/WindowMock'; @@ -22,9 +21,7 @@ describe('ServersExporter', () => { const erroneousToCsv = jest.fn(() => { throw new Error(''); }); - const createCsvjsonMock = (throwError = false) => Mock.of({ - toCSV: throwError ? erroneousToCsv : jest.fn(() => ''), - }); + const createCsvjsonMock = (throwError = false) => (throwError ? erroneousToCsv : jest.fn(() => '')); beforeEach(jest.clearAllMocks); diff --git a/test/servers/services/ServersImporter.test.ts b/test/servers/services/ServersImporter.test.ts index 4d5e7f1d..dee01be0 100644 --- a/test/servers/services/ServersImporter.test.ts +++ b/test/servers/services/ServersImporter.test.ts @@ -1,12 +1,10 @@ import { Mock } from 'ts-mockery'; -import { CsvJson } from 'csvjson'; import { ServersImporter } from '../../../src/servers/services/ServersImporter'; import { RegularServer } from '../../../src/servers/data'; describe('ServersImporter', () => { const servers: RegularServer[] = [Mock.all(), Mock.all()]; - const toObject = jest.fn().mockReturnValue(servers); - const csvjsonMock = Mock.of({ toObject }); + const csvjsonMock = jest.fn().mockResolvedValue(servers); const readAsText = jest.fn(); const fileReaderMock = Mock.of({ readAsText, @@ -28,9 +26,7 @@ describe('ServersImporter', () => { it('rejects with error if parsing the file fails', async () => { const expectedError = new Error('Error parsing file'); - toObject.mockImplementation(() => { - throw expectedError; - }); + csvjsonMock.mockRejectedValue(expectedError); await expect(importer.importServersFromFile(Mock.of({ type: 'text/html' }))).rejects.toEqual(expectedError); }); @@ -59,7 +55,7 @@ describe('ServersImporter', () => { ], ], ])('rejects with error if provided file does not parse to valid list of servers', async (parsedObject) => { - toObject.mockReturnValue(parsedObject); + csvjsonMock.mockResolvedValue(parsedObject); await expect(importer.importServersFromFile(Mock.of({ type: 'text/html' }))).rejects.toEqual( new Error('Provided file does not have the right format.'), @@ -80,13 +76,13 @@ describe('ServersImporter', () => { }, ]; - toObject.mockReturnValue(expectedServers); + csvjsonMock.mockResolvedValue(expectedServers); const result = await importer.importServersFromFile(Mock.all()); expect(result).toEqual(expectedServers); expect(readAsText).toHaveBeenCalledTimes(1); - expect(toObject).toHaveBeenCalledTimes(1); + expect(csvjsonMock).toHaveBeenCalledTimes(1); }); }); });