Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGrid] Add 'gridReady' event to notify the user when the grid has been mounted #6568

Closed
wants to merge 9 commits into from
Prev Previous commit
Next Next commit
refa: test moved from DataGridPro to DataGrid
  • Loading branch information
yaredtsy committed Feb 15, 2023
commit 7ddcac6265f6e8402e698438d7c7f2dfd5dbe145
145 changes: 1 addition & 144 deletions packages/grid/x-data-grid-pro/src/tests/events.DataGridPro.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
// @ts-ignore Remove once the test utils are typed
import { createRenderer, fireEvent, screen, act, waitFor } from '@mui/monorepo/test/utils';
import { createRenderer, fireEvent, screen, act } from '@mui/monorepo/test/utils';
import { expect } from 'chai';
import {
DataGridPro,
Expand All @@ -16,7 +16,6 @@ import {
GridApi,
GridEventListener,
} from '@mui/x-data-grid-pro';
import { getBasicGridData } from '@mui/x-data-grid-generator';
import { getCell, getColumnHeaderCell } from 'test/utils/helperFn';
import { spy } from 'sinon';

Expand Down Expand Up @@ -331,148 +330,6 @@ describe('<DataGridPro /> - Events Params', () => {
});
});

describe('gridReady', () => {
interface TestGridProps extends Partial<DataGridProProps> {
onGridReady: () => void;
}

let gridReadyApiRef: React.MutableRefObject<GridApi>;

function TestGrid(props: TestGridProps) {
gridReadyApiRef = useGridApiRef();
React.useEffect(() => {
return gridReadyApiRef.current.subscribeEvent('gridReady', () => {
props.onGridReady();
});
}, [props, props.onGridReady]);
return (
<div style={{ width: 300, height: 500 }}>
<DataGridPro
{...props}
apiRef={gridReadyApiRef}
rows={props.rows ?? []}
columns={props.columns ?? []}
/>
</div>
);
}
it('gridReady should only be fired once.', async () => {
const gridReady = spy();
const { rows, columns } = getBasicGridData(5, 2);

render(
<TestGrid
onGridReady={() => {
gridReady();
}}
rows={rows}
columns={columns}
/>,
);
await waitFor(() => expect(gridReady.callCount).to.equal(1));
});

it('gridReady should not be fired if there is no data.', async () => {
const gridReady = spy();
render(
<TestGrid
onGridReady={() => {
gridReady();
}}
loading
/>,
);

await waitFor(() => expect(gridReady.callCount).to.equal(0));
});

it('gridReady should be triggered after all states are initialized. so that user can start interacting with the gird after its published', async () => {
const gridReady = spy();
const rowLength = 5;
const { rows, columns } = getBasicGridData(rowLength, 4);
const focusedRow = rows[4].id;
const focusedColumnsField = columns[3].field;

render(
<TestGrid
onGridReady={() => {
gridReady(gridReadyApiRef.current.getRowModels().size);
// user should be able to interact with the grid the `gridReady` event is triggered.
act(() => gridReadyApiRef.current.setCellFocus(focusedRow, focusedColumnsField));
}}
rows={rows}
columns={columns}
/>,
);

await waitFor(() => expect(gridReady.callCount).to.equal(1));

// Checking if the user can successfully interact with the grid after gridReady called.
expect(gridReadyApiRef.current.state.focus.cell).to.not.equal(null);
expect(gridReady.args[0][0]).to.equal(rowLength);
});

it('gridReady should work with virtualization enabled.', async () => {
const gridReady = spy();
const { rows, columns } = getBasicGridData(20, 4);
render(
<TestGrid
onGridReady={() => {
gridReady();
}}
rows={rows}
columns={columns}
/>,
);

await waitFor(() => expect(gridReady.callCount).to.equal(1));
});

it('gridReady should not be called every time a state updates.', async () => {
const gridReady = spy();
const { rows, columns } = getBasicGridData(20, 4);

render(
<TestGrid
onGridReady={() => {
gridReady();
}}
rows={rows}
columns={columns}
/>,
);

await waitFor(() => {
expect(gridReady.callCount).to.equal(1);
});
act(() => gridReadyApiRef.current.setState({ ...gridReadyApiRef.current.state }));
expect(gridReady.callCount).to.equal(1);
});

it('gridReady should work with a predefined initial state.', async () => {
const gridReady = spy();
const { rows, columns } = getBasicGridData(20, 4);
render(
<TestGrid
onGridReady={() => {
gridReady(gridReadyApiRef.current.getRowModels().size);
}}
rows={rows}
columns={columns}
initialState={{
columns: {
columnVisibilityModel: {
[columns[0].field]: false,
},
},
}}
/>,
);

await waitFor(() => act(() => expect(gridReady.callCount).to.equal(1)));
});
});

it('publishing GRID_ROWS_SCROLL should call onRowsScrollEnd callback', () => {
const handleRowsScrollEnd = spy();
render(<TestEvents onRowsScrollEnd={handleRowsScrollEnd} />);
Expand Down
152 changes: 152 additions & 0 deletions packages/grid/x-data-grid/src/tests/events.DataGrid.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import * as React from 'react';
// @ts-ignore Remove once the test utils are typed
import { createRenderer, act, waitFor } from '@mui/monorepo/test/utils';
import { expect } from 'chai';
import { DataGrid, useGridApiRef, GridApi, DataGridProps } from '@mui/x-data-grid';
import { getBasicGridData } from '@mui/x-data-grid-generator/services';
import { spy } from 'sinon';

describe('<DataGrid /> - Events Params', () => {
const { render } = createRenderer();
describe('gridReady', () => {
interface TestGridProps extends Partial<DataGridProps> {
onGridReady: () => void;
}

let apiRef: React.MutableRefObject<GridApi>;

function TestGrid(props: TestGridProps) {
apiRef = useGridApiRef();
React.useEffect(() => {
return apiRef.current.subscribeEvent('gridReady', () => {
props.onGridReady();
});
}, [props, props.onGridReady]);
return (
<div style={{ width: 300, height: 500 }}>
<DataGrid
{...props}
apiRef={apiRef}
rows={props.rows ?? []}
columns={props.columns ?? []}
/>
</div>
);
}
it('gridReady should only be fired once.', async () => {
const gridReady = spy();
const { rows, columns } = getBasicGridData(5, 2);

render(
<TestGrid
onGridReady={() => {
gridReady();
}}
rows={rows}
columns={columns}
/>,
);
await waitFor(() => expect(gridReady.callCount).to.equal(1));
});

it('gridReady should not be fired if there is no data.', async () => {
const gridReady = spy();
render(
<TestGrid
onGridReady={() => {
gridReady();
}}
/>,
);

await waitFor(() => expect(gridReady.callCount).to.equal(0));
});

it('gridReady should be triggered after all states are initialized. so that user can start interacting with the gird after the event is published', async () => {
const gridReady = spy();
const rowLength = 5;
const { rows, columns } = getBasicGridData(rowLength, 4);
const focusedRow = rows[4].id;
const focusedColumnsField = columns[3].field;

render(
<TestGrid
onGridReady={() => {
gridReady(apiRef.current.getRowModels().size);
// user should be able to interact with the grid the `gridReady` event is triggered.
act(() => apiRef.current.setCellFocus(focusedRow, focusedColumnsField));
}}
rows={rows}
columns={columns}
/>,
);

await waitFor(() => expect(gridReady.callCount).to.equal(1));

// Checking if the user can successfully interact with the grid after gridReady called.
expect(apiRef.current.state.focus.cell).to.not.equal(null);
expect(gridReady.args[0][0]).to.equal(rowLength);
});

it('gridReady should work with virtualization enabled.', async () => {
const gridReady = spy();
const { rows, columns } = getBasicGridData(20, 4);
render(
<TestGrid
onGridReady={() => {
gridReady();
}}
rows={rows}
columns={columns}
/>,
);

await waitFor(() => expect(gridReady.callCount).to.equal(1));
});

it('gridReady should not be called every time a state updates.', async () => {
const gridReady = spy();
const { rows, columns } = getBasicGridData(20, 4);

render(
<TestGrid
onGridReady={() => {
gridReady();
}}
rows={rows}
columns={columns}
/>,
);

await waitFor(() => {
expect(gridReady.callCount).to.equal(1);
});
act(() => apiRef.current.setState({ ...apiRef.current.state }));
expect(gridReady.callCount).to.equal(1);
});

it('gridReady should work with a predefined initial state.', async () => {
const gridReady = spy();
const { rows, columns } = getBasicGridData(20, 4);
render(
<TestGrid
onGridReady={() => {
gridReady(apiRef.current.getRowModels().size);
}}
rows={rows}
columns={columns}
initialState={{
columns: {
columnVisibilityModel: {
[columns[0].field]: false,
},
},
}}
/>,
);

await waitFor(() => act(() => expect(gridReady.callCount).to.equal(1)));
expect(apiRef.current.getVisibleColumns().length).to.lessThan(columns.length);
});
});
});