test(openai): verify terminal audio cleanup

This commit is contained in:
Vincent Koc
2026-07-30 12:35:40 +08:00
parent 3133abed32
commit 21463e6e19
2 changed files with 135 additions and 0 deletions
@@ -185,6 +185,72 @@ describe("OpenAIQuicksilverVoiceBridge", () => {
expect(harness.onReady).toHaveBeenCalledOnce();
});
it("bounds queued audio by aggregate bytes before session readiness", async () => {
const harness = createHarness({ autoStart: false });
const connecting = harness.bridge.connect();
await vi.waitFor(() => expect(harness.socket.readyState).toBe(1));
harness.bridge.sendAudio(Buffer.alloc(512 * 1024, 0x01));
harness.bridge.sendAudio(Buffer.alloc(512 * 1024, 0x02));
harness.bridge.sendAudio(Buffer.from("overflow"));
harness.socket.serverEvent({
type: "session.started",
session: { id: "live-1", expires_at: Math.floor(Date.now() / 1000) + 60 },
});
await connecting;
const audioEvents = sentEvents(harness.socket).filter(
(event) => event.type === "input_audio.append",
);
expect(audioEvents).toHaveLength(2);
expect(
audioEvents.map((event) => Buffer.from(String(event.audio), "base64").byteLength),
).toEqual([512 * 1024, 512 * 1024]);
harness.bridge.close();
});
it("does not carry queued audio across terminal close and explicit reconnect", async () => {
const sockets: FakeSocket[] = [];
const bridge = new OpenAIQuicksilverVoiceBridge({
providerConfig: {},
model: "gpt-live-1-codex",
audioFormat: { encoding: "pcm16", sampleRateHz: 24000, channels: 1 },
resolveAuth: async () => ({ type: "api-key", token: "test-key" }),
webSocketFactory: (_url, _options) => {
const socket = new FakeSocket(false);
sockets.push(socket);
queueMicrotask(() => socket.open());
return socket as unknown as OpenAIQuicksilverSocket;
},
onAudio: vi.fn(),
onClearAudio: vi.fn(),
});
const firstConnect = bridge.connect();
await vi.waitFor(() => expect(sockets[0]?.readyState).toBe(1));
bridge.sendAudio(Buffer.from("queued-before-close"));
bridge.close();
await firstConnect;
bridge.sendAudio(Buffer.from("sent-after-close"));
const reconnecting = bridge.connect();
await vi.waitFor(() => expect(sockets[1]?.readyState).toBe(1));
sockets[1]?.serverEvent({
type: "session.started",
session: { id: "live-2", expires_at: Math.floor(Date.now() / 1000) + 60 },
});
await reconnecting;
const secondSocket = sockets[1];
if (!secondSocket) {
throw new Error("expected bridge to reconnect");
}
expect(
sentEvents(secondSocket).filter((event) => event.type === "input_audio.append"),
).toHaveLength(0);
bridge.close();
});
it("rejects startup failures without emitting terminal callbacks", async () => {
const harness = createHarness({ autoStart: false });
const connecting = harness.bridge.connect();
@@ -1517,6 +1517,75 @@ describe("buildOpenAIRealtimeVoiceProvider", () => {
expect(bridge.isConnected()).toBe(true);
});
it("bounds queued audio by aggregate bytes before session readiness", async () => {
const provider = buildOpenAIRealtimeVoiceProvider();
const bridge = provider.createBridge({
providerConfig: { apiKey: "sk-test" }, // pragma: allowlist secret
onAudio: vi.fn(),
onClearAudio: vi.fn(),
});
const connecting = bridge.connect();
const socket = FakeWebSocket.instances[0];
if (!socket) {
throw new Error("expected bridge to create a websocket");
}
socket.readyState = FakeWebSocket.OPEN;
socket.emit("open");
await Promise.resolve();
bridge.sendAudio(Buffer.alloc(512 * 1024, 0x01));
bridge.sendAudio(Buffer.alloc(512 * 1024, 0x02));
bridge.sendAudio(Buffer.from("overflow"));
socket.emit("message", Buffer.from(JSON.stringify({ type: "session.updated" })));
await connecting;
const audioEvents = parseSent(socket).filter(
(event) => event.type === "input_audio_buffer.append",
);
expect(audioEvents).toHaveLength(2);
expect(
audioEvents.map((event) => Buffer.from(String(event.audio), "base64").byteLength),
).toEqual([512 * 1024, 512 * 1024]);
bridge.close();
});
it("does not carry queued audio across terminal close and explicit reconnect", async () => {
const provider = buildOpenAIRealtimeVoiceProvider();
const bridge = provider.createBridge({
providerConfig: { apiKey: "sk-test" }, // pragma: allowlist secret
onAudio: vi.fn(),
onClearAudio: vi.fn(),
});
const firstConnect = bridge.connect();
const firstSocket = FakeWebSocket.instances[0];
if (!firstSocket) {
throw new Error("expected bridge to create a websocket");
}
firstSocket.readyState = FakeWebSocket.OPEN;
firstSocket.emit("open");
await Promise.resolve();
bridge.sendAudio(Buffer.from("queued-before-close"));
bridge.close();
await firstConnect;
bridge.sendAudio(Buffer.from("sent-after-close"));
const reconnecting = bridge.connect();
const secondSocket = FakeWebSocket.instances[1];
if (!secondSocket) {
throw new Error("expected bridge to reconnect");
}
secondSocket.readyState = FakeWebSocket.OPEN;
secondSocket.emit("open");
secondSocket.emit("message", Buffer.from(JSON.stringify({ type: "session.updated" })));
await reconnecting;
expect(
parseSent(secondSocket).filter((event) => event.type === "input_audio_buffer.append"),
).toHaveLength(0);
bridge.close();
});
it("shares an in-flight connection until session readiness", async () => {
const provider = buildOpenAIRealtimeVoiceProvider();
const onReady = vi.fn();