11import { render , screen } from '@testing-library/react' ;
22import userEvent from '@testing-library/user-event' ;
3- import { describe , expect , it , vi } from 'vitest' ;
3+ import { beforeAll , describe , expect , it , vi } from 'vitest' ;
44import { DataTable } from '../data-table' ;
55import styles from '../data-table.module.css' ;
66import { DataTableColumnDef } from '../data-table.types' ;
77
8+ beforeAll ( ( ) => {
9+ global . IntersectionObserver = vi . fn ( ) . mockImplementation ( ( ) => ( {
10+ observe : vi . fn ( ) ,
11+ unobserve : vi . fn ( ) ,
12+ disconnect : vi . fn ( )
13+ } ) ) ;
14+ } ) ;
15+
816interface TestData {
917 id : number ;
1018 name : string ;
@@ -43,7 +51,11 @@ describe('DataTable', () => {
4351 describe ( 'Basic Rendering' , ( ) => {
4452 it ( 'renders data table with content' , ( ) => {
4553 render (
46- < DataTable data = { mockData } columns = { mockColumns } >
54+ < DataTable
55+ data = { mockData }
56+ columns = { mockColumns }
57+ defaultSort = { { name : 'name' , order : 'asc' } }
58+ >
4759 < DataTable . Content />
4860 </ DataTable >
4961 ) ;
@@ -58,7 +70,11 @@ describe('DataTable', () => {
5870 } ;
5971
6072 render (
61- < DataTable data = { mockData } columns = { mockColumns } >
73+ < DataTable
74+ data = { mockData }
75+ columns = { mockColumns }
76+ defaultSort = { { name : 'name' , order : 'asc' } }
77+ >
6278 < TestComponent />
6379 </ DataTable >
6480 ) ;
@@ -68,7 +84,11 @@ describe('DataTable', () => {
6884
6985 it ( 'renders with empty data' , ( ) => {
7086 render (
71- < DataTable data = { [ ] } columns = { mockColumns } >
87+ < DataTable
88+ data = { [ ] }
89+ columns = { mockColumns }
90+ defaultSort = { { name : 'name' , order : 'asc' } }
91+ >
7292 < DataTable . Content />
7393 </ DataTable >
7494 ) ;
@@ -80,7 +100,11 @@ describe('DataTable', () => {
80100 describe ( 'Data Display' , ( ) => {
81101 it ( 'displays table data in content' , ( ) => {
82102 render (
83- < DataTable data = { mockData } columns = { mockColumns } >
103+ < DataTable
104+ data = { mockData }
105+ columns = { mockColumns }
106+ defaultSort = { { name : 'name' , order : 'asc' } }
107+ >
84108 < DataTable . Content />
85109 </ DataTable >
86110 ) ;
@@ -94,7 +118,11 @@ describe('DataTable', () => {
94118
95119 it ( 'displays column headers' , ( ) => {
96120 render (
97- < DataTable data = { mockData } columns = { mockColumns } >
121+ < DataTable
122+ data = { mockData }
123+ columns = { mockColumns }
124+ defaultSort = { { name : 'name' , order : 'asc' } }
125+ >
98126 < DataTable . Content />
99127 </ DataTable >
100128 ) ;
@@ -114,6 +142,7 @@ describe('DataTable', () => {
114142 < DataTable
115143 data = { mockData }
116144 columns = { mockColumns }
145+ defaultSort = { { name : 'name' , order : 'asc' } }
117146 onRowClick = { onRowClick }
118147 >
119148 < DataTable . Content />
@@ -129,7 +158,11 @@ describe('DataTable', () => {
129158 describe ( 'Component Composition' , ( ) => {
130159 it ( 'renders with toolbar' , ( ) => {
131160 const { container } = render (
132- < DataTable data = { mockData } columns = { mockColumns } >
161+ < DataTable
162+ data = { mockData }
163+ columns = { mockColumns }
164+ defaultSort = { { name : 'name' , order : 'asc' } }
165+ >
133166 < DataTable . Toolbar />
134167 < DataTable . Content />
135168 </ DataTable >
@@ -142,7 +175,11 @@ describe('DataTable', () => {
142175
143176 it ( 'renders with search' , ( ) => {
144177 render (
145- < DataTable data = { mockData } columns = { mockColumns } >
178+ < DataTable
179+ data = { mockData }
180+ columns = { mockColumns }
181+ defaultSort = { { name : 'name' , order : 'asc' } }
182+ >
146183 < DataTable . Search />
147184 < DataTable . Content />
148185 </ DataTable >
@@ -409,4 +446,133 @@ describe('DataTable', () => {
409446 expect ( screen . getByText ( 'John Doe' ) ) . toBeInTheDocument ( ) ;
410447 } ) ;
411448 } ) ;
449+
450+ describe ( 'Display Settings Reset' , ( ) => {
451+ const columnsWithSortAndGroup : DataTableColumnDef < TestData , unknown > [ ] = [
452+ {
453+ id : 'name' ,
454+ accessorKey : 'name' ,
455+ header : 'Name' ,
456+ cell : ( { getValue } ) => getValue ( ) ,
457+ enableSorting : true ,
458+ enableGrouping : true
459+ } ,
460+ {
461+ id : 'email' ,
462+ accessorKey : 'email' ,
463+ header : 'Email' ,
464+ cell : ( { getValue } ) => getValue ( ) ,
465+ enableSorting : true
466+ } ,
467+ {
468+ id : 'status' ,
469+ accessorKey : 'status' ,
470+ header : 'Status' ,
471+ cell : ( { getValue } ) => getValue ( ) ,
472+ enableSorting : true ,
473+ enableGrouping : true
474+ }
475+ ] ;
476+
477+ it ( 'resets sort and group to defaults on reset click' , async ( ) => {
478+ const onTableQueryChange = vi . fn ( ) ;
479+ const user = userEvent . setup ( ) ;
480+
481+ render (
482+ < DataTable
483+ data = { mockData }
484+ columns = { columnsWithSortAndGroup }
485+ defaultSort = { { name : 'name' , order : 'asc' } }
486+ mode = 'server'
487+ onTableQueryChange = { onTableQueryChange }
488+ query = { {
489+ sort : [ { name : 'email' , order : 'desc' } ] ,
490+ group_by : [ 'status' ]
491+ } }
492+ >
493+ < DataTable . Toolbar />
494+ < DataTable . Content />
495+ </ DataTable >
496+ ) ;
497+
498+ // Open Display popover and click reset
499+ await user . click ( screen . getByText ( 'Display' ) ) ;
500+ await user . click ( screen . getByText ( 'Reset to default' ) ) ;
501+
502+ // Verify onTableQueryChange was called with default sort and no group
503+ expect ( onTableQueryChange ) . toHaveBeenLastCalledWith (
504+ expect . objectContaining ( {
505+ sort : [ { name : 'name' , order : 'asc' } ] ,
506+ group_by : [ ]
507+ } )
508+ ) ;
509+ } ) ;
510+
511+ it ( 'does not show zero state when sort or group changes in client mode' , ( ) => {
512+ render (
513+ < DataTable
514+ data = { mockData }
515+ columns = { columnsWithSortAndGroup }
516+ defaultSort = { { name : 'name' , order : 'asc' } }
517+ mode = 'client'
518+ query = { {
519+ sort : [ { name : 'email' , order : 'desc' } ] ,
520+ group_by : [ 'status' ]
521+ } }
522+ >
523+ < DataTable . Content
524+ zeroState = { < div data-testid = 'zero-state' > No data</ div > }
525+ emptyState = { < div data-testid = 'empty-state' > No results</ div > }
526+ />
527+ </ DataTable >
528+ ) ;
529+
530+ // Data should still be visible, not zero/empty state
531+ expect ( screen . getByText ( 'John Doe' ) ) . toBeInTheDocument ( ) ;
532+ expect ( screen . queryByTestId ( 'zero-state' ) ) . not . toBeInTheDocument ( ) ;
533+ expect ( screen . queryByTestId ( 'empty-state' ) ) . not . toBeInTheDocument ( ) ;
534+ } ) ;
535+
536+ it ( 'shows empty state when sort is changed and no data' , ( ) => {
537+ render (
538+ < DataTable
539+ data = { [ ] }
540+ columns = { columnsWithSortAndGroup }
541+ defaultSort = { { name : 'name' , order : 'asc' } }
542+ query = { {
543+ sort : [ { name : 'email' , order : 'desc' } ]
544+ } }
545+ >
546+ < DataTable . Content
547+ zeroState = { < div data-testid = 'zero-state' > No data</ div > }
548+ emptyState = { < div data-testid = 'empty-state' > No results</ div > }
549+ />
550+ </ DataTable >
551+ ) ;
552+
553+ expect ( screen . getByTestId ( 'empty-state' ) ) . toBeInTheDocument ( ) ;
554+ expect ( screen . queryByTestId ( 'zero-state' ) ) . not . toBeInTheDocument ( ) ;
555+ } ) ;
556+
557+ it ( 'shows empty state when group is changed and no data' , ( ) => {
558+ render (
559+ < DataTable
560+ data = { [ ] }
561+ columns = { columnsWithSortAndGroup }
562+ defaultSort = { { name : 'name' , order : 'asc' } }
563+ query = { {
564+ group_by : [ 'status' ]
565+ } }
566+ >
567+ < DataTable . Content
568+ zeroState = { < div data-testid = 'zero-state' > No data</ div > }
569+ emptyState = { < div data-testid = 'empty-state' > No results</ div > }
570+ />
571+ </ DataTable >
572+ ) ;
573+
574+ expect ( screen . getByTestId ( 'empty-state' ) ) . toBeInTheDocument ( ) ;
575+ expect ( screen . queryByTestId ( 'zero-state' ) ) . not . toBeInTheDocument ( ) ;
576+ } ) ;
577+ } ) ;
412578} ) ;
0 commit comments