Skip to content

Commit 092a6fc

Browse files
committed
test(chat): measure delivery passes without spying on the global timer
A spy taken on setTimeout under fake timers was restored by the shared config after useRealTimers, which put the fake back: every later real-timer test in the file hung in sleep. Count reads of the cached chat, which every delivery pass makes, instead.
1 parent 99addba commit 092a6fc

1 file changed

Lines changed: 20 additions & 16 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/home/hooks/use-chat.dom.test.tsx‎

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -681,19 +681,20 @@ function elapse(ms: number): Promise<unknown> {
681681
return vi.isFakeTimers() ? vi.advanceTimersByTimeAsync(ms) : sleep(ms)
682682
}
683683

684+
/** Far under one read per fake millisecond, and room for the odd unrelated read. */
685+
const MAX_IDLE_CHAT_READS = 50
686+
684687
/**
685-
* How many zero-delay timers run while `ms` passes on the fake clock. Delivery
686-
* waking on a delay that is already over runs back to back, a pass per tick, so a
687-
* surface with nothing due must schedule none.
688+
* How many times the surface reads the cached chat while `ms` passes on the fake
689+
* clock. Every delivery pass reads it, so delivery waking on a delay already over
690+
* shows as a read per tick, where a surface with nothing due reads next to nothing.
688691
*/
689-
async function zeroDelayTimersDuring(ms: number): Promise<number> {
690-
const schedule = vi.spyOn(globalThis, 'setTimeout')
692+
async function chatReadsDuring(ms: number): Promise<number> {
693+
const read = vi.spyOn(queryClient, 'getQueryData')
691694
await act(async () => {
692695
await vi.advanceTimersByTimeAsync(ms)
693696
})
694-
const count = schedule.mock.calls.filter(([, delay]) => !delay).length
695-
schedule.mockRestore()
696-
return count
697+
return read.mock.calls.length
697698
}
698699

699700
/** Lets everything already due run: answered requests, their handlers, what those schedule. */
@@ -2595,7 +2596,7 @@ describe('useChat remount send recovery', () => {
25952596
expect(message?.delivery).toBe('failed')
25962597
const attempts = state.postBodies.length
25972598

2598-
expect(await zeroDelayTimersDuring(5_000)).toBe(0)
2599+
expect(await chatReadsDuring(5_000)).toBeLessThan(MAX_IDLE_CHAT_READS)
25992600
expect(state.postBodies).toHaveLength(attempts)
26002601
} finally {
26012602
vi.useRealTimers()
@@ -2618,11 +2619,13 @@ describe('useChat remount send recovery', () => {
26182619

26192620
/* Another tab's turn shows up in the chat before this message's retry delay ends. */
26202621
const fetchUnreachable = globalThis.fetch
2621-
vi.stubGlobal('fetch', async (input: RequestInfo | URL, init?: RequestInit) =>
2622-
String(input).includes('/api/mothership/chat/stream')
2623-
? Response.json({ success: true, events: [], status: 'active' })
2624-
: fetchUnreachable(input, init)
2625-
)
2622+
vi.stubGlobal('fetch', async (input: RequestInfo | URL, init?: RequestInit) => {
2623+
if (!String(input).includes('/api/mothership/chat/stream')) {
2624+
return fetchUnreachable(input, init)
2625+
}
2626+
await sleep(50)
2627+
return Response.json({ success: true, events: [], status: 'active' })
2628+
})
26262629
const running = { ...history, activeStreamId: 'run-in-another-tab' }
26272630
mockRequestJson.mockImplementation(() => Promise.resolve({ chat: running }))
26282631
await act(async () => {
@@ -2632,8 +2635,9 @@ describe('useChat remount send recovery', () => {
26322635
expect(view.getResult().isReconnecting || view.getResult().isSending).toBe(true)
26332636

26342637
await act(async () => vi.advanceTimersByTimeAsync(5_000))
2635-
expect(await zeroDelayTimersDuring(2_000)).toBe(0)
2638+
expect(await chatReadsDuring(2_000)).toBeLessThan(MAX_IDLE_CHAT_READS)
26362639
expect(state.postBodies).toHaveLength(1)
2640+
view.unmount()
26372641
} finally {
26382642
vi.useRealTimers()
26392643
}
@@ -4686,7 +4690,7 @@ describe('useChat remount send recovery', () => {
46864690
await waitFor(() => state.steerBodies.length === 3, 20_000)
46874691
await act(async () => vi.advanceTimersByTimeAsync(10))
46884692

4689-
expect(await zeroDelayTimersDuring(5_000)).toBe(0)
4693+
expect(await chatReadsDuring(5_000)).toBeLessThan(MAX_IDLE_CHAT_READS)
46904694
expect(state.postBodies).toHaveLength(1)
46914695
} finally {
46924696
vi.useRealTimers()

0 commit comments

Comments
 (0)