Skip to content

Commit 45bb64d

Browse files
committed
test: add regression tests
1 parent 21e8934 commit 45bb64d

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

  • superset-frontend/src/dashboard/components/gridComponents/Tab

‎superset-frontend/src/dashboard/components/gridComponents/Tab/Tab.test.tsx‎

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,3 +541,105 @@ test('Should not refresh charts when tab becomes active if no dashboard refresh
541541

542542
expect(onRefresh).not.toHaveBeenCalled();
543543
});
544+
545+
test('Should not cause infinite refresh loop with nested tabs - regression test', async () => {
546+
jest.clearAllMocks();
547+
const getChartIdsFromComponent = require('src/dashboard/util/getChartIdsFromComponent');
548+
getChartIdsFromComponent.mockReset();
549+
getChartIdsFromComponent.mockReturnValue([201, 202]);
550+
551+
const props = createProps();
552+
props.renderType = 'RENDER_TAB_CONTENT';
553+
props.isComponentVisible = false;
554+
555+
const initialState = {
556+
dashboardState: {
557+
lastRefreshTime: Date.now() - 1000, // Dashboard was refreshed recently
558+
tabActivationTimes: {
559+
'TAB-YT6eNksV-': Date.now() - 5000, // Tab was activated before refresh
560+
},
561+
},
562+
dashboardInfo: {
563+
id: 23,
564+
dash_edit_perm: true,
565+
},
566+
};
567+
568+
const { rerender } = render(<Tab {...props} />, {
569+
useRedux: true,
570+
useDnd: true,
571+
initialState,
572+
});
573+
574+
// Initial state - no refresh should happen
575+
expect(onRefresh).not.toHaveBeenCalled();
576+
577+
// Make tab visible - should trigger ONE refresh
578+
rerender(<Tab {...props} isComponentVisible />);
579+
580+
await waitFor(
581+
() => {
582+
expect(onRefresh).toHaveBeenCalledTimes(1);
583+
},
584+
{ timeout: 500 },
585+
);
586+
587+
// Clear the mock to track subsequent calls
588+
jest.clearAllMocks();
589+
590+
// REGRESSION TEST: Multiple re-renders should NOT trigger additional refreshes
591+
// This simulates the infinite loop scenario that was happening with nested tabs
592+
for (let i = 0; i < 5; i++) {
593+
rerender(<Tab {...props} isComponentVisible />);
594+
await new Promise(resolve => setTimeout(resolve, 20));
595+
}
596+
597+
expect(onRefresh).not.toHaveBeenCalled();
598+
});
599+
600+
test('Should use isLazyLoad flag for tab refreshes', async () => {
601+
jest.clearAllMocks();
602+
const getChartIdsFromComponent = require('src/dashboard/util/getChartIdsFromComponent');
603+
getChartIdsFromComponent.mockReset();
604+
getChartIdsFromComponent.mockReturnValue([401, 402]);
605+
606+
const props = createProps();
607+
props.renderType = 'RENDER_TAB_CONTENT';
608+
props.isComponentVisible = true;
609+
610+
const initialState = {
611+
dashboardState: {
612+
lastRefreshTime: Date.now() - 1000, // Dashboard was refreshed recently
613+
tabActivationTimes: {
614+
'TAB-YT6eNksV-': Date.now() - 5000, // Tab was activated before refresh
615+
},
616+
},
617+
dashboardInfo: {
618+
id: 42,
619+
dash_edit_perm: true,
620+
},
621+
};
622+
623+
render(<Tab {...props} />, {
624+
useRedux: true,
625+
useDnd: true,
626+
initialState,
627+
});
628+
629+
// Tab should trigger refresh with isLazyLoad = true
630+
await waitFor(
631+
() => {
632+
expect(onRefresh).toHaveBeenCalled();
633+
},
634+
{ timeout: 500 },
635+
);
636+
637+
// Verify that isLazyLoad flag is set to true for tab refreshes
638+
expect(onRefresh).toHaveBeenCalledWith(
639+
[401, 402],
640+
true, // force
641+
0, // interval
642+
42, // dashboardId
643+
true, // isLazyLoad should be true to prevent infinite loops
644+
);
645+
});

0 commit comments

Comments
 (0)