import { describe, expect, it } from 'vitest' import { buildLoopbackUrl, dialLoopback, type RawWs, type WsConstructor } from '../src/transport/loopback.js' describe('buildLoopbackUrl (T8)', () => { it('joins target + path without a double slash', () => { expect(buildLoopbackUrl('ws://127.0.0.1:3000', '/term?join=x')).toBe('ws://127.0.0.1:3000/term?join=x') expect(buildLoopbackUrl('ws://127.0.0.1:3000/', 'term')).toBe('ws://127.0.0.1:3000/term') }) }) class FakeRawWs implements RawWs { static last: FakeRawWs | null = null readonly url: string readonly origin: string | undefined private readonly handlers = new Map void>() constructor(url: string, opts?: { headers?: Record }) { this.url = url this.origin = opts?.headers?.['Origin'] FakeRawWs.last = this } send(): void {} close(): void {} on(): void {} once(event: string, cb: (...a: unknown[]) => void): void { this.handlers.set(event, cb) } fire(event: string, ...args: unknown[]): void { this.handlers.get(event)?.(...args) } } describe('dialLoopback (T8)', () => { it('replays Origin and resolves on open', async () => { const dial = dialLoopback('ws://127.0.0.1:3000', FakeRawWs as unknown as WsConstructor) const promise = dial('/term?join=x', 'https://host-42.term.example.com') FakeRawWs.last!.fire('open') const ws = await promise expect(FakeRawWs.last!.url).toBe('ws://127.0.0.1:3000/term?join=x') expect(FakeRawWs.last!.origin).toBe('https://host-42.term.example.com') expect(ws).toBeDefined() }) it('rejects on a pre-open error (base app down)', async () => { const dial = dialLoopback('ws://127.0.0.1:3000', FakeRawWs as unknown as WsConstructor) const promise = dial('/term', 'https://x') FakeRawWs.last!.fire('error', new Error('ECONNREFUSED')) await expect(promise).rejects.toThrow('ECONNREFUSED') }) })