Files
superset2/superset/assets/spec/javascripts/dashboard/components/gridComponents/Markdown_spec.jsx
Christine Chambers 9029701f24 [refactor] Migrate from Mocha+Chai to Jest (#6079)
* [refactor] Migrate from Mocha+Chai to Jest

This change migrates all the existing unit tests
- to Jest's global expect and matchers from chai's imported expect, asserts and matchers.
- to Jest's describe/test from mocha's describe/it

The majority of the mechanical changes to tests are achieved through running jest-codemods. The only two note-worthy manual tweaks:
1. Setting a testURL of http://localhost in jest config and adjusting a few tests to leverage this value instead of relying on about:blank.
2. Re-enabling ExploreChartPanel_spec which was previously commented out as we cannot have empty tests with nothing in it with Jest. :)

This change also removes dependencies to Mocha and Chai.

* Remove the test:one command as it now does the same thing as test.

* Fixing lint errors. The diff looks large but is large done through `yarn run lint --fix`

The only noteworthy change is the one in eslintrc for tests. The env has been updated from mocha to jest.

* Adding eslint-plugin-jest and further modify tests.

- One small fix in sqllab's Timer Spec for a test that is not using the spy it created for testing.
- Deletion of a duplicated test caught by eslint-plugin-jest.

* - Make istanbul coverage work with Jest.

- Remove dependency on stand-alone istanbul and babel-istanbul as they're built-into jest. Yes!

* Attempt to fix dynamic imports in tests.

* run sequentially and log heap usage

* - tweaking maxworkers for travis and specifying coverageDirectory for codecov

- remove dynamic import in shim.js now that it is set in babelrc for tests only.
2018-10-15 13:10:18 -07:00

154 lines
5.9 KiB
JavaScript

import { Provider } from 'react-redux';
import React from 'react';
import { mount } from 'enzyme';
import sinon from 'sinon';
import AceEditor from 'react-ace';
import ReactMarkdown from 'react-markdown';
import Markdown from '../../../../../src/dashboard/components/gridComponents/Markdown';
import MarkdownModeDropdown from '../../../../../src/dashboard/components/menu/MarkdownModeDropdown';
import DeleteComponentButton from '../../../../../src/dashboard/components/DeleteComponentButton';
import DragDroppable from '../../../../../src/dashboard/components/dnd/DragDroppable';
import WithPopoverMenu from '../../../../../src/dashboard/components/menu/WithPopoverMenu';
import ResizableContainer from '../../../../../src/dashboard/components/resizable/ResizableContainer';
import { mockStore } from '../../fixtures/mockStore';
import { dashboardLayout as mockLayout } from '../../fixtures/mockDashboardLayout';
import WithDragDropContext from '../../helpers/WithDragDropContext';
describe('Markdown', () => {
const props = {
id: 'id',
parentId: 'parentId',
component: mockLayout.present.MARKDOWN_ID,
depth: 2,
parentComponent: mockLayout.present.ROW_ID,
index: 0,
editMode: false,
availableColumnCount: 12,
columnWidth: 50,
onResizeStart() {},
onResize() {},
onResizeStop() {},
handleComponentDrop() {},
updateComponents() {},
deleteComponent() {},
};
function setup(overrideProps) {
// We have to wrap provide DragDropContext for the underlying DragDroppable
// otherwise we cannot assert on DragDroppable children
const wrapper = mount(
<Provider store={mockStore}>
<WithDragDropContext>
<Markdown {...props} {...overrideProps} />
</WithDragDropContext>
</Provider>,
);
return wrapper;
}
it('should render a DragDroppable', () => {
const wrapper = setup();
expect(wrapper.find(DragDroppable)).toHaveLength(1);
});
it('should render a WithPopoverMenu', () => {
const wrapper = setup();
expect(wrapper.find(WithPopoverMenu)).toHaveLength(1);
});
it('should render a ResizableContainer', () => {
const wrapper = setup();
expect(wrapper.find(ResizableContainer)).toHaveLength(1);
});
it('should only have an adjustableWidth if its parent is a Row', () => {
let wrapper = setup();
expect(wrapper.find(ResizableContainer).prop('adjustableWidth')).toBe(true);
wrapper = setup({ ...props, parentComponent: mockLayout.present.CHART_ID });
expect(wrapper.find(ResizableContainer).prop('adjustableWidth')).toBe(
false,
);
});
it('should pass correct props to ResizableContainer', () => {
const wrapper = setup();
const resizableProps = wrapper.find(ResizableContainer).props();
expect(resizableProps.widthStep).toBe(props.columnWidth);
expect(resizableProps.widthMultiple).toBe(props.component.meta.width);
expect(resizableProps.heightMultiple).toBe(props.component.meta.height);
expect(resizableProps.maxWidthMultiple).toBe(
props.component.meta.width + props.availableColumnCount,
);
});
it('should render an Markdown when NOT focused', () => {
const wrapper = setup();
expect(wrapper.find(AceEditor)).toHaveLength(0);
expect(wrapper.find(ReactMarkdown)).toHaveLength(1);
});
it('should render an AceEditor when focused and editMode=true and editorMode=edit', () => {
const wrapper = setup({ editMode: true });
expect(wrapper.find(AceEditor)).toHaveLength(0);
expect(wrapper.find(ReactMarkdown)).toHaveLength(1);
wrapper.find(WithPopoverMenu).simulate('click'); // focus + edit
expect(wrapper.find(AceEditor)).toHaveLength(1);
expect(wrapper.find(ReactMarkdown)).toHaveLength(0);
});
it('should render a ReactMarkdown when focused and editMode=true and editorMode=preview', () => {
const wrapper = setup({ editMode: true });
wrapper.find(WithPopoverMenu).simulate('click'); // focus + edit
expect(wrapper.find(AceEditor)).toHaveLength(1);
expect(wrapper.find(ReactMarkdown)).toHaveLength(0);
// we can't call setState on Markdown bc it's not the root component, so call
// the mode dropdown onchange instead
const dropdown = wrapper.find(MarkdownModeDropdown);
dropdown.prop('onChange')('preview');
wrapper.update();
expect(wrapper.find(ReactMarkdown)).toHaveLength(1);
expect(wrapper.find(AceEditor)).toHaveLength(0);
});
it('should call updateComponents when editMode changes from edit => preview, and there are markdownSource changes', () => {
const updateComponents = sinon.spy();
const wrapper = setup({ editMode: true, updateComponents });
wrapper.find(WithPopoverMenu).simulate('click'); // focus + edit
// we can't call setState on Markdown bc it's not the root component, so call
// the mode dropdown onchange instead
const dropdown = wrapper.find(MarkdownModeDropdown);
dropdown.prop('onChange')('preview');
expect(updateComponents.callCount).toBe(0);
dropdown.prop('onChange')('edit');
// because we can't call setState on Markdown, change it through the editor
// then go back to preview mode to invoke updateComponents
const editor = wrapper.find(AceEditor);
editor.prop('onChange')('new markdown!');
dropdown.prop('onChange')('preview');
expect(updateComponents.callCount).toBe(1);
});
it('should render a DeleteComponentButton when focused in editMode', () => {
const wrapper = setup({ editMode: true });
wrapper.find(WithPopoverMenu).simulate('click'); // focus
expect(wrapper.find(DeleteComponentButton)).toHaveLength(1);
});
it('should call deleteComponent when deleted', () => {
const deleteComponent = sinon.spy();
const wrapper = setup({ editMode: true, deleteComponent });
wrapper.find(WithPopoverMenu).simulate('click'); // focus
wrapper.find(DeleteComponentButton).simulate('click');
expect(deleteComponent.callCount).toBe(1);
});
});