blob: 2bb4272d5868b1e1f493329fe82bacf62992a5ee [file] [log] [blame]
import React from 'react';
import { shallow } from 'enzyme';
import mockConsole, { RestoreConsole } from 'jest-mock-console';
import createLoadableRenderer, {
LoadableRenderer as LoadableRendererType,
} from '@superset-ui/core/src/chart/components/createLoadableRenderer';
describe('createLoadableRenderer', () => {
function TestComponent() {
return <div className="test-component">test</div>;
}
let loadChartSuccess = jest.fn(() => Promise.resolve(TestComponent));
let render: (loaded: { Chart: React.ComponentType }) => JSX.Element;
let loading: () => JSX.Element;
let LoadableRenderer: LoadableRendererType<{}, {}>;
let restoreConsole: RestoreConsole;
beforeEach(() => {
restoreConsole = mockConsole();
loadChartSuccess = jest.fn(() => Promise.resolve(TestComponent));
render = jest.fn(loaded => {
const { Chart } = loaded;
return <Chart />;
});
loading = jest.fn(() => <div>Loading</div>);
LoadableRenderer = createLoadableRenderer({
loader: {
Chart: loadChartSuccess,
},
loading,
render,
});
});
afterEach(() => {
restoreConsole();
});
describe('returns a LoadableRenderer class', () => {
it('LoadableRenderer.preload() preloads the lazy-load components', () => {
expect(LoadableRenderer.preload).toBeInstanceOf(Function);
LoadableRenderer.preload();
expect(loadChartSuccess).toHaveBeenCalledTimes(1);
});
it('calls onRenderSuccess when succeeds', async () => {
const onRenderSuccess = jest.fn();
const onRenderFailure = jest.fn();
shallow(
<LoadableRenderer onRenderSuccess={onRenderSuccess} onRenderFailure={onRenderFailure} />,
);
expect(loadChartSuccess).toHaveBeenCalled();
jest.useRealTimers();
await new Promise(resolve => setTimeout(resolve, 10));
expect(render).toHaveBeenCalledTimes(1);
expect(onRenderSuccess).toHaveBeenCalledTimes(1);
expect(onRenderFailure).not.toHaveBeenCalled();
});
it('calls onRenderFailure when fails', () =>
new Promise(done => {
const loadChartFailure = jest.fn(() => Promise.reject(new Error('Invalid chart')));
const FailedRenderer = createLoadableRenderer({
loader: {
Chart: loadChartFailure,
},
loading,
render,
});
const onRenderSuccess = jest.fn();
const onRenderFailure = jest.fn();
shallow(
<FailedRenderer onRenderSuccess={onRenderSuccess} onRenderFailure={onRenderFailure} />,
);
expect(loadChartFailure).toHaveBeenCalledTimes(1);
setTimeout(() => {
expect(render).not.toHaveBeenCalled();
expect(onRenderSuccess).not.toHaveBeenCalled();
expect(onRenderFailure).toHaveBeenCalledTimes(1);
done();
}, 10);
}));
it('onRenderFailure is optional', () =>
new Promise(done => {
const loadChartFailure = jest.fn(() => Promise.reject(new Error('Invalid chart')));
const FailedRenderer = createLoadableRenderer({
loader: {
Chart: loadChartFailure,
},
loading,
render,
});
shallow(<FailedRenderer />);
expect(loadChartFailure).toHaveBeenCalledTimes(1);
setTimeout(() => {
expect(render).not.toHaveBeenCalled();
done();
}, 10);
}));
it('renders the lazy-load components', () =>
new Promise(done => {
const wrapper = shallow(<LoadableRenderer />);
// lazy-loaded component not rendered immediately
expect(wrapper.find(TestComponent)).toHaveLength(0);
setTimeout(() => {
// but rendered after the component is loaded.
expect(wrapper.find(TestComponent)).toHaveLength(1);
done();
}, 10);
}));
it('does not throw if loaders are empty', () => {
const NeverLoadingRenderer = createLoadableRenderer({
loader: {},
loading,
render: () => <div />,
});
expect(() => shallow(<NeverLoadingRenderer />)).not.toThrow();
});
});
});