From fd4c002536bc3ec50b4fbf74f4c63a5ea6a5242a Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 8 Mar 2024 10:01:52 -0700 Subject: [PATCH 1/2] Add tests to useBackgroundQuery to demonstrate intended behavior --- .../__tests__/useBackgroundQuery.test.tsx | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx index ac7477d51f7..f9f934cb392 100644 --- a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx +++ b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx @@ -446,6 +446,77 @@ it("auto resubscribes when mounting useReadQuery after naturally disposed by use await expect(Profiler).not.toRerender({ timeout: 50 }); }); +it("disposes of the queryRef when unmounting before it is used by useReadQuery", async () => { + const { query, mocks } = setupSimpleCase(); + const client = new ApolloClient({ + link: new MockLink(mocks), + cache: new InMemoryCache(), + }); + + const Profiler = createDefaultProfiler(); + + function App() { + useTrackRenders(); + useBackgroundQuery(query); + + return null; + } + + const { unmount } = renderWithClient(, { client, wrapper: Profiler }); + + expect(client.getObservableQueries().size).toBe(1); + expect(client).toHaveSuspenseCacheEntryUsing(query); + + { + const { renderedComponents } = await Profiler.takeRender(); + + expect(renderedComponents).toStrictEqual([App]); + } + + unmount(); + await wait(0); + + expect(client.getObservableQueries().size).toBe(0); + expect(client).not.toHaveSuspenseCacheEntryUsing(query); +}); + +it("does not prematurely dispose of the queryRef when using strict mode", async () => { + const { query, mocks } = setupSimpleCase(); + const client = new ApolloClient({ + link: new MockLink(mocks), + cache: new InMemoryCache(), + }); + + const Profiler = createDefaultProfiler(); + + function App() { + useTrackRenders(); + useBackgroundQuery(query); + + return null; + } + + renderWithClient(, { + client, + wrapper: ({ children }) => ( + + {children} + + ), + }); + + { + const { renderedComponents } = await Profiler.takeRender(); + + expect(renderedComponents).toStrictEqual([App]); + } + + await wait(10); + + expect(client.getObservableQueries().size).toBe(1); + expect(client).toHaveSuspenseCacheEntryUsing(query); +}); + it("allows the client to be overridden", async () => { const { query } = setupSimpleCase(); From d49341d478ec562be90c62c93ff344519d656075 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 8 Mar 2024 10:13:12 -0700 Subject: [PATCH 2/2] Add failing test for changing variables without consuming queryRef --- .../__tests__/useBackgroundQuery.test.tsx | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx index f9f934cb392..54ad243d5ba 100644 --- a/src/react/hooks/__tests__/useBackgroundQuery.test.tsx +++ b/src/react/hooks/__tests__/useBackgroundQuery.test.tsx @@ -480,6 +480,51 @@ it("disposes of the queryRef when unmounting before it is used by useReadQuery", expect(client).not.toHaveSuspenseCacheEntryUsing(query); }); +it("disposes of old queryRefs when changing variables before the queryRef is used by useReadQuery", async () => { + const { query, mocks } = setupVariablesCase(); + const client = new ApolloClient({ + link: new MockLink(mocks), + cache: new InMemoryCache(), + }); + + const Profiler = createDefaultProfiler(); + + function App({ id }: { id: string }) { + useTrackRenders(); + useBackgroundQuery(query, { variables: { id } }); + + return null; + } + + const { rerender } = renderWithClient(, { + client, + wrapper: Profiler, + }); + + expect(client.getObservableQueries().size).toBe(1); + expect(client).toHaveSuspenseCacheEntryUsing(query, { + variables: { id: "1" }, + }); + + { + const { renderedComponents } = await Profiler.takeRender(); + + expect(renderedComponents).toStrictEqual([App]); + } + + rerender(); + + await wait(0); + + expect(client.getObservableQueries().size).toBe(1); + expect(client).toHaveSuspenseCacheEntryUsing(query, { + variables: { id: "2" }, + }); + expect(client).not.toHaveSuspenseCacheEntryUsing(query, { + variables: { id: "1" }, + }); +}); + it("does not prematurely dispose of the queryRef when using strict mode", async () => { const { query, mocks } = setupSimpleCase(); const client = new ApolloClient({