Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
264 changes: 135 additions & 129 deletions packages/query-core/src/__tests__/hydration.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1387,106 +1387,109 @@ describe('dehydration and rehydration', () => {
})

it('should preserve queryType for infinite queries during hydration', async () => {
const key = queryKey()
const queryCache = new QueryCache()
const queryClient = new QueryClient({ queryCache })

await vi.waitFor(() =>
queryClient.prefetchInfiniteQuery({
queryKey: ['infinite'],
queryFn: async ({ pageParam }) =>
sleep(0).then(() => ({
items: [`page-${pageParam}`],
nextCursor: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: {
items: Array<string>
nextCursor: number
}) => lastPage.nextCursor,
}),
)
const prefetchPromise = queryClient.prefetchInfiniteQuery({
queryKey: key,
queryFn: ({ pageParam }) =>
sleep(10).then(() => ({
items: [`page-${pageParam}`],
nextCursor: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: {
items: Array<string>
nextCursor: number
}) => lastPage.nextCursor,
})
await vi.advanceTimersByTimeAsync(10)
await prefetchPromise

const dehydrated = dehydrate(queryClient)

const infiniteQueryState = dehydrated.queries.find(
(q) => q.queryKey[0] === 'infinite',
(q) => q.queryKey[0] === key[0],
)
expect(infiniteQueryState?.queryType).toBe('infinite')

const hydrationCache = new QueryCache()
const hydrationClient = new QueryClient({ queryCache: hydrationCache })
hydrate(hydrationClient, dehydrated)

const hydratedQuery = hydrationCache.find({ queryKey: ['infinite'] })
const hydratedQuery = hydrationCache.find({ queryKey: key })
expect(hydratedQuery?.state.data).toBeDefined()
expect(hydratedQuery?.state.data).toHaveProperty('pages')
expect(hydratedQuery?.state.data).toHaveProperty('pageParams')
expect((hydratedQuery?.state.data as any).pages).toHaveLength(1)
})

it('should attach infiniteQueryBehavior during hydration', async () => {
const key = queryKey()
const queryCache = new QueryCache()
const queryClient = new QueryClient({ queryCache })

await vi.waitFor(() =>
queryClient.prefetchInfiniteQuery({
queryKey: ['infinite-with-behavior'],
queryFn: async ({ pageParam }) =>
sleep(0).then(() => ({
data: `page-${pageParam}`,
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { data: string; next: number }) =>
lastPage.next,
}),
)
const prefetchPromise = queryClient.prefetchInfiniteQuery({
queryKey: key,
queryFn: ({ pageParam }) =>
sleep(10).then(() => ({
data: `page-${pageParam}`,
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { data: string; next: number }) =>
lastPage.next,
})
await vi.advanceTimersByTimeAsync(10)
await prefetchPromise

const dehydrated = dehydrate(queryClient)

const hydrationCache = new QueryCache()
const hydrationClient = new QueryClient({ queryCache: hydrationCache })
hydrate(hydrationClient, dehydrated)

const result = await vi.waitFor(() =>
hydrationClient.fetchInfiniteQuery({
queryKey: ['infinite-with-behavior'],
queryFn: async ({ pageParam }) =>
sleep(0).then(() => ({
data: `page-${pageParam}`,
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { data: string; next: number }) =>
lastPage.next,
}),
)
const resultPromise = hydrationClient.fetchInfiniteQuery({
queryKey: key,
queryFn: ({ pageParam }) =>
sleep(10).then(() => ({
data: `page-${pageParam}`,
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { data: string; next: number }) =>
lastPage.next,
})
await vi.advanceTimersByTimeAsync(10)
const result = await resultPromise

expect(result.pages).toHaveLength(1)
expect(result.pageParams).toHaveLength(1)
})

it('should restore infinite query type through dehydrate and hydrate cycle', async () => {
const key = queryKey()
const serverClient = new QueryClient({ queryCache: new QueryCache() })

await vi.waitFor(() =>
serverClient.prefetchInfiniteQuery({
queryKey: ['infinite-type-restore'],
queryFn: async ({ pageParam }) =>
sleep(0).then(() => ({
items: [`item-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
}),
)
const prefetchPromise = serverClient.prefetchInfiniteQuery({
queryKey: key,
queryFn: ({ pageParam }) =>
sleep(10).then(() => ({
items: [`item-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
})
await vi.advanceTimersByTimeAsync(10)
await prefetchPromise

const dehydrated = dehydrate(serverClient)

const dehydratedQuery = dehydrated.queries.find(
(q) => q.queryKey[0] === 'infinite-type-restore',
(q) => q.queryKey[0] === key[0],
)
expect(dehydratedQuery?.queryType).toBe('infinite')

Expand All @@ -1495,27 +1498,28 @@ describe('dehydration and rehydration', () => {
hydrate(clientClient, dehydrated)

const hydratedQuery = clientCache.find({
queryKey: ['infinite-type-restore'],
queryKey: key,
})
expect(hydratedQuery?.queryType).toBe('infinite')
})

it('should preserve pages structure when refetching infinite query after hydration', async () => {
const key = queryKey()
const serverClient = new QueryClient({ queryCache: new QueryCache() })

await vi.waitFor(() =>
serverClient.prefetchInfiniteQuery({
queryKey: ['refetch'],
queryFn: async ({ pageParam }) =>
sleep(0).then(() => ({
items: [`page-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
}),
)
const prefetchPromise = serverClient.prefetchInfiniteQuery({
queryKey: key,
queryFn: ({ pageParam }) =>
sleep(10).then(() => ({
items: [`page-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
})
await vi.advanceTimersByTimeAsync(10)
await prefetchPromise

const dehydrated = dehydrate(serverClient)

Expand All @@ -1526,23 +1530,23 @@ describe('dehydration and rehydration', () => {
const beforeRefetch = clientClient.getQueryData<{
pages: Array<{ items: Array<string>; next: number }>
pageParams: Array<unknown>
}>(['refetch'])
}>(key)
expect(beforeRefetch?.pages).toHaveLength(1)
expect(beforeRefetch?.pageParams).toHaveLength(1)

const result = await vi.waitFor(() =>
clientClient.fetchInfiniteQuery({
queryKey: ['refetch'],
queryFn: async ({ pageParam }) =>
sleep(0).then(() => ({
items: [`page-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
}),
)
const resultPromise = clientClient.fetchInfiniteQuery({
queryKey: key,
queryFn: ({ pageParam }) =>
sleep(10).then(() => ({
items: [`page-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
})
await vi.advanceTimersByTimeAsync(10)
const result = await resultPromise

expect(result).toHaveProperty('pages')
expect(result).toHaveProperty('pageParams')
Expand All @@ -1552,52 +1556,54 @@ describe('dehydration and rehydration', () => {
})

it('should retain infinite query type after subsequent setOptions calls', async () => {
const key = queryKey()
const serverClient = new QueryClient({ queryCache: new QueryCache() })

await vi.waitFor(() =>
serverClient.prefetchInfiniteQuery({
queryKey: ['infinite-setoptions-guard'],
queryFn: async ({ pageParam }) =>
sleep(0).then(() => ({
data: `p${pageParam}`,
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { data: string; next: number }) =>
lastPage.next,
}),
)
const prefetchPromise = serverClient.prefetchInfiniteQuery({
queryKey: key,
queryFn: ({ pageParam }) =>
sleep(10).then(() => ({
data: `p${pageParam}`,
next: pageParam + 1,
})),
initialPageParam: 0,
getNextPageParam: (lastPage: { data: string; next: number }) =>
lastPage.next,
})
await vi.advanceTimersByTimeAsync(10)
await prefetchPromise

const dehydrated = dehydrate(serverClient)

const clientCache = new QueryCache()
const clientClient = new QueryClient({ queryCache: clientCache })
hydrate(clientClient, dehydrated)

const query = clientCache.find({ queryKey: ['infinite-setoptions-guard'] })!
const query = clientCache.find({ queryKey: key })!
expect(query.queryType).toBe('infinite')

query.setOptions({ queryKey: ['infinite-setoptions-guard'] })
query.setOptions({ queryKey: key })
expect(query.queryType).toBe('infinite')
})

it('should restore all pages when refetching multi-page infinite query after hydration', async () => {
const key = queryKey()
const serverClient = new QueryClient({ queryCache: new QueryCache() })

await vi.waitFor(() =>
serverClient.prefetchInfiniteQuery({
queryKey: ['infinite-multipage-restore'],
queryFn: async ({ pageParam }) =>
sleep(0).then(() => ({
items: [`item-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
pages: 2,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
}),
)
const prefetchPromise = serverClient.prefetchInfiniteQuery({
queryKey: key,
queryFn: ({ pageParam }) =>
sleep(10).then(() => ({
items: [`item-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
pages: 2,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
})
await vi.advanceTimersByTimeAsync(20)
await prefetchPromise

const dehydrated = dehydrate(serverClient)

Expand All @@ -1608,23 +1614,23 @@ describe('dehydration and rehydration', () => {
const beforeRefetch = clientClient.getQueryData<{
pages: Array<unknown>
pageParams: Array<unknown>
}>(['infinite-multipage-restore'])
}>(key)
expect(beforeRefetch?.pages).toHaveLength(2)

const result = await vi.waitFor(() =>
clientClient.fetchInfiniteQuery({
queryKey: ['infinite-multipage-restore'],
queryFn: async ({ pageParam }) =>
sleep(0).then(() => ({
items: [`item-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
pages: 2,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
}),
)
const resultPromise = clientClient.fetchInfiniteQuery({
queryKey: key,
queryFn: ({ pageParam }) =>
sleep(10).then(() => ({
items: [`item-${pageParam}`],
next: pageParam + 1,
})),
initialPageParam: 0,
pages: 2,
getNextPageParam: (lastPage: { items: Array<string>; next: number }) =>
lastPage.next,
})
await vi.advanceTimersByTimeAsync(20)
const result = await resultPromise

expect(result.pages).toHaveLength(2)
expect(result.pageParams).toHaveLength(2)
Expand Down
Loading