This is an automated email from the ASF dual-hosted git repository.

msyavuz pushed a commit to branch msyavuz/fix/infinite-refresh-bug
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 45bb64d08e441a16bcbd3041c9fd36af29edbc30
Author: Mehmet Salih Yavuz <[email protected]>
AuthorDate: Fri Jan 9 21:20:27 2026 +0300

    test: add regression tests
---
 .../components/gridComponents/Tab/Tab.test.tsx     | 102 +++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git 
a/superset-frontend/src/dashboard/components/gridComponents/Tab/Tab.test.tsx 
b/superset-frontend/src/dashboard/components/gridComponents/Tab/Tab.test.tsx
index e4e529eade..7f0392fc5f 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Tab/Tab.test.tsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Tab/Tab.test.tsx
@@ -541,3 +541,105 @@ test('Should not refresh charts when tab becomes active 
if no dashboard refresh
 
   expect(onRefresh).not.toHaveBeenCalled();
 });
+
+test('Should not cause infinite refresh loop with nested tabs - regression 
test', async () => {
+  jest.clearAllMocks();
+  const getChartIdsFromComponent = 
require('src/dashboard/util/getChartIdsFromComponent');
+  getChartIdsFromComponent.mockReset();
+  getChartIdsFromComponent.mockReturnValue([201, 202]);
+
+  const props = createProps();
+  props.renderType = 'RENDER_TAB_CONTENT';
+  props.isComponentVisible = false;
+
+  const initialState = {
+    dashboardState: {
+      lastRefreshTime: Date.now() - 1000, // Dashboard was refreshed recently
+      tabActivationTimes: {
+        'TAB-YT6eNksV-': Date.now() - 5000, // Tab was activated before refresh
+      },
+    },
+    dashboardInfo: {
+      id: 23,
+      dash_edit_perm: true,
+    },
+  };
+
+  const { rerender } = render(<Tab {...props} />, {
+    useRedux: true,
+    useDnd: true,
+    initialState,
+  });
+
+  // Initial state - no refresh should happen
+  expect(onRefresh).not.toHaveBeenCalled();
+
+  // Make tab visible - should trigger ONE refresh
+  rerender(<Tab {...props} isComponentVisible />);
+
+  await waitFor(
+    () => {
+      expect(onRefresh).toHaveBeenCalledTimes(1);
+    },
+    { timeout: 500 },
+  );
+
+  // Clear the mock to track subsequent calls
+  jest.clearAllMocks();
+
+  // REGRESSION TEST: Multiple re-renders should NOT trigger additional 
refreshes
+  // This simulates the infinite loop scenario that was happening with nested 
tabs
+  for (let i = 0; i < 5; i++) {
+    rerender(<Tab {...props} isComponentVisible />);
+    await new Promise(resolve => setTimeout(resolve, 20));
+  }
+
+  expect(onRefresh).not.toHaveBeenCalled();
+});
+
+test('Should use isLazyLoad flag for tab refreshes', async () => {
+  jest.clearAllMocks();
+  const getChartIdsFromComponent = 
require('src/dashboard/util/getChartIdsFromComponent');
+  getChartIdsFromComponent.mockReset();
+  getChartIdsFromComponent.mockReturnValue([401, 402]);
+
+  const props = createProps();
+  props.renderType = 'RENDER_TAB_CONTENT';
+  props.isComponentVisible = true;
+
+  const initialState = {
+    dashboardState: {
+      lastRefreshTime: Date.now() - 1000, // Dashboard was refreshed recently
+      tabActivationTimes: {
+        'TAB-YT6eNksV-': Date.now() - 5000, // Tab was activated before refresh
+      },
+    },
+    dashboardInfo: {
+      id: 42,
+      dash_edit_perm: true,
+    },
+  };
+
+  render(<Tab {...props} />, {
+    useRedux: true,
+    useDnd: true,
+    initialState,
+  });
+
+  // Tab should trigger refresh with isLazyLoad = true
+  await waitFor(
+    () => {
+      expect(onRefresh).toHaveBeenCalled();
+    },
+    { timeout: 500 },
+  );
+
+  // Verify that isLazyLoad flag is set to true for tab refreshes
+  expect(onRefresh).toHaveBeenCalledWith(
+    [401, 402],
+    true, // force
+    0, // interval
+    42, // dashboardId
+    true, // isLazyLoad should be true to prevent infinite loops
+  );
+});

Reply via email to