Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions superset-frontend/src/components/Chart/chartReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ export default function chartReducer(
};
},
[actions.CHART_UPDATE_STARTED](state) {
const controller = state.queryController;
Comment thread
LevisNgigi marked this conversation as resolved.
Outdated
if (controller) {
setTimeout(() => controller.abort(), 0);
Comment thread
LevisNgigi marked this conversation as resolved.
Outdated
}
return {
...state,
chartStatus: 'loading',
Expand Down
31 changes: 31 additions & 0 deletions superset-frontend/src/components/Chart/chartReducers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,35 @@ describe('chart reducers', () => {
expect(newState[chartKey].chartUpdateEndTime).toBeGreaterThan(0);
expect(newState[chartKey].chartStatus).toEqual('failed');
});

test('should defer abort of previous controller to avoid Redux state mutation', () => {
jest.useFakeTimers();

const oldController = new AbortController();
const abortSpy = jest.spyOn(oldController, 'abort');

const chartWithController = {
...testChart,
queryController: oldController,
chartStatus: 'loading',
};

const newController = new AbortController();
const newState = chartReducer(
{ [chartKey]: chartWithController },
actions.chartUpdateStarted(newController, {}, chartKey),
);

expect(abortSpy).not.toHaveBeenCalled();
expect(oldController.signal.aborted).toBe(false);

jest.runAllTimers();
expect(abortSpy).toHaveBeenCalledTimes(1);
expect(oldController.signal.aborted).toBe(true);

expect(newState[chartKey].queryController).toBe(newController);
expect(newState[chartKey].chartStatus).toBe('loading');

jest.useRealTimers();
});
});
Loading