From 9944ba4db4863e4523a389c67583e2b6cfaca57c Mon Sep 17 00:00:00 2001 From: Florian Ellis Date: Wed, 8 May 2024 22:28:43 +0200 Subject: [PATCH] fix(replays): fix 'clearQueryCache' method in 'useReplayData' hook Fix a bug currently causing the 'clearQueryCache' method defined in 'static/app/utils/replays/hooks/useReplayData.tsx' to have no effect (extra arrow function declaration). Add a unit test to cover this behavior of the custom hook. --- .../replays/hooks/useReplayData.spec.tsx | 66 ++++++++++++++++++- .../app/utils/replays/hooks/useReplayData.tsx | 28 ++++---- 2 files changed, 76 insertions(+), 18 deletions(-) diff --git a/static/app/utils/replays/hooks/useReplayData.spec.tsx b/static/app/utils/replays/hooks/useReplayData.spec.tsx index 2547427106a2fe..6b1f57f319eef7 100644 --- a/static/app/utils/replays/hooks/useReplayData.spec.tsx +++ b/static/app/utils/replays/hooks/useReplayData.spec.tsx @@ -32,10 +32,14 @@ jest.mocked(useProjects).mockReturnValue({ placeholders: [], }); +const mockInvalidateQueries = jest.fn(); + function wrapper({children}: {children?: ReactNode}) { - return ( - {children} - ); + const queryClient = makeTestQueryClient(); + + queryClient.invalidateQueries = mockInvalidateQueries; + + return {children}; } function getMockReplayRecord(replayRecord?: Partial) { @@ -59,6 +63,7 @@ function getMockReplayRecord(replayRecord?: Partial) { describe('useReplayData', () => { beforeEach(() => { MockApiClient.clearMockResponses(); + mockInvalidateQueries.mockClear(); }); it('should hydrate the replayRecord', async () => { @@ -505,4 +510,59 @@ describe('useReplayData', () => { ) ); }); + + it("should invalidate queries when result's 'onRetry' function is called", async () => { + const {mockReplayResponse} = getMockReplayRecord({ + count_errors: 0, + count_segments: 0, + error_ids: [], + }); + + const replayId = mockReplayResponse.id; + + MockApiClient.addMockResponse({ + url: `/organizations/${organization.slug}/replays/${replayId}/`, + body: {data: mockReplayResponse}, + }); + + MockApiClient.addMockResponse({ + url: `/organizations/${organization.slug}/replays-events-meta/`, + body: { + data: [], + }, + headers: { + Link: [ + '; rel="previous"; results="false"; cursor="0:1:0"', + '; rel="next"; results="false"; cursor="0:1:0"', + ].join(','), + }, + }); + + const {result} = renderHook(useReplayData, { + wrapper, + initialProps: { + replayId, + orgSlug: organization.slug, + }, + }); + + // We need this 'await waitFor()' for the following assertions to pass: + await waitFor(() => { + expect(result.current).toBeTruthy(); + }); + + result.current.onRetry(); + + expect(mockInvalidateQueries).toHaveBeenCalledWith({ + queryKey: [`/organizations/${organization.slug}/replays/${replayId}/`], + }); + expect(mockInvalidateQueries).toHaveBeenCalledWith({ + queryKey: [ + `/projects/${organization.slug}/${project.slug}/replays/${replayId}/recording-segments/`, + ], + }); + expect(mockInvalidateQueries).toHaveBeenCalledWith({ + queryKey: [`/organizations/${organization.slug}/replays-events-meta/`], + }); + }); }); diff --git a/static/app/utils/replays/hooks/useReplayData.tsx b/static/app/utils/replays/hooks/useReplayData.tsx index ba6d13168fe9ca..d89ce43ede58cc 100644 --- a/static/app/utils/replays/hooks/useReplayData.tsx +++ b/static/app/utils/replays/hooks/useReplayData.tsx @@ -214,21 +214,19 @@ function useReplayData({ }); const clearQueryCache = useCallback(() => { - () => { - queryClient.invalidateQueries({ - queryKey: [`/organizations/${orgSlug}/replays/${replayId}/`], - }); - queryClient.invalidateQueries({ - queryKey: [ - `/projects/${orgSlug}/${projectSlug}/replays/${replayId}/recording-segments/`, - ], - }); - // The next one isn't optimized - // This statement will invalidate the cache of fetched error events for all replayIds - queryClient.invalidateQueries({ - queryKey: [`/organizations/${orgSlug}/replays-events-meta/`], - }); - }; + queryClient.invalidateQueries({ + queryKey: [`/organizations/${orgSlug}/replays/${replayId}/`], + }); + queryClient.invalidateQueries({ + queryKey: [ + `/projects/${orgSlug}/${projectSlug}/replays/${replayId}/recording-segments/`, + ], + }); + // The next one isn't optimized + // This statement will invalidate the cache of fetched error events for all replayIds + queryClient.invalidateQueries({ + queryKey: [`/organizations/${orgSlug}/replays-events-meta/`], + }); }, [orgSlug, replayId, projectSlug, queryClient]); return useMemo(() => {