diff --git a/src/servers/services/ServersExporter.js b/src/servers/services/ServersExporter.js index 85235e5a..37005b1e 100644 --- a/src/servers/services/ServersExporter.js +++ b/src/servers/services/ServersExporter.js @@ -1,9 +1,7 @@ -import Storage from '../../utils/Storage'; +import serversService from './ServersService'; import { dissoc, head, keys, values } from 'ramda'; import csvjson from 'csvjson'; -const SERVERS_STORAGE_KEY = 'servers'; - const saveCsv = (window, csv) => { const { navigator, document } = window; const filename = 'shlink-servers.csv'; @@ -27,16 +25,14 @@ const saveCsv = (window, csv) => { }; export class ServersExporter { - constructor(storage, window, csvjson) { - this.storage = storage; + constructor(serversService, window, csvjson) { + this.serversService = serversService; this.window = window; this.csvjson = csvjson; } exportServers = async () => { - const servers = values(this.storage.get(SERVERS_STORAGE_KEY) || {}).map( - dissoc('id') - ); + const servers = values(this.serversService.listServers()).map(dissoc('id')); try { const csv = this.csvjson.toCSV(servers, { @@ -50,4 +46,5 @@ export class ServersExporter { }; } -export default new ServersExporter(Storage, global.window, csvjson); +const serverExporter = new ServersExporter(serversService, global.window, csvjson); +export default serverExporter; diff --git a/test/servers/services/ServersExporter.test.js b/test/servers/services/ServersExporter.test.js new file mode 100644 index 00000000..04125bb1 --- /dev/null +++ b/test/servers/services/ServersExporter.test.js @@ -0,0 +1,95 @@ +import { ServersExporter } from '../../../src/servers/services/ServersExporter'; +import sinon from 'sinon'; + +describe('ServersExporter', () => { + const createLinkMock = () => ({ + setAttribute: sinon.fake(), + click: sinon.fake(), + style: {}, + }); + const createWindowMock = (isIe10 = true) => ({ + navigator: { + msSaveBlob: isIe10 ? sinon.fake() : undefined, + }, + document: { + createElement: sinon.fake.returns(createLinkMock()), + body: { + appendChild: sinon.fake(), + removeChild: sinon.fake(), + }, + } + }); + const serversServiceMock = { + listServers: sinon.fake.returns({ + abc123: { + id: 'abc123', + name: 'foo', + }, + def456: { + id: 'def456', + name: 'bar', + }, + }), + }; + const createCsvjsonMock = (throwError = false) => ({ + toCSV: throwError ? sinon.fake.throws('') : sinon.fake.returns(''), + }); + + describe('exportServers', () => { + let originalConsole; + + beforeEach(() => { + originalConsole = global.console; + global.console = { error: sinon.fake() }; + global.Blob = function Blob() {}; + global.URL = { createObjectURL: () => '' }; + serversServiceMock.listServers.resetHistory(); + }); + afterEach(() => global.console = originalConsole); + + it('logs an error if something fails', () => { + const csvjsonMock = createCsvjsonMock(true); + const exporter = new ServersExporter( + serversServiceMock, + createWindowMock(), + csvjsonMock, + ); + + exporter.exportServers(); + + expect(global.console.error.callCount).toEqual(1); + expect(csvjsonMock.toCSV.callCount).toEqual(1); + }); + + it('makes use of msSaveBlob API when available', () => { + const windowMock = createWindowMock(); + const exporter = new ServersExporter( + serversServiceMock, + windowMock, + createCsvjsonMock(), + ); + + exporter.exportServers(); + + expect(serversServiceMock.listServers.callCount).toEqual(1); + expect(windowMock.navigator.msSaveBlob.callCount).toEqual(1); + expect(windowMock.document.createElement.callCount).toEqual(0); + }); + + it('makes use of download link API when available', () => { + const windowMock = createWindowMock(false); + const exporter = new ServersExporter( + serversServiceMock, + windowMock, + createCsvjsonMock(), + ); + + exporter.exportServers(); + + expect(serversServiceMock.listServers.callCount).toEqual(1); + expect(windowMock.document.createElement.callCount).toEqual(1); + expect(windowMock.document.body.appendChild.callCount).toEqual(1); + expect(windowMock.document.body.removeChild.callCount).toEqual(1); + }); + }); +});