import { Mock } from 'ts-mockery'; import { CsvJson } from 'csvjson'; import ServersExporter from '../../../src/servers/services/ServersExporter'; import LocalStorage from '../../../src/utils/services/LocalStorage'; describe('ServersExporter', () => { const createLinkMock = () => ({ setAttribute: jest.fn(), click: jest.fn(), style: {}, }); const appendChild = jest.fn(); const removeChild = jest.fn(); const createWindowMock = () => Mock.of({ document: { createElement: jest.fn(() => createLinkMock()), body: { appendChild, removeChild }, }, }); const storageMock = Mock.of({ get: jest.fn(() => ({ abc123: { id: 'abc123', name: 'foo', }, def456: { id: 'def456', name: 'bar', }, })), }); const erroneousToCsv = jest.fn(() => { throw new Error(''); }); const createCsvjsonMock = (throwError = false) => Mock.of({ toCSV: throwError ? erroneousToCsv : jest.fn(() => ''), }); beforeEach(jest.clearAllMocks); describe('exportServers', () => { let originalConsole: Console; const error = jest.fn(); beforeEach(() => { originalConsole = global.console; global.console = Mock.of({ error }); (global as any).Blob = class Blob {}; // eslint-disable-line @typescript-eslint/no-extraneous-class (global as any).URL = { createObjectURL: () => '' }; }); afterEach(() => { global.console = originalConsole; jest.clearAllMocks(); }); it('logs an error if something fails', () => { const csvjsonMock = createCsvjsonMock(true); const exporter = new ServersExporter(storageMock, createWindowMock(), csvjsonMock); exporter.exportServers(); expect(error).toHaveBeenCalledTimes(1); expect(erroneousToCsv).toHaveBeenCalledTimes(1); }); it('makes use of download link API', () => { const windowMock = createWindowMock(); const exporter = new ServersExporter(storageMock, windowMock, createCsvjsonMock()); const { document: { createElement } } = windowMock; exporter.exportServers(); expect(storageMock.get).toHaveBeenCalledTimes(1); expect(createElement).toHaveBeenCalledTimes(1); expect(appendChild).toHaveBeenCalledTimes(1); expect(removeChild).toHaveBeenCalledTimes(1); }); }); });