diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-with-promise-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-with-promise-table.js deleted file mode 100644 index c66e3bd..0000000 --- a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-with-promise-table.js +++ /dev/null @@ -1,75 +0,0 @@ -/* eslint no-unused-vars: 0 */ -/* eslint arrow-body-style: 0 */ -import React, { Component } from 'react'; - -import BootstrapTable from 'react-bootstrap-table2'; -import Code from 'components/common/code-block'; -import { productsGenerator, sleep } from 'utils/common'; - -const products = productsGenerator(); - -const columns = [{ - dataField: 'id', - text: 'Product ID' -}, { - dataField: 'name', - text: 'Product Name' -}, { - dataField: 'price', - text: 'Product Price' -}]; - -const sourceCode = `\ -class CellEditWithPromise extends Component { - handleCellEditing = (rowId, dataField, newValue) => { - return sleep(1000).then(() => { - if (dataField === 'price' && (newValue < 2000 || isNaN(newValue))) { - throw new Error('Product Price should bigger than $2000'); - } - }); - } - - render() { - const cellEdit = { - mode: 'click', - blurToSave: true, - onUpdate: this.handleCellEditing - }; - - return ( -
- - { sourceCode } -
- ); - } -} -`; - -class CellEditWithPromise extends Component { - handleCellEditing = (rowId, dataField, newValue) => { - return sleep(1000).then(() => { - if (dataField === 'price' && (newValue < 2000 || isNaN(newValue))) { - throw new Error('Product Price should bigger than $2000'); - } - }); - } - - render() { - const cellEdit = { - mode: 'click', - blurToSave: true, - onUpdate: this.handleCellEditing - }; - - return ( -
- - { sourceCode } -
- ); - } -} - -export default CellEditWithPromise; - diff --git a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-with-redux-table.js b/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-with-redux-table.js deleted file mode 100644 index 760c6d9..0000000 --- a/packages/react-bootstrap-table2-example/examples/cell-edit/cell-edit-with-redux-table.js +++ /dev/null @@ -1,212 +0,0 @@ -/* eslint no-unused-vars: 0 */ -/* eslint react/prop-types: 0 */ -/* eslint arrow-body-style: 0 */ -/* eslint consistent-return: 0 */ -/* eslint no-class-assign: 0 */ -import React, { Component } from 'react'; -import thunk from 'redux-thunk'; -import { Provider, connect } from 'react-redux'; -import { createStore, applyMiddleware } from 'redux'; -import BootstrapTable from 'react-bootstrap-table2'; -import Code from 'components/common/code-block'; -import { productsGenerator } from 'utils/common'; - -const columns = [{ - dataField: 'id', - text: 'Product ID' -}, { - dataField: 'name', - text: 'Product Name' -}, { - dataField: 'price', - text: 'Product Price' -}]; - -const sourceCode = `\ -/////////////////////// Action Creator /////////////////////// -const setErrorMessage = (errorMessage = null) => { - return { type: 'SET_ERR_MESSAGE', errorMessage }; -}; - -// Async Action, using redux-thunk -const cellEditingAsync = (rowId, dataField, newValue) => { - return (dispatch) => { - setTimeout(() => { - if (dataField === 'price' && (newValue < 2000 || isNaN(newValue))) { - dispatch(setErrorMessage('Product Price should bigger than $2000')); - } else { - dispatch({ type: 'ADD_SUCCESS', rowId, dataField, newValue }); - } - }, 1200); - }; -}; - -/////////////////////// Component /////////////////////// -class CellEditWithRedux extends Component { - // dispatch a async action - handleCellEditing = (rowId, dataField, newValue) => { - this.props.dispatch(cellEditingAsync(rowId, dataField, newValue)); - return false; - } - - handleErrorMsgDisappear = () => { - this.props.dispatch(setErrorMessage()); - } - - render() { - const cellEdit = { - mode: 'click', - editing: this.props.cellEditing, - errorMessage: this.props.errorMessage, - onUpdate: this.handleCellEditing, - onErrorMessageDisappear: this.handleErrorMsgDisappear - }; - - return ( -
- - { sourceCode } -
- ); - } -} -// connect -CellEditWithRedux = connect(state => state)(CellEditWithRedux); - -/////////////////////// Reducer /////////////////////// -// initial state object and simple reducers -const initialState = { - data: productsGenerator(), - cellEditing: false, - errorMessage: null -}; - -const reducers = (state, action) => { - switch (action.type) { - case 'ADD_SUCCESS': { - const { rowId, dataField, newValue } = action; - const data = [...state.data]; - const rowIndex = data.findIndex(r => r.id === rowId); - data[rowIndex][dataField] = newValue; - return { - data, - cellEditing: false, - errorMessage: null - }; - } - case 'SET_ERR_MESSAGE': { - const { errorMessage } = action; - return { - ...state, - cellEditing: true, - errorMessage - }; - } - default: { - return { ...state }; - } - } -}; - -/////////////////////// Index /////////////////////// -const store = createStore(reducers, initialState, applyMiddleware(thunk)); - -const Index = () => ( - - - -); -`; - -const setErrorMessage = (errorMessage = null) => { - return { type: 'SET_ERR_MESSAGE', errorMessage }; -}; - -// Async Action, using redux-thunk -const cellEditingAsync = (rowId, dataField, newValue) => { - return (dispatch) => { - setTimeout(() => { - if (dataField === 'price' && (newValue < 2000 || isNaN(newValue))) { - dispatch(setErrorMessage('Product Price should bigger than $2000')); - } else { - dispatch({ type: 'ADD_SUCCESS', rowId, dataField, newValue }); - } - }, 1200); - }; -}; - -class CellEditWithRedux extends Component { - // dispatch a async action - handleCellEditing = (rowId, dataField, newValue) => { - this.props.dispatch(cellEditingAsync(rowId, dataField, newValue)); - return false; - } - - handleErrorMsgDisappear = () => { - this.props.dispatch(setErrorMessage()); - } - - render() { - const cellEdit = { - mode: 'click', - editing: this.props.cellEditing, - errorMessage: this.props.errorMessage, - onUpdate: this.handleCellEditing, - onErrorMessageDisappear: this.handleErrorMsgDisappear - }; - - return ( -
- - { sourceCode } -
- ); - } -} -// connect -CellEditWithRedux = connect(state => state)(CellEditWithRedux); - -// initial state object and simple reducers -const initialState = { - data: productsGenerator(), - cellEditing: false, - errorMessage: null -}; - -const reducers = (state, action) => { - switch (action.type) { - case 'ADD_SUCCESS': { - const { rowId, dataField, newValue } = action; - const data = JSON.parse(JSON.stringify(state.data)); - const rowIndex = data.findIndex(r => r.id === rowId); - data[rowIndex][dataField] = newValue; - return { - data, - cellEditing: false, - errorMessage: null - }; - } - case 'SET_ERR_MESSAGE': { - const { errorMessage } = action; - return { - ...state, - cellEditing: true, - errorMessage - }; - } - default: { - return { ...state }; - } - } -}; - -const store = createStore(reducers, initialState, applyMiddleware(thunk)); - -const Index = () => ( - - - -); - -export default Index; - diff --git a/packages/react-bootstrap-table2-example/examples/remote/remote-celledit.js b/packages/react-bootstrap-table2-example/examples/remote/remote-celledit.js new file mode 100644 index 0000000..312c81e --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/remote/remote-celledit.js @@ -0,0 +1,165 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import BootstrapTable from 'react-bootstrap-table2'; +import Code from 'components/common/code-block'; +import { productsGenerator } from 'utils/common'; + +const products = productsGenerator(); + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name' +}, { + dataField: 'price', + text: 'Product Price' +}]; + +const sourceCode = `\ +const RemoteCellEdit = (props) => { + const cellEdit = { + mode: 'click', + errorMessage: props.errorMessage + }; + + return ( +
+ + { sourceCode } +
+ ); +}; + +RemoteCellEdit.propTypes = { + data: PropTypes.array.isRequired, + onTableChange: PropTypes.func.isRequired, + errorMessage: PropTypes.string.isRequired +}; + +class Container extends React.Component { + constructor(props) { + super(props); + this.state = { + data: products, + errorMessage: null + }; + } + + handleTableChange = (type, { data, cellEdit: { rowId, dataField, newValue } }) => { + setTimeout(() => { + if (newValue === 'test' && dataField === 'name') { + this.setState(() => ({ + data, + errorMessage: 'Oops, product name shouldn't be "test"' + })); + } else { + const result = data.map((row) => { + if (row.id === rowId) { + const newRow = { ...row }; + newRow[dataField] = newValue; + return newRow; + } + return row; + }); + this.setState(() => ({ + data: result, + errorMessage: null + })); + } + }, 2000); + } + + render() { + return ( + + ); + } +} +`; + + +const RemoteCellEdit = (props) => { + const cellEdit = { + mode: 'click', + errorMessage: props.errorMessage + }; + + return ( +
+ + { sourceCode } +
+ ); +}; + +RemoteCellEdit.propTypes = { + data: PropTypes.array.isRequired, + onTableChange: PropTypes.func.isRequired, + errorMessage: PropTypes.string.isRequired +}; + +class Container extends React.Component { + constructor(props) { + super(props); + this.state = { + data: products, + errorMessage: null + }; + } + + handleTableChange = (type, { data, cellEdit: { rowId, dataField, newValue } }) => { + setTimeout(() => { + if (newValue === 'test' && dataField === 'name') { + this.setState(() => ({ + data, + errorMessage: 'Oops, product name shouldn\'t be "test"' + })); + } else { + const result = data.map((row) => { + if (row.id === rowId) { + const newRow = { ...row }; + newRow[dataField] = newValue; + return newRow; + } + return row; + }); + this.setState(() => ({ + data: result, + errorMessage: null + })); + } + }, 2000); + } + + render() { + return ( + + ); + } +} + +export default Container; diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js index 909f5b8..3fe704c 100644 --- a/packages/react-bootstrap-table2-example/stories/index.js +++ b/packages/react-bootstrap-table2-example/stories/index.js @@ -63,8 +63,6 @@ import CellEditHooks from 'examples/cell-edit/cell-edit-hooks-table'; import CellEditValidator from 'examples/cell-edit/cell-edit-validator-table'; import CellEditStyleTable from 'examples/cell-edit/cell-edit-style-table'; import CellEditClassTable from 'examples/cell-edit/cell-edit-class-table'; -import CellEditWithPromise from 'examples/cell-edit/cell-edit-with-promise-table'; -import CellEditWithRedux from 'examples/cell-edit/cell-edit-with-redux-table'; // work on row selection import SingleSelectionTable from 'examples/row-selection/single-selection'; @@ -91,6 +89,7 @@ import TableOverlay from 'examples/loading-overlay/table-overlay'; import RemoteSort from 'examples/remote/remote-sort'; import RemoteFilter from 'examples/remote/remote-filter'; import RemotePaginationTable from 'examples/remote/remote-pagination'; +import RemoteCellEdit from 'examples/remote/remote-celledit'; import RemoteAll from 'examples/remote/remote-all'; // css style @@ -165,9 +164,7 @@ storiesOf('Cell Editing', module) .add('Rich Hook Functions', () => ) .add('Validation', () => ) .add('Custom Cell Style When Editing', () => ) - .add('Custom Cell Classes When Editing', () => ) - .add('Async Cell Editing(Promise)', () => ) - .add('Async Cell Editing(Redux)', () => ); + .add('Custom Cell Classes When Editing', () => ); storiesOf('Row Selection', module) .add('Single Selection', () => ) @@ -194,4 +191,5 @@ storiesOf('Remote', module) .add('Remote Sort', () => ) .add('Remote Filter', () => ) .add('Remote Pagination', () => ) + .add('Remote Cell Editing', () => ) .add('Remote All', () => ); diff --git a/packages/react-bootstrap-table2-filter/test/wrapper.test.js b/packages/react-bootstrap-table2-filter/test/wrapper.test.js index f250c46..b80cd74 100644 --- a/packages/react-bootstrap-table2-filter/test/wrapper.test.js +++ b/packages/react-bootstrap-table2-filter/test/wrapper.test.js @@ -28,7 +28,7 @@ describe('Wrapper', () => { onTableChangeCB.reset(); }); - const createTableProps = () => { + const createTableProps = (props) => { const tableProps = { keyField: 'id', columns: [{ @@ -47,7 +47,8 @@ describe('Wrapper', () => { filter: filter(), _, store: new Store('id'), - onTableChange: onTableChangeCB + onTableChange: onTableChangeCB, + ...props }; tableProps.store.data = data; return tableProps; @@ -105,6 +106,17 @@ describe('Wrapper', () => { }); }); + describe('when props.isDataChanged is true and remote is enable', () => { + beforeEach(() => { + nextProps = createTableProps({ isDataChanged: true }); + instance.componentWillReceiveProps(nextProps); + }); + + it('should setting isDataChanged as true', () => { + expect(instance.state.isDataChanged).toBeTruthy(); + }); + }); + describe('when props.store.filters is different from current state.currFilters', () => { beforeEach(() => { nextProps = createTableProps(); diff --git a/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js b/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js index 8f21f5f..c195b16 100644 --- a/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js +++ b/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js @@ -31,13 +31,10 @@ describe('CellEditWrapper', () => { }; const keyField = 'id'; - let onUpdateCellCB = sinon.stub(); const store = new Store(keyField); store.data = data; - const CellEditWrapper = wrapperFactory(Container, { - onUpdateCell: onUpdateCellCB - }); + const CellEditWrapper = wrapperFactory(Container); beforeEach(() => { wrapper = shallow( @@ -60,24 +57,24 @@ describe('CellEditWrapper', () => { expect(wrapper.state().ridx).toBeNull(); expect(wrapper.state().cidx).toBeNull(); expect(wrapper.state().message).toBeNull(); - expect(wrapper.state().editing).toBeFalsy(); + expect(wrapper.state().isDataChanged).toBeFalsy(); }); it('should inject correct props to base component', () => { expect(wrapper.props().onCellUpdate).toBeDefined(); expect(wrapper.props().onStartEditing).toBeDefined(); expect(wrapper.props().onEscapeEditing).toBeDefined(); + expect(wrapper.props().isDataChanged).toBe(wrapper.state().isDataChanged); expect(wrapper.props().currEditCell).toBeDefined(); expect(wrapper.props().currEditCell.ridx).toBeNull(); expect(wrapper.props().currEditCell.cidx).toBeNull(); expect(wrapper.props().currEditCell.message).toBeNull(); - expect(wrapper.props().currEditCell.editing).toBeFalsy(); }); describe('when receive new cellEdit prop', () => { const spy = jest.spyOn(CellEditWrapper.prototype, 'escapeEditing'); - describe('and cellEdit.editing is false', () => { + describe('and cellEdit is not work on remote', () => { beforeEach(() => { wrapper = shallow( { store={ store } /> ); - wrapper.setProps({ cellEdit: { ...cellEdit, editing: false } }); + wrapper.setProps({ cellEdit: { ...cellEdit } }); }); - it('should call escapeEditing', () => { - expect(spy).toHaveBeenCalled(); - }); - - it('should have correct state', () => { - expect(wrapper.state().ridx).toBeNull(); - expect(wrapper.state().cidx).toBeNull(); - expect(wrapper.state().message).toBeNull(); - expect(wrapper.state().editing).toBeFalsy(); + it('should always setting state.isDataChanged as false', () => { + expect(wrapper.state().isDataChanged).toBeFalsy(); }); }); - describe('and cellEdit.editing is true', () => { - const errorMessage = 'test'; + describe('and cellEdit is work on remote', () => { + let errorMessage; const ridx = 1; const cidx = 2; - beforeEach(() => { - wrapper = shallow( - - ); - wrapper.setState({ ridx, cidx, editing: true }); - wrapper.setProps({ cellEdit: { ...cellEdit, editing: true, errorMessage } }); + describe('and cellEdit.errorMessage is defined', () => { + beforeEach(() => { + wrapper = shallow( + + ); + errorMessage = 'test'; + wrapper.setState({ ridx, cidx }); + wrapper.setProps({ cellEdit: { ...cellEdit, errorMessage } }); + }); + + it('should setting correct state', () => { + expect(wrapper.state().ridx).toEqual(ridx); + expect(wrapper.state().cidx).toEqual(cidx); + expect(wrapper.state().isDataChanged).toBeFalsy(); + expect(wrapper.state().message).toEqual(errorMessage); + }); }); - it('should have correct state', () => { - expect(wrapper.state().ridx).toEqual(ridx); - expect(wrapper.state().cidx).toEqual(cidx); - expect(wrapper.state().editing).toBeTruthy(); - expect(wrapper.state().message).toEqual(errorMessage); - }); - }); - }); + describe('and cellEdit.errorMessage is undefined', () => { + beforeEach(() => { + wrapper = shallow( + + ); + errorMessage = null; + wrapper.setState({ ridx, cidx }); + wrapper.setProps({ cellEdit: { ...cellEdit, errorMessage } }); + }); - describe('call updateEditingWithErr function', () => { - it('should set state.message correctly', () => { - const message = 'test'; - wrapper.instance().updateEditingWithErr(message); - expect(wrapper.state().message).toEqual(message); + it('should setting correct state', () => { + expect(wrapper.state().isDataChanged).toBeTruthy(); + }); + + it('should escape current editing', () => { + expect(spy).toHaveBeenCalled(); + }); + }); }); }); @@ -144,7 +156,6 @@ describe('CellEditWrapper', () => { wrapper.instance().escapeEditing(); expect(wrapper.state().ridx).toBeNull(); expect(wrapper.state().cidx).toBeNull(); - expect(wrapper.state().editing).toBeFalsy(); }); }); @@ -155,7 +166,7 @@ describe('CellEditWrapper', () => { wrapper.instance().startEditing(ridx, cidx); expect(wrapper.state().ridx).toEqual(ridx); expect(wrapper.state().cidx).toEqual(cidx); - expect(wrapper.state().editing).toBeTruthy(); + expect(wrapper.state().isDataChanged).toBeFalsy(); }); describe('if selectRow.clickToSelect is defined', () => { @@ -199,7 +210,6 @@ describe('CellEditWrapper', () => { wrapper.instance().startEditing(ridx, cidx); expect(wrapper.state().ridx).toEqual(ridx); expect(wrapper.state().cidx).toEqual(cidx); - expect(wrapper.state().editing).toBeTruthy(); }); }); }); @@ -210,7 +220,7 @@ describe('CellEditWrapper', () => { expect(wrapper.state().ridx).toBeNull(); expect(wrapper.state().cidx).toBeNull(); expect(wrapper.state().message).toBeNull(); - expect(wrapper.state().editing).toBeFalsy(); + expect(wrapper.state().isDataChanged).toBeTruthy(); }); }); @@ -219,35 +229,75 @@ describe('CellEditWrapper', () => { const column = columns[1]; const newValue = 'new name'; - beforeEach(() => { - wrapper = shallow( - - ); - wrapper.instance().handleCellUpdate(row, column, newValue); + describe('when cell edit is work on remote', () => { + const spy = jest.spyOn(CellEditWrapper.prototype, 'handleCellChange'); + const onTableChangeCB = jest.fn(); + + beforeEach(() => { + wrapper = shallow( + + ); + wrapper.instance().handleCellUpdate(row, column, newValue); + }); + + it('should calling handleCellChange correctly', () => { + expect(spy).toHaveBeenCalled(); + expect(spy.mock.calls).toHaveLength(1); + expect(spy.mock.calls[0]).toHaveLength(3); + expect(spy.mock.calls[0][0]).toEqual(row[keyField]); + expect(spy.mock.calls[0][1]).toEqual(column.dataField); + expect(spy.mock.calls[0][2]).toEqual(newValue); + }); }); - it('should calling onUpdateCell callback correctly', () => { - expect(onUpdateCellCB.callCount).toBe(1); - expect(onUpdateCellCB.calledWith(row.id, column.dataField, newValue)).toBe(true); - }); + describe('when cell edit is not work on remote', () => { + const spyOnCompleteEditing = jest.spyOn(CellEditWrapper.prototype, 'completeEditing'); + const spyOnStoreEdit = jest.spyOn(Store.prototype, 'edit'); - describe('when onUpdateCell function return true', () => { - const spy = jest.spyOn(CellEditWrapper.prototype, 'completeEditing'); + beforeEach(() => { + wrapper = shallow( + + ); + wrapper.instance().handleCellUpdate(row, column, newValue); + }); + + afterEach(() => { + spyOnStoreEdit.mockReset(); + spyOnCompleteEditing.mockReset(); + }); + + it('should calling props.store.edit', () => { + expect(spyOnStoreEdit).toHaveBeenCalled(); + expect(spyOnStoreEdit.mock.calls).toHaveLength(1); + expect(spyOnStoreEdit.mock.calls[0]).toHaveLength(3); + expect(spyOnStoreEdit.mock.calls[0][0]).toEqual(row[keyField]); + expect(spyOnStoreEdit.mock.calls[0][1]).toEqual(column.dataField); + expect(spyOnStoreEdit.mock.calls[0][2]).toEqual(newValue); + }); it('should calling completeEditing function', () => { - expect(spy).toHaveBeenCalled(); + expect(spyOnCompleteEditing).toHaveBeenCalled(); }); describe('if cellEdit.afterSaveCell prop defined', () => { const aftereSaveCellCallBack = sinon.stub(); + beforeEach(() => { - cellEdit.beforeSaveCell = aftereSaveCellCallBack; + cellEdit.afterSaveCell = aftereSaveCellCallBack; wrapper = shallow( { }); }); - describe('when onUpdateCell function return false', () => { - const spy = jest.spyOn(CellEditWrapper.prototype, 'completeEditing'); - - beforeEach(() => { - onUpdateCellCB = sinon.stub().returns(false); - wrapper = shallow( - - ); - wrapper.instance().handleCellUpdate(row, column, newValue); - }); - - it('shouldn\'t calling completeEditing function', () => { - expect(spy).toHaveBeenCalled(); - }); - }); - describe('if cellEdit.beforeSaveCell prop defined', () => { const beforeSaveCellCallBack = sinon.stub(); beforeEach(() => { diff --git a/packages/react-bootstrap-table2/test/container.test.js b/packages/react-bootstrap-table2/test/container.test.js index 42c67bf..066a948 100644 --- a/packages/react-bootstrap-table2/test/container.test.js +++ b/packages/react-bootstrap-table2/test/container.test.js @@ -1,12 +1,10 @@ /* eslint react/prefer-stateless-function: 0 */ /* eslint react/no-multi-comp: 0 */ import React from 'react'; -import sinon from 'sinon'; import { shallow } from 'enzyme'; import BootstrapTable from '../src/bootstrap-table'; import Container from '../src'; -import { getRowByRowId } from '../src/store/rows'; describe('container', () => { let wrapper; @@ -79,63 +77,6 @@ describe('container', () => { it('should render BootstrapTable component successfully', () => { expect(wrapper.dive().find(BootstrapTable)).toHaveLength(1); }); - - describe('for handleUpdateCell function', () => { - const rowId = data[1].id; - const dataField = columns[1].dataField; - const newValue = 'tester'; - let result; - - describe('when cellEdit.onUpdate callback is not defined', () => { - beforeEach(() => { - result = wrapper.instance().handleUpdateCell(rowId, dataField, newValue); - }); - - it('should return true', () => { - expect(result).toBeTruthy(); - }); - - it('should update store data directly', () => { - const store = wrapper.instance().store; - const row = getRowByRowId(store)(rowId); - expect(row[dataField]).toEqual(newValue); - }); - }); - - describe('when cellEdit.onUpdate callback is define and which return false', () => { - beforeEach(() => { - cellEdit.onUpdate = sinon.stub().returns(false); - wrapper = shallow( - - ); - result = wrapper.instance().handleUpdateCell(rowId, dataField, newValue); - }); - - it('should calling cellEdit.onUpdate callback correctly', () => { - expect(cellEdit.onUpdate.callCount).toBe(1); - expect(cellEdit.onUpdate.calledWith(rowId, dataField, newValue)).toBe(true); - }); - - it('should return false', () => { - expect(result).toBeFalsy(); - }); - - it('shouldn\'t update store data', () => { - const store = wrapper.instance().store; - const row = getRowByRowId(store)(rowId); - expect(row[dataField]).not.toEqual(newValue); - }); - }); - - // We need refactoring handleUpdateCell function for handling promise firstly - // then it will be much easier to test - describe.skip('when cellEdit.onUpdate callback is define and which return a Promise', () => {}); - }); }); describe('when selectRow prop is defined', () => { diff --git a/packages/react-bootstrap-table2/test/props-resolver/index.test.js b/packages/react-bootstrap-table2/test/props-resolver/index.test.js index 79eabb4..7f4cf59 100644 --- a/packages/react-bootstrap-table2/test/props-resolver/index.test.js +++ b/packages/react-bootstrap-table2/test/props-resolver/index.test.js @@ -93,7 +93,6 @@ describe('TableResolver', () => { const expectNonEditableRows = [1, 2]; const cellEdit = { mode: Const.DBCLICK_TO_CELL_EDIT, - onUpdate: sinon.stub(), blurToSave: true, beforeSaveCell: sinon.stub(), afterSaveCell: sinon.stub(), diff --git a/packages/react-bootstrap-table2/test/props-resolver/remote-resolver.test.js b/packages/react-bootstrap-table2/test/props-resolver/remote-resolver.test.js index a6e260d..b88760f 100644 --- a/packages/react-bootstrap-table2/test/props-resolver/remote-resolver.test.js +++ b/packages/react-bootstrap-table2/test/props-resolver/remote-resolver.test.js @@ -134,6 +134,58 @@ describe('remoteResolver', () => { }); }); + describe('isRemoteCellEdit', () => { + describe('when remote is false', () => { + beforeEach(() => { + shallowContainer(); + }); + + it('should return false', () => { + expect(wrapper.instance().isRemoteCellEdit()).toBeFalsy(); + }); + }); + + describe('when remote is true', () => { + beforeEach(() => { + shallowContainer({ remote: true }); + }); + + it('should return true', () => { + expect(wrapper.instance().isRemoteCellEdit()).toBeTruthy(); + }); + }); + + describe('when remote.cellEdit is true', () => { + beforeEach(() => { + shallowContainer({ remote: { cellEdit: true } }); + }); + + it('should return true', () => { + expect(wrapper.instance().isRemoteCellEdit()).toBeTruthy(); + }); + }); + }); + + describe('handleCellChange', () => { + const onTableChangeCB = sinon.stub(); + const rowId = 1; + const dataField = 'name'; + const newValue = 'test'; + + beforeEach(() => { + onTableChangeCB.reset(); + shallowContainer({ onTableChange: onTableChangeCB }); + wrapper.instance().handleCellChange(rowId, dataField, newValue); + }); + + it('should calling props.onTableChange correctly', () => { + const cellEdit = { rowId, dataField, newValue }; + expect(onTableChangeCB.calledOnce).toBeTruthy(); + expect(onTableChangeCB.calledWith( + 'cellEdit', wrapper.instance().getNewestState({ cellEdit }))).toBeTruthy(); + }); + }); + describe('handleSortChange', () => { const onTableChangeCB = sinon.stub(); beforeEach(() => { diff --git a/packages/react-bootstrap-table2/test/row.test.js b/packages/react-bootstrap-table2/test/row.test.js index 11ccdd6..a44e52f 100644 --- a/packages/react-bootstrap-table2/test/row.test.js +++ b/packages/react-bootstrap-table2/test/row.test.js @@ -273,7 +273,6 @@ describe('Row', () => { cellEdit.cidx = editingColIndex; cellEdit.onUpdate = sinon.stub(); cellEdit.onEscape = sinon.stub(); - cellEdit.onUpdate = sinon.stub(); wrapper = shallow(