@@ -13,7 +13,13 @@ import {
1313 skipToken ,
1414} from '..'
1515import { mockOnlineManagerIsOnline } from './utils'
16- import type { QueryCache , QueryFunction , QueryObserverOptions } from '..'
16+ import type {
17+ InfiniteData ,
18+ Query ,
19+ QueryCache ,
20+ QueryFunction ,
21+ QueryObserverOptions ,
22+ } from '..'
1723
1824describe ( 'queryClient' , ( ) => {
1925 let queryClient : QueryClient
@@ -1478,6 +1484,162 @@ describe('queryClient', () => {
14781484 } )
14791485 } )
14801486
1487+ test ( 'should throw when skipToken is provided and no cached data exists' , async ( ) => {
1488+ const key = queryKey ( )
1489+ const select = vi . fn (
1490+ ( data : { pages : Array < string > } ) => data . pages . length ,
1491+ )
1492+
1493+ await expect (
1494+ queryClient . infiniteQuery ( {
1495+ queryKey : key ,
1496+ queryFn : skipToken ,
1497+ initialPageParam : 0 ,
1498+ select,
1499+ } ) ,
1500+ ) . rejects . toThrowError ( )
1501+
1502+ expect ( select ) . not . toHaveBeenCalled ( )
1503+ } )
1504+
1505+ test ( 'should throw when enabled resolves true and skipToken are provided with no cached data' , async ( ) => {
1506+ await expect (
1507+ queryClient . infiniteQuery ( {
1508+ queryKey : queryKey ( ) ,
1509+ queryFn : skipToken ,
1510+ initialPageParam : 0 ,
1511+ enabled : true ,
1512+ } ) ,
1513+ ) . rejects . toThrowError ( )
1514+ } )
1515+
1516+ test ( 'should return cached data when enabled resolves false and skipToken are provided' , async ( ) => {
1517+ const key = queryKey ( )
1518+
1519+ queryClient . setQueryData ( key , {
1520+ pages : [ { value : 'cached-page' } ] ,
1521+ pageParams : [ 0 ] ,
1522+ } )
1523+
1524+ const result = await queryClient . infiniteQuery ( {
1525+ queryKey : key ,
1526+ queryFn : skipToken ,
1527+ initialPageParam : 0 ,
1528+ enabled : ( ) => false ,
1529+ select : ( data : { pages : Array < { value : string } > } ) =>
1530+ data . pages [ 0 ] ?. value . length ,
1531+ } )
1532+
1533+ expect ( result ) . toBe ( 'cached-page' . length )
1534+ } )
1535+
1536+ test ( 'should fetch when enabled callback returns true and cache is stale' , async ( ) => {
1537+ const key = queryKey ( )
1538+
1539+ queryClient . setQueryData ( key , {
1540+ pages : [ 'old-page' ] ,
1541+ pageParams : [ 0 ] ,
1542+ } )
1543+
1544+ await vi . advanceTimersByTimeAsync ( 1 )
1545+
1546+ const queryFn = vi . fn ( ( { pageParam } : { pageParam : number } ) =>
1547+ Promise . resolve ( `new-page-${ String ( pageParam ) } ` ) ,
1548+ )
1549+
1550+ const result = await queryClient . infiniteQuery ( {
1551+ queryKey : key ,
1552+ queryFn,
1553+ initialPageParam : 0 ,
1554+ enabled : ( ) => true ,
1555+ staleTime : 0 ,
1556+ } )
1557+
1558+ expect ( result ) . toEqual ( {
1559+ pages : [ 'new-page-0' ] ,
1560+ pageParams : [ 0 ] ,
1561+ } )
1562+ expect ( queryFn ) . toHaveBeenCalledTimes ( 1 )
1563+ } )
1564+
1565+ test ( 'should evaluate staleTime callback and refetch when it returns stale' , async ( ) => {
1566+ const key = queryKey ( )
1567+
1568+ queryClient . setQueryData ( key , {
1569+ pages : [ { value : 'old-page' , staleTime : 0 } ] ,
1570+ pageParams : [ 0 ] ,
1571+ } )
1572+
1573+ await vi . advanceTimersByTimeAsync ( 1 )
1574+
1575+ const queryFn = vi . fn ( ( { pageParam } : { pageParam : number } ) =>
1576+ Promise . resolve ( {
1577+ value : `new-page-${ String ( pageParam ) } ` ,
1578+ staleTime : 0 ,
1579+ } ) ,
1580+ )
1581+ const staleTimeSpy = vi . fn ( )
1582+ const staleTime = (
1583+ query : Query <
1584+ { value : string ; staleTime : number } ,
1585+ Error ,
1586+ InfiniteData < { value : string ; staleTime : number } , number >
1587+ > ,
1588+ ) => {
1589+ staleTimeSpy ( )
1590+ return query . state . data ?. pages [ 0 ] ?. staleTime ?? 0
1591+ }
1592+
1593+ const result = await queryClient . infiniteQuery ( {
1594+ queryKey : key ,
1595+ queryFn,
1596+ initialPageParam : 0 ,
1597+ staleTime,
1598+ } )
1599+
1600+ expect ( result ) . toEqual ( {
1601+ pages : [ { value : 'new-page-0' , staleTime : 0 } ] ,
1602+ pageParams : [ 0 ] ,
1603+ } )
1604+ expect ( staleTimeSpy ) . toHaveBeenCalled ( )
1605+ expect ( queryFn ) . toHaveBeenCalledTimes ( 1 )
1606+ } )
1607+
1608+ test ( 'should read from cache with static staleTime even if invalidated' , async ( ) => {
1609+ const key = queryKey ( )
1610+
1611+ const queryFn = vi . fn ( ( { pageParam } : { pageParam : number } ) =>
1612+ Promise . resolve ( { value : `fetched-${ String ( pageParam ) } ` } ) ,
1613+ )
1614+ const first = await queryClient . infiniteQuery ( {
1615+ queryKey : key ,
1616+ queryFn,
1617+ initialPageParam : 0 ,
1618+ staleTime : 'static' ,
1619+ } )
1620+
1621+ expect ( first ) . toEqual ( {
1622+ pages : [ { value : 'fetched-0' } ] ,
1623+ pageParams : [ 0 ] ,
1624+ } )
1625+ expect ( queryFn ) . toHaveBeenCalledTimes ( 1 )
1626+
1627+ await queryClient . invalidateQueries ( {
1628+ queryKey : key ,
1629+ refetchType : 'none' ,
1630+ } )
1631+
1632+ const second = await queryClient . infiniteQuery ( {
1633+ queryKey : key ,
1634+ queryFn,
1635+ initialPageParam : 0 ,
1636+ staleTime : 'static' ,
1637+ } )
1638+
1639+ expect ( queryFn ) . toHaveBeenCalledTimes ( 1 )
1640+ expect ( second ) . toBe ( first )
1641+ } )
1642+
14811643 test ( 'should apply select to infinite query data' , async ( ) => {
14821644 const key = queryKey ( )
14831645
0 commit comments