Copilot commented on code in PR #37497:
URL: https://github.com/apache/superset/pull/37497#discussion_r2737931766


##########
superset-frontend/src/dashboard/actions/dashboardState.test.js:
##########
@@ -234,4 +236,61 @@ describe('dashboardState actions', () => {
       );
     });
   });
+
+  // eslint-disable-next-line no-restricted-globals -- TODO: Migrate from 
describe blocks
+  describe('fetchFaveStar', () => {
+    test('dispatches TOGGLE_FAVE_STAR on successful fetch', async () => {
+      const dashboardId = 123;
+      const dispatch = sinon.stub();
+      
+      getStub.restore();
+      getStub = sinon.stub(SupersetClient, 'get').resolves({
+        json: {
+          result: [{ id: dashboardId, value: true }],
+        },
+      });
+
+      const thunk = fetchFaveStar(dashboardId);
+      await thunk(dispatch);
+
+      await waitFor(() => expect(dispatch.callCount).toBe(1));
+      expect(dispatch.getCall(0).args[0].type).toBe(TOGGLE_FAVE_STAR);
+      expect(dispatch.getCall(0).args[0].isStarred).toBe(true);
+    });
+
+    test('does not dispatch error toast on 404 response', async () => {
+      const dashboardId = 999;
+      const dispatch = sinon.stub();
+      
+      getStub.restore();
+      const error404 = new Error('Not found');
+      error404.status = 404;
+      getStub = sinon.stub(SupersetClient, 'get').rejects(error404);
+
+      const thunk = fetchFaveStar(dashboardId);
+      await thunk(dispatch);
+
+      // Should not dispatch any action (no toast, no toggle)
+      expect(dispatch.callCount).toBe(0);
+    });
+
+    test('dispatches error toast on non-404 errors', async () => {
+      const dashboardId = 123;
+      const dispatch = sinon.stub();
+      
+      getStub.restore();
+      const error500 = new Error('Internal server error');
+      error500.status = 500;
+      getStub = sinon.stub(SupersetClient, 'get').rejects(error500);

Review Comment:
   Same mocking issue as the 404 test: rejecting with a plain `Error` (even 
with `status = 500`) won’t reliably propagate `status` through 
`getClientErrorObject`. To ensure this test is validating the intended non-404 
branch, reject with a Response-like object that includes `status`/`statusText` 
(or mock `getClientErrorObject`).



##########
superset-frontend/src/dashboard/components/Header/index.jsx:
##########
@@ -592,7 +592,12 @@ const Header = () => {
   const faveStarProps = useMemo(
     () => ({
       itemId: dashboardInfo.id,
-      fetchFaveStar: boundActionCreators.fetchFaveStar,
+      // Only fetch favorite status for valid, existing dashboards
+      // Skip fetch entirely if dashboard ID is falsy to prevent
+      // 404 errors when navigating after dashboard deletion

Review Comment:
   The inline comment suggests a falsy dashboard ID would lead to 404s, but a 
404 implies a *truthy* ID that no longer exists. Consider rewording this 
comment to reflect the actual scenario (skip fetch when there is no ID / 
component is unmounted), and rely on the 404 handling in `fetchFaveStar` for 
deleted/stale IDs.
   ```suggestion
         // Only attempt to fetch favorite status when there's a valid 
dashboard ID.
         // When the ID is falsy (e.g., dashboard not yet created or component 
unmounted),
         // skip the fetch and rely on fetchFaveStar to handle 404s for 
deleted/stale IDs.
   ```



##########
superset-frontend/src/dashboard/actions/dashboardState.test.js:
##########
@@ -234,4 +236,61 @@ describe('dashboardState actions', () => {
       );
     });
   });
+
+  // eslint-disable-next-line no-restricted-globals -- TODO: Migrate from 
describe blocks
+  describe('fetchFaveStar', () => {
+    test('dispatches TOGGLE_FAVE_STAR on successful fetch', async () => {
+      const dashboardId = 123;
+      const dispatch = sinon.stub();
+      
+      getStub.restore();
+      getStub = sinon.stub(SupersetClient, 'get').resolves({
+        json: {
+          result: [{ id: dashboardId, value: true }],
+        },
+      });
+
+      const thunk = fetchFaveStar(dashboardId);
+      await thunk(dispatch);
+
+      await waitFor(() => expect(dispatch.callCount).toBe(1));
+      expect(dispatch.getCall(0).args[0].type).toBe(TOGGLE_FAVE_STAR);
+      expect(dispatch.getCall(0).args[0].isStarred).toBe(true);
+    });
+
+    test('does not dispatch error toast on 404 response', async () => {
+      const dashboardId = 999;
+      const dispatch = sinon.stub();
+      
+      getStub.restore();
+      const error404 = new Error('Not found');
+      error404.status = 404;
+      getStub = sinon.stub(SupersetClient, 'get').rejects(error404);

Review Comment:
   The mocked 404 error here (`new Error()` with a `status` field) will not be 
interpreted as a 404 by `getClientErrorObject` (it only carries `status` 
through when the rejection is a Response-like object, e.g. `{ response: { 
status, statusText, bodyUsed } }`). As a result, this test won’t actually 
exercise the 404-suppression path and will likely dispatch the danger toast 
instead. Update the mock rejection to match the shape 
SupersetClient/getClientErrorObject expects (or mock `getClientErrorObject` 
directly).
   ```suggestion
         getStub = sinon
           .stub(SupersetClient, 'get')
           .rejects({
             response: {
               status: 404,
               statusText: 'Not Found',
               bodyUsed: false,
             },
           });
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to