import { shell } from 'electron'; import { shallow } from 'enzyme'; import * as React from 'react'; import * as fs from 'fs-extra'; import { AddThemeDialog } from '../../../src/renderer/components/dialog-add-theme'; import { overridePlatform, resetPlatform } from '../../utils'; import { defaultLight, LoadedFiddleTheme, } from '../../../src/renderer/themes-defaults'; import { StateMock } from '../../mocks/mocks'; jest.mock('../../../src/renderer/ipc'); jest.mock('../../../src/renderer/binary'); describe('AddThemeDialog component', () => { let store: StateMock; beforeAll(() => { // We render the buttons different depending on the // platform, so let' have a uniform platform for unit tests overridePlatform('darwin'); }); afterAll(() => { resetPlatform(); }); beforeEach(() => { ({ state: store } = (window as any).ElectronFiddle.app); }); it('renders', () => { const wrapper = shallow(); wrapper.setState({ file: '/test/file', }); expect(wrapper).toMatchSnapshot(); }); describe('createNewThemeFromMonaco()', () => { it('handles invalid input', async () => { const wrapper = shallow(); const instance: AddThemeDialog = wrapper.instance() as any; try { await instance.createNewThemeFromMonaco('', {} as LoadedFiddleTheme); } catch (err) { expect(err.message).toEqual(`Filename not found`); expect(fs.outputJSON).toHaveBeenCalledTimes(0); expect(store.setTheme).toHaveBeenCalledTimes(0); expect(shell.showItemInFolder).toHaveBeenCalledTimes(0); } }); it('handles valid input', async () => { const wrapper = shallow(); const instance: AddThemeDialog = wrapper.instance() as any; wrapper.setState({ file: '/test/file' }); (fs.outputJSON as jest.Mock).mockResolvedValue({}); await instance.createNewThemeFromMonaco('testingLight', defaultLight); expect(fs.outputJSON).toHaveBeenCalled(); const args = (fs.outputJSON as jest.Mock).mock.calls[0]; expect(args[0].includes(`.electron-fiddle`)).toBe(true); expect(args[1].name).toEqual('testingLight'); expect(args[1].common).toBeDefined(); expect(args[1].file).toBeDefined(); const themePath = '~/.electron-fiddle/themes/testingLight'; expect(store.setTheme).toHaveBeenCalledWith(themePath); expect(shell.showItemInFolder).toHaveBeenCalledWith(themePath); }); }); describe('onSubmit()', () => { it('does nothing if there is no file currently set', async () => { const wrapper = shallow(); const instance: AddThemeDialog = wrapper.instance() as any; instance.createNewThemeFromMonaco = jest.fn(); instance.onClose = jest.fn(); await instance.onSubmit(); expect(fs.readJSONSync).toHaveBeenCalledTimes(0); expect(instance.createNewThemeFromMonaco).toHaveBeenCalledTimes(0); expect(instance.onClose).toHaveBeenCalledTimes(0); }); it('loads a theme if a file is currently set', async () => { const wrapper = shallow(); const instance: AddThemeDialog = wrapper.instance() as any; wrapper.setState({ file: '/test/file' }); (fs.readJSONSync as jest.Mock).mockReturnValue(defaultLight.editor); instance.createNewThemeFromMonaco = jest.fn(); instance.onClose = jest.fn(); await instance.onSubmit(); expect(fs.readJSONSync).toHaveBeenCalledTimes(1); expect(instance.createNewThemeFromMonaco).toHaveBeenCalledTimes(1); expect(instance.onClose).toHaveBeenCalledTimes(1); }); it('shows an error dialog for a malformed theme', async () => { store.showErrorDialog = jest.fn().mockResolvedValueOnce(true); const wrapper = shallow(); const instance: AddThemeDialog = wrapper.instance() as any; wrapper.setState({ file: '/test/file' }); (fs.readJSONSync as jest.Mock).mockReturnValue({}); instance.onClose = jest.fn(); await instance.onSubmit(); expect(fs.readJSONSync).toHaveBeenCalledTimes(1); expect(store.showErrorDialog).toHaveBeenCalledWith( expect.stringMatching(/file does not match specifications/i), ); }); }); describe('onChangeFile()', () => { it('handles valid input', () => { const wrapper = shallow(); const files = ['one', 'two']; (wrapper.instance() as any).onChangeFile({ target: { files }, }); expect(wrapper.state('file')).toBe(files[0]); }); it('handles no input', () => { const wrapper = shallow(); (wrapper.instance() as any).onChangeFile({ target: { files: null }, }); expect(wrapper.state('file')).toBeUndefined(); }); }); });