Skip to content

Commit 675561c

Browse files
committed
test(sse): cover delivery across rotation
1 parent 50104c4 commit 675561c

3 files changed

Lines changed: 18 additions & 10 deletions

File tree

apps/sim/hooks/queries/mcp.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ describe('useMcpToolsQuery', () => {
127127
// mcp.ts captured these Map/Set instances in module consts at import, so reassigning the
128128
// globalThis property wouldn't reset what the module uses — clear the shared instances.
129129
;(
130-
globalThis as unknown as { __mcp_rotating_sse_connections?: Map<string, unknown> }
131-
).__mcp_rotating_sse_connections?.clear()
130+
globalThis as unknown as { __mcp_sse_connections?: Map<string, unknown> }
131+
).__mcp_sse_connections?.clear()
132132
;(globalThis as unknown as { __mcp_sse_subscribed?: Set<string> }).__mcp_sse_subscribed?.clear()
133133
})
134134

apps/sim/hooks/queries/mcp.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -543,9 +543,9 @@ export function useStoredMcpTools(workspaceId: string, options?: { enabled?: boo
543543
* Reference-counted so the connection is closed when the last consumer unmounts.
544544
* Attached to `globalThis` so connections survive HMR in development.
545545
*/
546-
const SSE_KEY = '__mcp_rotating_sse_connections' as const
546+
const SSE_KEY = '__mcp_sse_connections' as const
547547

548-
type SseEntry = { connection: RotatingEventSourceConnection; refs: number }
548+
type SseEntry = { source: RotatingEventSourceConnection; refs: number }
549549

550550
const sseConnections: Map<string, SseEntry> =
551551
((globalThis as Record<string, unknown>)[SSE_KEY] as Map<string, SseEntry>) ??
@@ -582,7 +582,7 @@ export function useMcpToolsEvents(workspaceId: string) {
582582
if (!entry) {
583583
const isResubscribe = sseEverSubscribed.has(workspaceId)
584584
sseEverSubscribed.add(workspaceId)
585-
const connection = createRotatingEventSource({
585+
const source = createRotatingEventSource({
586586
url: `/api/mcp/events?workspaceId=${encodeURIComponent(workspaceId)}`,
587587
events: {
588588
tools_changed: (event) => {
@@ -602,7 +602,7 @@ export function useMcpToolsEvents(workspaceId: string) {
602602
},
603603
})
604604

605-
entry = { connection, refs: 0 }
605+
entry = { source, refs: 0 }
606606
sseConnections.set(workspaceId, entry)
607607
}
608608

@@ -614,7 +614,7 @@ export function useMcpToolsEvents(workspaceId: string) {
614614

615615
current.refs--
616616
if (current.refs <= 0) {
617-
current.connection.close()
617+
current.source.close()
618618
sseConnections.delete(workspaceId)
619619
}
620620
}

apps/sim/lib/events/rotating-event-source.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ describe('createRotatingEventSource', () => {
6868

6969
it('keeps the current source open until its replacement connects', () => {
7070
const reasons: EventSourceOpenReason[] = []
71+
const onMessage = vi.fn()
7172
const connection = createRotatingEventSource({
7273
url: '/api/events',
73-
events: {},
74+
events: { message: onMessage },
7475
onOpen: (reason) => reasons.push(reason),
7576
})
7677
const first = MockEventSource.instances[0]
7778
first.open()
79+
first.emit('message')
7880

7981
first.emit('rotate')
8082

@@ -83,28 +85,34 @@ describe('createRotatingEventSource', () => {
8385

8486
const second = MockEventSource.instances[1]
8587
second.open()
88+
second.emit('message')
8689

8790
expect(first.readyState).toBe(MockEventSource.CLOSED)
8891
expect(second.readyState).toBe(MockEventSource.OPEN)
8992
expect(reasons).toEqual(['initial', 'rotation'])
93+
expect(onMessage).toHaveBeenCalledTimes(2)
9094
connection.close()
9195
})
9296

9397
it('classifies a replacement as reconnecting when the old source dropped first', () => {
9498
const reasons: EventSourceOpenReason[] = []
99+
const onMessage = vi.fn()
95100
const connection = createRotatingEventSource({
96101
url: '/api/events',
97-
events: {},
102+
events: { message: onMessage },
98103
onOpen: (reason) => reasons.push(reason),
99104
})
100105
const first = MockEventSource.instances[0]
101106
first.open()
102107
first.emit('rotate')
103108
first.error()
104109

105-
MockEventSource.instances[1].open()
110+
const second = MockEventSource.instances[1]
111+
second.open()
112+
second.emit('message')
106113

107114
expect(reasons).toEqual(['initial', 'reconnect'])
115+
expect(onMessage).toHaveBeenCalledTimes(1)
108116
connection.close()
109117
})
110118

0 commit comments

Comments
 (0)