diff --git a/src/components/tokenRetriever/LtiTokenRetriever.test.jsx b/src/components/tokenRetriever/LtiTokenRetriever.test.jsx index 35353dc..8f0b7fd 100644 --- a/src/components/tokenRetriever/LtiTokenRetriever.test.jsx +++ b/src/components/tokenRetriever/LtiTokenRetriever.test.jsx @@ -122,7 +122,28 @@ describe('LtiTokenRetriever Test Suite', () => { expect(await screen.findAllByText('Mock Child Element')).toBeDefined() expect(mockJwtFn).toHaveBeenCalledWith(jwt, mockServer) }) - + + it('Does not make multiple fetch calls inside StrictMode', async () => { + const search = `?token=1234` + vi.spyOn(window, 'location', 'get').mockReturnValue({search}) + mockJwtFn.mockClear() + let callCount = 0 + server.use( + http.post('http://server.test/token', () => { + callCount += 1 + return HttpResponse.json({jwt}) + }) + ) + render( + + +

Mock Child Element

+
+
+ ) + expect(await screen.findAllByText('Mock Child Element')).toBeDefined() + expect(callCount).toBe(1) + }) -}); \ No newline at end of file +}); diff --git a/src/components/tokenRetriever/LtiTokenRetriever.tsx b/src/components/tokenRetriever/LtiTokenRetriever.tsx index fabe64d..fcada26 100644 --- a/src/components/tokenRetriever/LtiTokenRetriever.tsx +++ b/src/components/tokenRetriever/LtiTokenRetriever.tsx @@ -4,7 +4,7 @@ import { Spinner } from '@instructure/ui-spinner'; import ErrorBillboard from "../errorBillboard/ErrorBillboard"; type TokenRetrieverState = { - loading: boolean + loading: boolean, error: string | null } @@ -28,10 +28,15 @@ type LtiTokenRetrieverProps = { export const LtiTokenRetriever = ({ ltiServer, handleJwt, children, location = window.location }: LtiTokenRetrieverProps) => { const [state, setState] = useState({ loading: true, - error: null + error: null, }); + // This is to prevent multiple loads of the token, especially when using in development. + // A token can only be retrieved once so the second request always fails. + const hasFetchedRef = useRef(false); useEffect(() => { + if (hasFetchedRef.current) return; + hasFetchedRef.current = true; const fetchToken = async () => { const token = getToken(); const server = getServer(); @@ -52,7 +57,7 @@ export const LtiTokenRetriever = ({ ltiServer, handleJwt, children, location = w const response = await fetch(`${server}/token`, { method: 'POST', - body: formData + body: formData, }); if (!response.ok) {