mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 09:37:33 +00:00
Desktop, CLI, web and runtime transports now take a PairedRuntimeConnection (endpoint, pinned host key, credential) instead of a PairingOffer. Offers stay on the pairing input path (codes, QR, links, environment add) and are converted with pairedRuntimeConnectionFromOffer. The credential is token-only today; request envelopes still carry the same deviceToken, so the wire is unchanged. This lets device-key and ticket credentials replace the token later without touching every connect call site again. Co-authored-by: m4air <m4air@Mac.localdomain>
84 lines
2.9 KiB
TypeScript
84 lines
2.9 KiB
TypeScript
import { pairedRuntimeConnectionFromOffer } from './paired-runtime-connection'
|
|
import type { EventEmitter } from 'node:events'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
import { generateKeyPair, publicKeyToBase64 } from './e2ee-crypto'
|
|
import { openRemoteRuntimeWebSocket } from './remote-runtime-request-websocket'
|
|
import { REMOTE_RUNTIME_MAX_WEBSOCKET_FRAME_BYTES } from './remote-runtime-memory-limits'
|
|
import { WebSocketServer } from 'ws'
|
|
|
|
describe('openRemoteRuntimeWebSocket', () => {
|
|
it('detaches Orca callback listeners when cleaned up', () => {
|
|
const keyPair = generateKeyPair()
|
|
const opened = openRemoteRuntimeWebSocket(
|
|
pairedRuntimeConnectionFromOffer({
|
|
v: 2,
|
|
endpoint: 'ws://127.0.0.1:1',
|
|
deviceToken: 'device-token',
|
|
publicKeyB64: publicKeyToBase64(keyPair.publicKey)
|
|
}),
|
|
{
|
|
onClose: vi.fn(),
|
|
onError: vi.fn(),
|
|
onTextFrame: vi.fn()
|
|
}
|
|
)
|
|
if (!opened.ok) {
|
|
throw opened.error
|
|
}
|
|
|
|
const socketEvents = opened.socket.ws as unknown as EventEmitter
|
|
expect(socketEvents.listenerCount('open')).toBe(1)
|
|
expect(socketEvents.listenerCount('close')).toBe(1)
|
|
expect(socketEvents.listenerCount('message')).toBe(1)
|
|
expect(socketEvents.listenerCount('error')).toBe(1)
|
|
|
|
opened.socket.cleanup()
|
|
opened.socket.cleanup()
|
|
|
|
expect(socketEvents.listenerCount('open')).toBe(0)
|
|
expect(socketEvents.listenerCount('close')).toBe(0)
|
|
expect(socketEvents.listenerCount('message')).toBe(0)
|
|
expect(socketEvents.listenerCount('error')).toBe(1)
|
|
expect(() => socketEvents.emit('error', new Error('late socket error'))).not.toThrow()
|
|
opened.socket.ws.terminate()
|
|
})
|
|
|
|
it('closes on a frame larger than any runtime sends', async () => {
|
|
const server = new WebSocketServer({ host: '127.0.0.1', port: 0 })
|
|
server.on('connection', (ws) =>
|
|
ws.send(Buffer.alloc(REMOTE_RUNTIME_MAX_WEBSOCKET_FRAME_BYTES + 1))
|
|
)
|
|
await new Promise((resolve) => server.once('listening', resolve))
|
|
const address = server.address()
|
|
const port = typeof address === 'object' && address ? address.port : 0
|
|
const onError = vi.fn()
|
|
const onBinaryFrame = vi.fn()
|
|
const closed = new Promise<void>((resolve) => {
|
|
const opened = openRemoteRuntimeWebSocket(
|
|
pairedRuntimeConnectionFromOffer({
|
|
v: 2,
|
|
endpoint: `ws://127.0.0.1:${port}`,
|
|
deviceToken: 'device-token',
|
|
publicKeyB64: publicKeyToBase64(generateKeyPair().publicKey)
|
|
}),
|
|
{
|
|
onClose: () => resolve(),
|
|
onError,
|
|
onTextFrame: vi.fn(),
|
|
onBinaryFrame
|
|
}
|
|
)
|
|
if (!opened.ok) {
|
|
throw opened.error
|
|
}
|
|
})
|
|
try {
|
|
await closed
|
|
expect(onError).toHaveBeenCalledOnce()
|
|
expect(onBinaryFrame).not.toHaveBeenCalled()
|
|
} finally {
|
|
await new Promise((resolve) => server.close(resolve))
|
|
}
|
|
})
|
|
})
|