@@ -42,6 +42,7 @@ vi.mock('@/lib/api/client/request', async (importOriginal) => ({
4242
4343import { MothershipHandoffStorage } from '@/lib/core/utils/browser-storage'
4444import { useChat } from '@/app/workspace/[workspaceId]/home/hooks/use-chat'
45+ import { type MothershipChatHistory , mothershipChatKeys } from '@/hooks/queries/mothership-chats'
4546import { useMothershipQueueStore } from '@/stores/mothership-queue/store'
4647
4748const DEDUPED_CHAT_ID = 'chat-the-first-attempt-opened'
@@ -150,13 +151,18 @@ function renderUseChat(): {
150151 * pathname has to match: the hook resets a chat-bound surface back to a fresh
151152 * pending key when it finds itself on the home route.
152153 */
153- function renderUseChatInChat ( chatId : string ) : {
154+ function renderUseChatInChat (
155+ chatId : string ,
156+ sharedQueryClient : QueryClient = new QueryClient ( {
157+ defaultOptions : { queries : { retry : false } } ,
158+ } )
159+ ) : {
154160 getResult : ( ) => ReturnType < typeof useChat >
155161 unmount : ( ) => void
156162} {
157163 navigationMocks . usePathname . mockReturnValue ( `/workspace/ws-1/chat/${ chatId } ` )
158164 ; ( globalThis as { IS_REACT_ACT_ENVIRONMENT ?: boolean } ) . IS_REACT_ACT_ENVIRONMENT = true
159- queryClient = new QueryClient ( { defaultOptions : { queries : { retry : false } } } )
165+ queryClient = sharedQueryClient
160166 const container = document . createElement ( 'div' )
161167 const root = createRoot ( container )
162168 mountedRoots . push ( root )
@@ -509,4 +515,66 @@ describe('useChat remount send recovery', () => {
509515 // Must NOT have gone to the cross-surface handoff.
510516 expect ( MothershipHandoffStorage . consume ( 'ws-1' ) ) . toBeNull ( )
511517 } )
518+
519+ it ( 'restores the last edited table view after switching away and back' , async ( ) => {
520+ const chatId = 'chat-with-table'
521+ const sharedQueryClient = new QueryClient ( {
522+ defaultOptions : { queries : { retry : false } } ,
523+ } )
524+ const initialHistory : MothershipChatHistory = {
525+ id : chatId ,
526+ title : 'Table chat' ,
527+ messages : [ ] ,
528+ activeStreamId : null ,
529+ resources : [ { type : 'table' , id : 'table-1' , title : 'Invoices' } ] ,
530+ }
531+ sharedQueryClient . setQueryData ( mothershipChatKeys . detail ( chatId ) , initialHistory )
532+
533+ const firstSurface = renderUseChatInChat ( chatId , sharedQueryClient )
534+ await waitFor ( ( ) => firstSurface . getResult ( ) . resources . length === 1 )
535+
536+ act ( ( ) => {
537+ firstSurface . getResult ( ) . addResource ( {
538+ type : 'table' ,
539+ id : 'table-1' ,
540+ title : 'Invoices' ,
541+ viewId : 'view-edited' ,
542+ } )
543+ } )
544+ await waitFor ( ( ) => firstSurface . getResult ( ) . resources [ 0 ] ?. viewId === 'view-edited' )
545+ firstSurface . unmount ( )
546+
547+ const restoredSurface = renderUseChatInChat ( chatId , sharedQueryClient )
548+ await waitFor ( ( ) => restoredSurface . getResult ( ) . resources . length === 1 )
549+
550+ expect ( restoredSurface . getResult ( ) . resources [ 0 ] ?. viewId ) . toBe ( 'view-edited' )
551+ } )
552+
553+ it ( 'hydrates a table view change when resource identity and title stay the same' , async ( ) => {
554+ const chatId = 'chat-with-refetched-view'
555+ const sharedQueryClient = new QueryClient ( {
556+ defaultOptions : { queries : { retry : false } } ,
557+ } )
558+ const initialHistory : MothershipChatHistory = {
559+ id : chatId ,
560+ title : 'Table chat' ,
561+ messages : [ ] ,
562+ activeStreamId : null ,
563+ resources : [ { type : 'table' , id : 'table-1' , title : 'Invoices' } ] ,
564+ }
565+ sharedQueryClient . setQueryData ( mothershipChatKeys . detail ( chatId ) , initialHistory )
566+
567+ const surface = renderUseChatInChat ( chatId , sharedQueryClient )
568+ await waitFor ( ( ) => surface . getResult ( ) . resources . length === 1 )
569+
570+ act ( ( ) => {
571+ sharedQueryClient . setQueryData < MothershipChatHistory > ( mothershipChatKeys . detail ( chatId ) , {
572+ ...initialHistory ,
573+ resources : [ { type : 'table' , id : 'table-1' , title : 'Invoices' , viewId : 'view-refetched' } ] ,
574+ } )
575+ } )
576+
577+ await waitFor ( ( ) => surface . getResult ( ) . resources [ 0 ] ?. viewId === 'view-refetched' )
578+ expect ( surface . getResult ( ) . resources [ 0 ] ?. viewId ) . toBe ( 'view-refetched' )
579+ } )
512580} )
0 commit comments