@@ -75,6 +75,12 @@ describe('ChatNavigationLink', () => {
7575 return link
7676 }
7777
78+ function pointerEvent ( type : string , pointerType : 'mouse' | 'touch' , init ?: MouseEventInit ) {
79+ const event = new MouseEvent ( type , { bubbles : true , ...init } )
80+ Object . defineProperty ( event , 'pointerType' , { value : pointerType } )
81+ return event
82+ }
83+
7884 it ( 'prefetches the route and exact history after deliberate pointer intent' , ( ) => {
7985 const link = renderLink ( )
8086
@@ -132,6 +138,59 @@ describe('ChatNavigationLink', () => {
132138 expect ( prefetchQuery ) . not . toHaveBeenCalled ( )
133139 } )
134140
141+ it ( 'prefetches before direct mouse clicks and completed touch taps' , ( ) => {
142+ const link = renderLink ( )
143+
144+ act ( ( ) => link . dispatchEvent ( pointerEvent ( 'pointerdown' , 'mouse' , { button : 0 } ) ) )
145+
146+ expect ( linkPrefetch ) . toHaveBeenLastCalledWith ( true )
147+ expect ( prefetchQuery ) . toHaveBeenCalledTimes ( 1 )
148+
149+ act ( ( ) => link . dispatchEvent ( new FocusEvent ( 'focusout' , { bubbles : true } ) ) )
150+ prefetchQuery . mockClear ( )
151+ act ( ( ) => link . dispatchEvent ( pointerEvent ( 'pointerup' , 'touch' , { button : 0 } ) ) )
152+
153+ expect ( linkPrefetch ) . toHaveBeenLastCalledWith ( true )
154+ expect ( prefetchQuery ) . toHaveBeenCalledTimes ( 1 )
155+ } )
156+
157+ it ( 'cancels touch-scroll pointer intent before it can prefetch' , ( ) => {
158+ const link = renderLink ( )
159+
160+ act ( ( ) => {
161+ link . dispatchEvent ( pointerEvent ( 'pointerdown' , 'touch' , { button : 0 } ) )
162+ link . dispatchEvent ( pointerEvent ( 'pointercancel' , 'touch' , { button : 0 } ) )
163+ } )
164+
165+ expect ( linkPrefetch ) . toHaveBeenLastCalledWith ( false )
166+ expect ( prefetchQuery ) . not . toHaveBeenCalled ( )
167+ } )
168+
169+ it ( 'does not prefetch when a nested chat action is pressed' , ( ) => {
170+ act ( ( ) => {
171+ root . render (
172+ < QueryClientProvider client = { queryClient } >
173+ < ChatNavigationLink chatId = 'chat-1' href = '/workspace/ws-1/chat/chat-1' >
174+ < button type = 'button' onClick = { ( event ) => event . preventDefault ( ) } >
175+ Chat options
176+ </ button >
177+ </ ChatNavigationLink >
178+ </ QueryClientProvider >
179+ )
180+ } )
181+ const button = container . querySelector ( 'button' )
182+ if ( ! button ) throw new Error ( 'chat action not rendered' )
183+
184+ act ( ( ) => {
185+ button . dispatchEvent ( pointerEvent ( 'pointerdown' , 'mouse' , { button : 0 } ) )
186+ button . dispatchEvent ( pointerEvent ( 'pointerup' , 'touch' , { button : 0 } ) )
187+ button . dispatchEvent ( new MouseEvent ( 'click' , { bubbles : true , cancelable : true } ) )
188+ } )
189+
190+ expect ( linkPrefetch ) . toHaveBeenLastCalledWith ( false )
191+ expect ( prefetchQuery ) . not . toHaveBeenCalled ( )
192+ } )
193+
135194 it ( 'does not prefetch the chat that is already open' , ( ) => {
136195 const link = renderLink ( 'chat-1' , true )
137196
0 commit comments