@@ -5,7 +5,9 @@ import { act } from 'react'
55import { createRoot , hydrateRoot , type Root } from 'react-dom/client'
66import { renderToString } from 'react-dom/server'
77import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
8+ import { WorkspaceRecencyProvider } from '@/components/workspaces/workspace-recency-provider'
89import { STORAGE_KEYS , WorkspaceRecencyStorage } from '@/lib/core/utils/browser-storage'
10+ import { WORKSPACE_RECENCY_COOKIE } from '@/lib/workspaces/recency-cookie'
911
1012const { mockUseWorkspacesQuery, pins } = vi . hoisted ( ( ) => ( {
1113 pins : { current : new Set < string > ( ) } ,
@@ -64,20 +66,31 @@ function workspaceIds() {
6466}
6567
6668describe ( 'useOrganizationWorkspaces' , ( ) => {
67- it ( 'hydrates the prefetched order before applying visit history without changing the query cache ' , async ( ) => {
69+ it ( 'renders the visit order on the server so hydration does not reshuffle rows ' , async ( ) => {
6870 localStorage . setItem (
6971 STORAGE_KEYS . WORKSPACE_RECENCY ,
7072 JSON . stringify ( { oldest : 100 , older : 200 , 'other-org' : 300 } )
7173 )
72- container . innerHTML = renderToString ( < Harness /> )
73- expect ( workspaceIds ( ) ) . toEqual ( [ 'newest' , 'older' , 'oldest' ] )
74+ const recentIds = [ 'other-org' , 'older' , 'oldest' ]
75+ const tree = (
76+ < WorkspaceRecencyProvider recentWorkspaceIds = { recentIds } >
77+ < Harness />
78+ </ WorkspaceRecencyProvider >
79+ )
80+ container . innerHTML = renderToString ( tree )
81+ expect ( workspaceIds ( ) ) . toEqual ( [ 'older' , 'oldest' , 'newest' ] )
7482
7583 const onRecoverableError = vi . fn ( )
84+ const observed : string [ ] [ ] = [ ]
85+ const observer = new MutationObserver ( ( ) => observed . push ( workspaceIds ( ) ) )
86+ observer . observe ( container , { childList : true , subtree : true , characterData : true } )
7687 await act ( async ( ) => {
77- root = hydrateRoot ( container , < Harness /> , { onRecoverableError } )
88+ root = hydrateRoot ( container , tree , { onRecoverableError } )
7889 } )
90+ observer . disconnect ( )
7991
8092 expect ( onRecoverableError ) . not . toHaveBeenCalled ( )
93+ expect ( observed ) . toEqual ( [ ] )
8194 expect ( workspaceIds ( ) ) . toEqual ( [ 'older' , 'oldest' , 'newest' ] )
8295 expect ( mockUseWorkspacesQuery ( ) . data . map ( ( { id } : { id : string } ) => id ) ) . toEqual ( [
8396 'newest' ,
@@ -87,6 +100,15 @@ describe('useOrganizationWorkspaces', () => {
87100 ] )
88101 } )
89102
103+ it ( 'mirrors visits into the recency cookie' , async ( ) => {
104+ await act ( async ( ) => {
105+ root = createRoot ( container )
106+ root . render ( < Harness /> )
107+ } )
108+ await act ( async ( ) => WorkspaceRecencyStorage . touch ( 'older' ) )
109+ expect ( document . cookie ) . toContain ( `${ WORKSPACE_RECENCY_COOKIE } =older` )
110+ } )
111+
90112 it ( 'preserves creation-date order when the browser has no visit history' , async ( ) => {
91113 await act ( async ( ) => {
92114 root = createRoot ( container )
0 commit comments