import { IItemRendererProps } from '@blueprintjs/select';
import { shell } from 'electron';
import { shallow } from 'enzyme';
import * as React from 'react';
import * as fs from 'fs-extra';
import {
AppearanceSettings,
filterItem,
renderItem,
} from '../../../src/renderer/components/settings-general-appearance';
import { getAvailableThemes } from '../../../src/renderer/themes';
import { FiddleTheme } from '../../../src/renderer/themes-defaults';
import { StateMock } from '../../mocks/mocks';
const mockThemes = [
{
name: 'defaultDark',
file: 'defaultDark',
},
];
const doNothingFunc = () => {
// Do Nothing
};
jest.mock('fs-extra');
jest.mock('../../../src/renderer/themes', () => ({
THEMES_PATH: '~/.electron-fiddle/themes',
getAvailableThemes: jest.fn(),
getTheme: () =>
Promise.resolve({
common: {},
}),
}));
describe('AppearanceSettings component', () => {
let store: StateMock;
beforeEach(() => {
({ state: store } = (window as any).ElectronFiddle.app);
(getAvailableThemes as jest.Mock).mockResolvedValue(mockThemes);
});
it('renders', () => {
const wrapper = shallow(
,
);
expect(wrapper).toMatchSnapshot();
});
it('renders the correct selected theme', async () => {
store.theme = 'defaultDark';
const wrapper = shallow(
,
);
await process.nextTick;
expect((wrapper.state() as any).selectedTheme.name).toBe('defaultDark');
});
it('handles a theme change', () => {
const wrapper = shallow(
,
);
const instance: AppearanceSettings = wrapper.instance() as any;
instance.handleChange({ file: 'defaultLight' } as any);
expect(store.setTheme).toHaveBeenCalledWith('defaultLight');
});
it('toggles popover toggle event', () => {
const toggleFunc = jest.fn();
const wrapper = shallow(
,
);
// Find the button
const button = wrapper.find('#open-theme-selector');
// Simulate opening the theme selector
button.simulate('click');
expect(toggleFunc).toHaveBeenCalledTimes(1);
// Simulate closing the theme selector
button.simulate('click');
expect(toggleFunc).toHaveBeenCalledTimes(2);
});
describe('openThemeFolder()', () => {
it('attempts to open the folder', async () => {
const wrapper = shallow(
,
);
const instance: AppearanceSettings = wrapper.instance() as any;
await instance.openThemeFolder();
expect(shell.showItemInFolder).toHaveBeenCalled();
});
it('handles an error', async () => {
const wrapper = shallow(
,
);
const instance: AppearanceSettings = wrapper.instance() as any;
(shell as any).showItemInFolder.mockImplementationOnce(() => {
throw new Error('Bwap');
});
expect(await instance.openThemeFolder()).toBe(false);
});
});
describe('createNewThemeFromCurrent()', () => {
it('creates a new file from the current theme', async () => {
const wrapper = shallow(
,
);
const instance: AppearanceSettings = wrapper.instance() as any;
await instance.createNewThemeFromCurrent();
expect(shell.showItemInFolder).toHaveBeenCalled();
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).toBeDefined();
expect(args[1].name === 'defaultDark').toBe(false);
expect(args[1].common).toBeDefined();
expect(args[1].file).toBeUndefined();
});
it('adds the newly created theme to the Themes dropdown', async () => {
const arr: Array = [];
(getAvailableThemes as jest.Mock).mockResolvedValue(arr);
(fs.outputJSON as jest.Mock).mockImplementation(
(_, theme: FiddleTheme) => {
arr.push(theme);
},
);
const wrapper = shallow(
,
);
expect(wrapper.state('themes')).toHaveLength(0);
const instance: AppearanceSettings = wrapper.instance() as any;
await instance.createNewThemeFromCurrent();
expect(wrapper.state('themes')).toHaveLength(1);
});
it('handles an error', async () => {
const wrapper = shallow(
,
);
const instance: AppearanceSettings = wrapper.instance() as any;
(shell as any).showItemInFolder.mockImplementationOnce(() => {
throw new Error('Bwap');
});
const result = await instance.createNewThemeFromCurrent();
expect(result).toBe(false);
});
});
describe('filterItem()', () => {
it('filters', () => {
const foo = filterItem('foo', { name: 'foo' } as any);
expect(foo).toBe(true);
const bar = filterItem('foo', { name: 'bar' } as any);
expect(bar).toBe(false);
});
});
describe('renderItem()', () => {
const mockItemProps: IItemRendererProps = {
handleClick: () => ({}),
index: 0,
modifiers: {
active: false,
disabled: false,
matchesPredicate: true,
},
query: '',
};
it('returns null for non-matching', () => {
const result = renderItem({ name: 'foo' } as any, {
...mockItemProps,
modifiers: {
...mockItemProps.modifiers,
matchesPredicate: false,
},
});
expect(result).toBe(null);
});
it('returns a MenuItem for matching', () => {
const result = renderItem({ name: 'foo' } as any, {
...mockItemProps,
});
expect(result).toMatchSnapshot();
});
});
});