@@ -388,12 +388,84 @@ describe('useOffsetPaginatedQuery', () => {
388388 expect ( result . current . data ) . toBeDefined ( ) ;
389389 expect ( result . current . data ?. window . windowIndex ) . toBe ( 0 ) ;
390390
391- // Should have more pages available due to large time range
392- expect ( result . current . hasNextPage ) . toBe ( true ) ;
391+ // The only window has fewer rows than the requested limit.
392+ expect ( result . current . hasNextPage ) . toBe ( false ) ;
393393 } ) ;
394394 } ) ;
395395
396396 describe ( 'Pagination Within Time Windows' , ( ) => {
397+ it . each ( [ 'Timestamp DESC' , 'Timestamp ASC' ] ) (
398+ 'moves straight to the next window after a partial page (%s)' ,
399+ async orderBy => {
400+ const config = createMockChartConfig ( {
401+ orderBy,
402+ limit : { limit : 100 , offset : 0 } ,
403+ } ) ;
404+ mockReader . read
405+ . mockResolvedValueOnce ( {
406+ done : false ,
407+ value : [
408+ { json : ( ) => [ 'message' ] } ,
409+ { json : ( ) => [ 'String' ] } ,
410+ { json : ( ) => [ 'first window' ] } ,
411+ ] ,
412+ } )
413+ . mockResolvedValueOnce ( { done : true } ) ;
414+
415+ const { result } = renderHook ( ( ) => useOffsetPaginatedQuery ( config ) , {
416+ wrapper,
417+ } ) ;
418+ await waitFor ( ( ) => expect ( result . current . isLoading ) . toBe ( false ) ) ;
419+ expect ( result . current . data ?. data ) . toHaveLength ( 1 ) ;
420+ expect ( result . current . hasNextPage ) . toBe ( true ) ;
421+
422+ mockReader . read . mockResolvedValueOnce ( { done : true } ) ;
423+ await act ( async ( ) => {
424+ await result . current . fetchNextPage ( ) ;
425+ } ) ;
426+
427+ await waitFor ( ( ) => {
428+ expect ( result . current . data ?. window . windowIndex ) . toBe ( 1 ) ;
429+ } ) ;
430+ expect ( jest . mocked ( renderChartConfig ) . mock . calls [ 1 ] [ 0 ] ) . toMatchObject ( {
431+ limit : { limit : 100 , offset : 0 } ,
432+ } ) ;
433+ } ,
434+ ) ;
435+
436+ it . each ( [
437+ [ 'a search without windowing' , { orderBy : 'message DESC' } ] ,
438+ [ 'a query without LIMIT' , { orderBy : 'message DESC' , limit : undefined } ] ,
439+ [
440+ 'the final time window' ,
441+ {
442+ dateRange : [
443+ new Date ( '2024-01-01T00:00:00Z' ) ,
444+ new Date ( '2024-01-01T00:05:00Z' ) ,
445+ ] as [ Date , Date ] ,
446+ } ,
447+ ] ,
448+ ] ) ( 'stops after a partial page for %s' , async ( _name , overrides ) => {
449+ const config = createMockChartConfig ( overrides ) ;
450+ mockReader . read
451+ . mockResolvedValueOnce ( {
452+ done : false ,
453+ value : [
454+ { json : ( ) => [ 'message' ] } ,
455+ { json : ( ) => [ 'String' ] } ,
456+ { json : ( ) => [ 'only result' ] } ,
457+ ] ,
458+ } )
459+ . mockResolvedValueOnce ( { done : true } ) ;
460+
461+ const { result } = renderHook ( ( ) => useOffsetPaginatedQuery ( config ) , {
462+ wrapper,
463+ } ) ;
464+ await waitFor ( ( ) => expect ( result . current . isLoading ) . toBe ( false ) ) ;
465+ expect ( result . current . data ?. data ) . toHaveLength ( 1 ) ;
466+ expect ( result . current . hasNextPage ) . toBe ( false ) ;
467+ } ) ;
468+
397469 it ( 'should paginate within the same time window' , async ( ) => {
398470 const config = createMockChartConfig ( {
399471 limit : { limit : 2 , offset : 0 } ,
0 commit comments