11import { describe , it , expect , vi , beforeEach , afterEach } from 'vitest' ;
2- import { render , screen , fireEvent } from '@testing-library/react' ;
2+ import { render , screen , fireEvent , act } from '@testing-library/react' ;
33import { ExpertiseCard } from './ExpertiseCard' ;
44import type { ExpertiseItem } from '@/data/expertise' ;
55
@@ -10,24 +10,39 @@ const mockItem: ExpertiseItem = {
1010 skills : [ 'PagerDuty' , 'Runbooks' , 'Blameless Culture' ] ,
1111} ;
1212
13+ const noop = ( ) => { } ;
14+
1315describe ( 'ExpertiseCard' , ( ) => {
16+ beforeEach ( ( ) => {
17+ vi . useFakeTimers ( ) ;
18+ } ) ;
19+
20+ afterEach ( ( ) => {
21+ vi . useRealTimers ( ) ;
22+ } ) ;
23+
1424 it ( 'renders the title' , ( ) => {
15- render ( < ExpertiseCard item = { mockItem } isExpanded = { false } onExpand = { ( ) => { } } /> ) ;
25+ render ( < ExpertiseCard item = { mockItem } isExpanded = { false } onExpand = { noop } onCollapse = { noop } /> ) ;
1626 expect ( screen . getByText ( 'Incident Management' ) ) . toBeInTheDocument ( ) ;
1727 } ) ;
1828
1929 it ( 'shows description when expanded' , ( ) => {
20- render ( < ExpertiseCard item = { mockItem } isExpanded = { true } onExpand = { ( ) => { } } /> ) ;
30+ render ( < ExpertiseCard item = { mockItem } isExpanded = { true } onExpand = { noop } onCollapse = { noop } /> ) ;
2131 expect ( screen . getByText ( mockItem . description ) ) . toBeInTheDocument ( ) ;
2232 } ) ;
2333
24- it ( 'calls onExpand on mouse enter' , ( ) => {
34+ it ( 'calls onExpand after delay on mouse enter' , ( ) => {
2535 const onExpand = vi . fn ( ) ;
26- render ( < ExpertiseCard item = { mockItem } isExpanded = { false } onExpand = { onExpand } /> ) ;
36+ render ( < ExpertiseCard item = { mockItem } isExpanded = { false } onExpand = { onExpand } onCollapse = { noop } /> ) ;
2737
2838 const card = screen . getByText ( 'Incident Management' ) . closest ( 'div[tabindex]' ) ;
2939 if ( card ) {
3040 fireEvent . mouseEnter ( card ) ;
41+ expect ( onExpand ) . not . toHaveBeenCalled ( ) ; // Not called immediately
42+
43+ act ( ( ) => {
44+ vi . advanceTimersByTime ( 1000 ) ; // EXPAND_DELAY
45+ } ) ;
3146 expect ( onExpand ) . toHaveBeenCalled ( ) ;
3247 }
3348 } ) ;
@@ -41,13 +56,18 @@ describe('ExpertiseCard', () => {
4156 delete ( window as unknown as { gtag ?: unknown } ) . gtag ;
4257 } ) ;
4358
44- it ( 'fires expertise_card_expand event on first hover when not expanded' , ( ) => {
59+ it ( 'fires expertise_card_expand event after hover delay when not expanded' , ( ) => {
4560 const onExpand = vi . fn ( ) ;
46- render ( < ExpertiseCard item = { mockItem } isExpanded = { false } onExpand = { onExpand } /> ) ;
61+ render ( < ExpertiseCard item = { mockItem } isExpanded = { false } onExpand = { onExpand } onCollapse = { noop } /> ) ;
4762
4863 const card = screen . getByText ( 'Incident Management' ) . closest ( 'div[tabindex]' ) ;
4964 if ( card ) {
5065 fireEvent . mouseEnter ( card ) ;
66+ expect ( window . gtag ) . not . toHaveBeenCalled ( ) ; // Not immediate
67+
68+ act ( ( ) => {
69+ vi . advanceTimersByTime ( 1000 ) ; // EXPAND_DELAY
70+ } ) ;
5171
5272 expect ( window . gtag ) . toHaveBeenCalledWith ( 'event' , 'expertise_card_expand' , {
5373 event_category : 'engagement' ,
@@ -58,24 +78,29 @@ describe('ExpertiseCard', () => {
5878
5979 it ( 'does not fire event when already expanded' , ( ) => {
6080 const onExpand = vi . fn ( ) ;
61- render ( < ExpertiseCard item = { mockItem } isExpanded = { true } onExpand = { onExpand } /> ) ;
81+ render ( < ExpertiseCard item = { mockItem } isExpanded = { true } onExpand = { onExpand } onCollapse = { noop } /> ) ;
6282
6383 const card = screen . getByText ( 'Incident Management' ) . closest ( 'div[tabindex]' ) ;
6484 if ( card ) {
6585 fireEvent . mouseEnter ( card ) ;
6686
87+ act ( ( ) => {
88+ vi . advanceTimersByTime ( 1000 ) ;
89+ } ) ;
90+
6791 expect ( window . gtag ) . not . toHaveBeenCalled ( ) ;
6892 }
6993 } ) ;
7094
71- it ( 'fires expertise_card_expand event on focus ' , ( ) => {
95+ it ( 'fires expertise_card_expand event on click ' , ( ) => {
7296 const onExpand = vi . fn ( ) ;
73- render ( < ExpertiseCard item = { mockItem } isExpanded = { false } onExpand = { onExpand } /> ) ;
97+ render ( < ExpertiseCard item = { mockItem } isExpanded = { false } onExpand = { onExpand } onCollapse = { noop } /> ) ;
7498
7599 const card = screen . getByText ( 'Incident Management' ) . closest ( 'div[tabindex]' ) ;
76100 if ( card ) {
77- fireEvent . focus ( card ) ;
101+ fireEvent . click ( card ) ;
78102
103+ // Click fires immediately (no delay)
79104 expect ( window . gtag ) . toHaveBeenCalledWith ( 'event' , 'expertise_card_expand' , {
80105 event_category : 'engagement' ,
81106 event_label : 'Incident Management'
0 commit comments