rusackas commented on code in PR #40292:
URL: https://github.com/apache/superset/pull/40292#discussion_r4161665784


##########
superset/templates/superset/oauth2.html:
##########
@@ -25,13 +25,23 @@
   <body>
     <script nonce="{{ macros.get_nonce() }}">
       const message = { tabId: '{{ tab_id }}' };
+      // Emit on both channels: postMessage success doesn't guarantee the 
original
+      // tab's listener was attached. The receiver dedupes via a `handled` 
flag.
       if (typeof BroadcastChannel !== 'undefined') {
-        const channel = new BroadcastChannel('oauth');
-        channel.postMessage(message);
-        channel.close();
+        try {
+          const channel = new BroadcastChannel('oauth');
+          channel.postMessage(message);
+          channel.close();
+        } catch (e) {
+          // ignore; storage path below still fires
+        }
+      }
+      try {
+        localStorage.setItem('oauth2_auth_complete', JSON.stringify(message));
+        localStorage.removeItem('oauth2_auth_complete');
+      } catch (e) {

Review Comment:
   Good catch, fixed in b0cc385: `window.close()` now only runs once at least 
one of the two sends actually succeeded, otherwise the window stays open with 
the re-run instructions visible. Added `oauth2CallbackScript.test.ts` covering 
it, it runs the actual inline script from the template rather than a copy of it.



##########
superset-frontend/src/components/ErrorMessage/OAuth2RedirectMessage.test.tsx:
##########
@@ -304,4 +312,82 @@ describe('OAuth2RedirectMessage Component', () => {
     });
     expect(api.util.invalidateTags).not.toHaveBeenCalled();
   });
+
+  test('dispatches only once when both BroadcastChannel and storage signals 
arrive', async () => {
+    render(setup());
+
+    simulateBroadcastMessage({ tabId: 'tabId' });
+    simulateStorageMessage({ tabId: 'tabId' });
+
+    await waitFor(() => {
+      expect(reRunQuery).toHaveBeenCalledTimes(1);
+    });
+  });
+
+  test('falls back to storage events when BroadcastChannel construction 
throws', async () => {
+    globalWithBroadcastChannel.BroadcastChannel = jest
+      .fn()
+      .mockImplementation(() => {
+        throw new Error('blocked');
+      });
+
+    render(setup());
+
+    simulateStorageMessage({ tabId: 'tabId' });
+
+    await waitFor(() => {
+      expect(reRunQuery).toHaveBeenCalledWith({ sql: 'SELECT * FROM table' });
+    });
+  });
+
+  test('re-processes a later signal when the first arrived before state was 
ready', async () => {
+    const initialState = {
+      sqlLab: {
+        queries: {},
+        queryEditors: [{ id: 'editor-id' }],
+        tabHistory: ['editor-id'],
+      },
+      explore: { slice: { slice_id: 123 } },
+      charts: { '1': {}, '2': {} },
+      dashboardInfo: { id: 'dashboard-id' },
+    };
+    type DynamicStoreState = typeof initialState;
+    type DynamicStoreAction = { type: string };
+    const dynamicStore = createStore(
+      (state: DynamicStoreState = initialState, action: DynamicStoreAction) => 
{
+        if (action.type === 'SET_READY') {
+          return {
+            ...state,
+            sqlLab: {
+              ...state.sqlLab,
+              queries: { 'query-id': { sql: 'SELECT * FROM table' } },
+              queryEditors: [{ id: 'editor-id', latestQueryId: 'query-id' }],
+            },
+          };
+        }
+        return state;
+      },
+    );
+
+    render(
+      <Provider store={dynamicStore}>
+        <OAuth2RedirectMessage {...defaultProps} />
+      </Provider>,
+    );
+
+    // First signal arrives before the SQL Lab query state is populated;
+    // nothing dispatches and `handled` must NOT be flipped.
+    simulateBroadcastMessage({ tabId: 'tabId' });
+    expect(reRunQuery).not.toHaveBeenCalled();
+
+    // Query state becomes available, then the storage fallback signal fires.
+    act(() => {
+      dynamicStore.dispatch({ type: 'SET_READY' });

Review Comment:
   Fair, fixed in b0cc385: the test now asserts the BroadcastChannel mock and 
the storage listener spy both stay at a call count of 1 across the Redux 
dispatch, so a regression back to the old state-dependent deps would actually 
fail this test instead of sliding through on the final outcome alone.



-- 
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