UNPKG

d2-ui

Version:
224 lines (166 loc) 8.82 kB
import React from 'react'; import {describeWithDOM, shallow} from 'enzyme'; import DataTable from '../../src/data-table/DataTable.component'; import DataTableHeader from '../../src/data-table/DataTableHeader.component'; import DataTableContextMenu from '../../src/data-table/DataTableContextMenu.component'; import Popover from 'material-ui/Popover/Popover'; describe('DataTable component', () => { let dataTableComponent; function renderComponent(props = {}) { return shallow(<DataTable {...Object.assign({contextMenuActions: {}}, props)} />); } beforeEach(() => { dataTableComponent = renderComponent(); }); describe('initial state', () => { it('should have set the default columns', () => { expect(dataTableComponent.state('columns')).to.deep.equal(['name', 'lastUpdated']); }); it('should have a data-table row', () => { expect(dataTableComponent.hasClass('data-table')).to.be.true; }); }); describe('with headers', () => { it('should have set the passed columns', () => { const columns = ['name', 'code', 'lastUpdated']; dataTableComponent = renderComponent({columns}); expect(dataTableComponent.state('columns')).to.deep.equal(['name', 'code', 'lastUpdated']); }); it('should not set the columns if the column value is not an array of strings', () => { const columns = ['name', 'code', 'lastUpdated', {}]; dataTableComponent = renderComponent({columns}); expect(dataTableComponent.state('columns')).to.deep.equal(['name', 'lastUpdated']); }); it('should generate the headers wrap', () => { expect(dataTableComponent.find('.data-table__headers')).to.have.length(1); }); it('should generate the correct number of headers', () => { expect(dataTableComponent.find(DataTableHeader)).to.have.length(3); }); }); it('should have a property for rows that is empty', () => { expect(dataTableComponent.state().dataRows).to.be.an('array'); }); describe('with source', () => { beforeEach(() => { const dataTableSource = [ {uid: 'b1', name: 'BDC', lastUpdated: 'Tomorrow'}, {uid: 'f1', name: 'BFG', lastUpdated: 'Last year'}, {uid: 'c1', name: 'BFG', lastUpdated: 'Today'}, ]; dataTableComponent = renderComponent({rows: dataTableSource}); }); it('should have set the dataRows onto the state', () => { expect(dataTableComponent.state('dataRows')).to.have.length(3); }); it('should not set the dataRows when the received value is not iterable', () => { dataTableComponent = renderComponent({rows: {}}); expect(dataTableComponent.state('dataRows')).to.have.length(0) }); it('should generate a row wrap', () => { expect(dataTableComponent.find('.data-table__rows')).to.have.length(1); }); it('should update the source when the rows property changes', () => { dataTableComponent.setProps({rows: [{uid: 'b1', name: 'BDC', lastUpdated: 'Tomorrow'}]}); expect(dataTableComponent.state('dataRows').length).to.equal(1); }); it('should correctly render a map', () => { dataTableComponent.setProps({ rows: new Map([ ['b1', {uid: 'b1', name: 'BDC', lastUpdated: 'Tomorrow'}], ['f1', {uid: 'f1', name: 'BFG', lastUpdated: 'Last year'}], ['c1', {uid: 'c1', name: 'BFG', lastUpdated: 'Today'}], ]), }); expect(dataTableComponent.state('dataRows')).to.have.length(3); }); }); describe('interaction', () => { beforeEach(() => { const dataTableSource = [ {uid: 'b1', name: 'BDC', lastUpdated: 'Tomorrow'}, {uid: 'f1', name: 'BFG', lastUpdated: 'Last year'}, {uid: 'c1', name: 'BFG', lastUpdated: 'Today'}, ]; dataTableComponent = renderComponent({source: dataTableSource}); }); it('should show the context menu when the activeRow state is set', () => { const fakeRowSource = {name: 'My item'}; expect(dataTableComponent.find('.data-table__context-menu')).to.have.length(0); dataTableComponent.instance() .handleRowClick( {currentTarget: dataTableComponent}, fakeRowSource ); dataTableComponent.update(); const contextMenuComponent = dataTableComponent.find(DataTableContextMenu); expect(contextMenuComponent).to.have.length(1); expect(contextMenuComponent.props().target).to.deep.equal(dataTableComponent); }); it('should hide the context menu when handleRowClick is called twice with the same source', () => { const fakeRowSource = {name: 'My item'}; dataTableComponent.instance().handleRowClick({clientY: 100, clientX: 100}, fakeRowSource); dataTableComponent.update(); dataTableComponent.instance().handleRowClick({clientY: 100, clientX: 100}, fakeRowSource); dataTableComponent.update(); const contextMenuComponent = dataTableComponent.find('.data-table__context-menu'); expect(contextMenuComponent).to.have.length(0); }); it('should not render the context menu when the activeRow is undefined', () => { const fakeRowSource = {name: 'My item'}; dataTableComponent.setState({contextMenuTarget: {}, activeRow: fakeRowSource}); dataTableComponent.instance()._hideContextMenu(); dataTableComponent.update(); const contextMenuComponent = dataTableComponent.find('.data-table__context-menu'); expect(contextMenuComponent).to.have.length(0); expect(dataTableComponent.state('activeRow')).to.be.undefined; }); it('should initially not show the contextmenu', () => { expect(dataTableComponent.find('.data-table__context-menu')).to.have.length(0); }); // TODO: The Popover requires a dom element as a targetEl prop. Figure out how to test this without a DOM. xit('should hide the contextmenu when left clicking outside the contextmenu', () => { const fakeRowSource = {name: 'My item'}; dataTableComponent.instance() .handleRowClick( {currentTarget: dataTableComponent}, fakeRowSource ); dataTableComponent.update(); expect(dataTableComponent.find('.data-table__context-menu')).to.have.length(1); // onRequestClose is called when clicking outside the menu dataTableComponent.find(Popover).props().onRequestClose(); dataTableComponent.update(); expect(dataTableComponent.find('.data-table__context-menu')).to.have.length(0); }); }); describe('context menu action filtering', () => { let isContextActionAllowed; let contextMenuActions; let fakeRowSource; beforeEach(() => { fakeRowSource = {name: 'My item'}; isContextActionAllowed = sinon.stub().returns(true); contextMenuActions = { edit: () => {}, delete: () => {}, translate: () => {}, }; dataTableComponent = renderComponent({isContextActionAllowed, contextMenuActions}); }); it('should pass through when the actions are allowed', () => { // Show context menu initially dataTableComponent.setState({contextMenuTarget: {}, activeRow: fakeRowSource}); const passedContextMenuActions = dataTableComponent.find(DataTableContextMenu).props().actions; expect(Object.keys(passedContextMenuActions)).to.deep.equal(['edit', 'delete', 'translate']); }); it('should not pass actions that are not allowed', () => { isContextActionAllowed.withArgs(fakeRowSource, 'delete').returns(false); dataTableComponent = renderComponent({isContextActionAllowed, contextMenuActions}); // Show context menu initially dataTableComponent.setState({contextMenuTarget: {}, activeRow: fakeRowSource}); const passedContextMenuActions = dataTableComponent.find(DataTableContextMenu).props().actions; expect(Object.keys(passedContextMenuActions)).to.deep.equal(['edit', 'translate']); }); }); });