Skip to content

Commit f17620a

Browse files
committed
test: add end-to-end integration tests for network transport fallback
1 parent 1b7f1a2 commit f17620a

1 file changed

Lines changed: 124 additions & 0 deletions

File tree

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// @vitest-environment node
2+
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
3+
import { ServerEventBus } from '@tanstack/devtools-event-bus/server'
4+
import { createNetworkTransportClient } from '../src/plugin'
5+
6+
describe('End-to-end: ServerEventBus + EventClient network transport', () => {
7+
let serverBus: ServerEventBus
8+
9+
beforeEach(() => {
10+
globalThis.__TANSTACK_EVENT_TARGET__ = null
11+
globalThis.__TANSTACK_DEVTOOLS_SERVER__ = null
12+
globalThis.__TANSTACK_DEVTOOLS_WSS_SERVER__ = null
13+
process.env.NODE_ENV = 'development'
14+
})
15+
16+
afterEach(async () => {
17+
serverBus?.stop()
18+
globalThis.__TANSTACK_EVENT_TARGET__ = null
19+
globalThis.__TANSTACK_DEVTOOLS_SERVER__ = null
20+
globalThis.__TANSTACK_DEVTOOLS_WSS_SERVER__ = null
21+
await new Promise((resolve) => setTimeout(resolve, 100))
22+
})
23+
24+
it('should support bidirectional events between isolated EventClient and ServerEventBus', async () => {
25+
// 1. Start ServerEventBus
26+
serverBus = new ServerEventBus({ port: 0 })
27+
const port = await serverBus.start()
28+
const serverEventTarget = globalThis.__TANSTACK_EVENT_TARGET__!
29+
30+
// 2. Simulate isolation: null out globalThis
31+
globalThis.__TANSTACK_EVENT_TARGET__ = null
32+
33+
// 3. Create isolated EventClient with network transport
34+
const client = createNetworkTransportClient({
35+
pluginId: 'e2e-test',
36+
port,
37+
host: 'localhost',
38+
protocol: 'http',
39+
})
40+
41+
// 4. Set up listener on the isolated client
42+
const clientReceived = new Promise<any>((resolve) => {
43+
client.on('from-server', (event) => resolve(event))
44+
})
45+
46+
// 5. Emit from client → should reach server
47+
const serverReceived = new Promise<any>((resolve) => {
48+
serverEventTarget.addEventListener('e2e-test:from-client', (e) => {
49+
resolve((e as CustomEvent).detail)
50+
})
51+
})
52+
53+
client.emit('from-client', { direction: 'client-to-server' })
54+
55+
// Wait for connection + delivery
56+
const fromClient = await Promise.race([
57+
serverReceived,
58+
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout: client→server')), 3000)),
59+
])
60+
61+
expect(fromClient.payload).toEqual({ direction: 'client-to-server' })
62+
63+
// 6. Now emit from server → should reach isolated client
64+
await new Promise((resolve) => setTimeout(resolve, 200))
65+
66+
serverEventTarget.dispatchEvent(
67+
new CustomEvent('tanstack-dispatch-event', {
68+
detail: {
69+
type: 'e2e-test:from-server',
70+
payload: { direction: 'server-to-client' },
71+
pluginId: 'e2e-test',
72+
},
73+
}),
74+
)
75+
76+
const fromServer = await Promise.race([
77+
clientReceived,
78+
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout: server→client')), 3000)),
79+
])
80+
81+
expect(fromServer.payload).toEqual({ direction: 'server-to-client' })
82+
83+
client.destroy()
84+
})
85+
86+
it('should handle multiple isolated clients simultaneously', async () => {
87+
serverBus = new ServerEventBus({ port: 0 })
88+
const port = await serverBus.start()
89+
const serverEventTarget = globalThis.__TANSTACK_EVENT_TARGET__!
90+
globalThis.__TANSTACK_EVENT_TARGET__ = null
91+
92+
const client1 = createNetworkTransportClient({
93+
pluginId: 'multi-1',
94+
port,
95+
host: 'localhost',
96+
})
97+
98+
const client2 = createNetworkTransportClient({
99+
pluginId: 'multi-2',
100+
port,
101+
host: 'localhost',
102+
})
103+
104+
// Both emit, both should reach server
105+
const received: Array<any> = []
106+
serverEventTarget.addEventListener('multi-1:ping', (e) => {
107+
received.push((e as CustomEvent).detail)
108+
})
109+
serverEventTarget.addEventListener('multi-2:ping', (e) => {
110+
received.push((e as CustomEvent).detail)
111+
})
112+
113+
client1.emit('ping', { from: 1 })
114+
client2.emit('ping', { from: 2 })
115+
116+
await new Promise((resolve) => setTimeout(resolve, 2000))
117+
118+
expect(received.length).toBe(2)
119+
expect(received.map((e) => e.payload.from).sort()).toEqual([1, 2])
120+
121+
client1.destroy()
122+
client2.destroy()
123+
})
124+
})

0 commit comments

Comments
 (0)