Skip to content

Commit fcec190

Browse files
committed
test(files): cover the refetchInterval passthrough against real react-query
Both consumers' test setups (the reconcile unit tests and the browser harness) replace @/hooks/queries/workspace-files, so the real hook's two changed lines were exercised by nothing but the type-checker. These render the real useWorkspaceFileContent under a real QueryClientProvider with a stubbed fetch: no polling by default, polling with a numeric interval, and the function form re-evaluated so flipping its condition stops the polling — the exact mechanism the reconcile fix depends on. The two polling tests fail against the pre-fix hook.
1 parent adcbe0a commit fcec190

1 file changed

Lines changed: 104 additions & 0 deletions

File tree

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* @vitest-environment jsdom
3+
*
4+
* `useWorkspaceFileContent` against REAL react-query (no module mocks): the `refetchInterval`
5+
* option must reach the query — the editor's post-stream reconcile depends on it to poll until the
6+
* server content advances (see `use-editable-file-content.ts`), and both its consumers' test
7+
* setups replace this module, so without this file the passthrough itself would be exercised by
8+
* nothing but the type-checker.
9+
*/
10+
import { act, type ReactNode } from 'react'
11+
import { sleep } from '@sim/utils/helpers'
12+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
13+
import { createRoot, type Root } from 'react-dom/client'
14+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
15+
import { useWorkspaceFileContent } from '@/hooks/queries/workspace-files'
16+
17+
let fetchCount = 0
18+
19+
beforeEach(() => {
20+
;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true
21+
fetchCount = 0
22+
vi.stubGlobal(
23+
'fetch',
24+
vi.fn(async () => {
25+
fetchCount += 1
26+
return new Response('# content', { status: 200 })
27+
})
28+
)
29+
})
30+
31+
afterEach(() => {
32+
vi.unstubAllGlobals()
33+
})
34+
35+
function renderContentHook(options?: {
36+
refetchInterval?: number | false | (() => number | false)
37+
}): { unmount: () => void } {
38+
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } })
39+
const container = document.createElement('div')
40+
const root: Root = createRoot(container)
41+
42+
function Probe() {
43+
useWorkspaceFileContent('ws-1', 'file-1', 'workspace/ws-1/123-abc-doc.md', false, options)
44+
return null
45+
}
46+
47+
function Wrapper({ children }: { children: ReactNode }) {
48+
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
49+
}
50+
51+
act(() => {
52+
root.render(
53+
<Wrapper>
54+
<Probe />
55+
</Wrapper>
56+
)
57+
})
58+
return {
59+
unmount: () => {
60+
act(() => root.unmount())
61+
queryClient.clear()
62+
},
63+
}
64+
}
65+
66+
describe('useWorkspaceFileContent refetchInterval passthrough', () => {
67+
it('fetches once and does not poll by default', async () => {
68+
const { unmount } = renderContentHook()
69+
await act(async () => {
70+
await sleep(150)
71+
})
72+
expect(fetchCount).toBe(1)
73+
unmount()
74+
})
75+
76+
it('polls when a numeric refetchInterval is passed', async () => {
77+
const { unmount } = renderContentHook({ refetchInterval: 30 })
78+
await act(async () => {
79+
await sleep(200)
80+
})
81+
expect(fetchCount).toBeGreaterThanOrEqual(3)
82+
unmount()
83+
})
84+
85+
it('function form is re-evaluated so flipping its condition stops the polling', async () => {
86+
let polling = true
87+
const { unmount } = renderContentHook({ refetchInterval: () => (polling ? 30 : false) })
88+
await act(async () => {
89+
await sleep(200)
90+
})
91+
expect(fetchCount).toBeGreaterThanOrEqual(3)
92+
93+
polling = false
94+
await act(async () => {
95+
await sleep(100)
96+
})
97+
const settled = fetchCount
98+
await act(async () => {
99+
await sleep(150)
100+
})
101+
expect(fetchCount).toBe(settled)
102+
unmount()
103+
})
104+
})

0 commit comments

Comments
 (0)