mirror of
https://github.com/apache/superset.git
synced 2026-05-30 04:39:20 +00:00
fix: chart rendering race condition and homepage connection reset (#40065)
Co-authored-by: Geidō <60598000+geido@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
01224007da
commit
a62bf2b0bb
@@ -156,6 +156,78 @@ describe('chart actions', () => {
|
||||
.mockImplementation((data: unknown) => Promise.resolve(data));
|
||||
});
|
||||
|
||||
test('should drop stale success dispatches when a newer controller has replaced ours in state', async () => {
|
||||
const chartKey = 'stale_success_test';
|
||||
const formData: Partial<QueryFormData> = {
|
||||
slice_id: 456,
|
||||
datasource: 'table__1',
|
||||
viz_type: 'table',
|
||||
};
|
||||
// A controller belonging to a *newer* in-flight request, already stored
|
||||
// in state by the time this thunk's response resolves.
|
||||
const newerController = new AbortController();
|
||||
const state: MockState = {
|
||||
charts: {
|
||||
[chartKey]: {
|
||||
queryController: newerController,
|
||||
},
|
||||
},
|
||||
common: {
|
||||
conf: {
|
||||
SUPERSET_WEBSERVER_TIMEOUT: 60,
|
||||
},
|
||||
},
|
||||
};
|
||||
const getState = jest.fn(() => state);
|
||||
const dispatchMock = jest.fn();
|
||||
const getChartDataRequestSpy = jest
|
||||
.spyOn(actions, 'getChartDataRequest')
|
||||
.mockResolvedValue({
|
||||
response: { status: 200 } as Response,
|
||||
json: { result: [{ data: [{ stale: true }] }] },
|
||||
});
|
||||
const handleChartDataResponseSpy = jest
|
||||
.spyOn(actions, 'handleChartDataResponse')
|
||||
.mockResolvedValue([{ data: [{ stale: true }] }]);
|
||||
const updateDataMaskSpy = jest
|
||||
.spyOn(dataMaskActions, 'updateDataMask')
|
||||
.mockReturnValue({ type: 'UPDATE_DATA_MASK' } as ReturnType<
|
||||
typeof dataMaskActions.updateDataMask
|
||||
>);
|
||||
const getQuerySettingsStub = jest
|
||||
.spyOn(exploreUtils, 'getQuerySettings')
|
||||
.mockReturnValue([false, () => {}] as unknown as ReturnType<
|
||||
typeof exploreUtils.getQuerySettings
|
||||
>);
|
||||
|
||||
try {
|
||||
const thunkAction = actions.exploreJSON(
|
||||
formData as QueryFormData,
|
||||
false,
|
||||
undefined,
|
||||
chartKey,
|
||||
);
|
||||
await thunkAction(
|
||||
dispatchMock as unknown as actions.ChartThunkDispatch,
|
||||
getState as unknown as () => actions.RootState,
|
||||
undefined,
|
||||
);
|
||||
|
||||
// CHART_UPDATE_STARTED is fine (it ran before the gate),
|
||||
// but CHART_UPDATE_SUCCEEDED must NOT have fired with the stale data.
|
||||
const dispatchedTypes = dispatchMock.mock.calls.map(
|
||||
([action]) => action?.type,
|
||||
);
|
||||
expect(dispatchedTypes).toContain(actions.CHART_UPDATE_STARTED);
|
||||
expect(dispatchedTypes).not.toContain(actions.CHART_UPDATE_SUCCEEDED);
|
||||
} finally {
|
||||
getChartDataRequestSpy.mockRestore();
|
||||
handleChartDataResponseSpy.mockRestore();
|
||||
updateDataMaskSpy.mockRestore();
|
||||
getQuerySettingsStub.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
test('should defer abort of previous controller to avoid Redux state mutation', async () => {
|
||||
jest.useFakeTimers();
|
||||
const chartKey = 'defer_abort_test';
|
||||
|
||||
Reference in New Issue
Block a user