mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-24 19:35:28 -06:00
test(voice-call): isolate media lifecycle coverage
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import type { RealtimeTranscriptionSession } from "openclaw/plugin-sdk/realtime-transcription";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { MediaStreamHandler } from "./media-stream.js";
|
||||
import { connectWs, startUpgradeWsServer, waitForClose } from "./websocket-test-support.js";
|
||||
|
||||
describe("MediaStreamHandler lifecycle", () => {
|
||||
it("rejects duplicate start frames without creating another STT session", async () => {
|
||||
const sttSession: RealtimeTranscriptionSession = {
|
||||
connect: async () => {},
|
||||
sendAudio: () => {},
|
||||
close: vi.fn(),
|
||||
isConnected: () => true,
|
||||
};
|
||||
const createSession = vi.fn(() => sttSession);
|
||||
const shouldAcceptStream = vi.fn(() => true);
|
||||
const onConnect = vi.fn();
|
||||
const onDisconnect = vi.fn();
|
||||
const handler = new MediaStreamHandler({
|
||||
transcriptionProvider: {
|
||||
createSession,
|
||||
id: "openai",
|
||||
label: "OpenAI",
|
||||
isConfigured: () => true,
|
||||
},
|
||||
providerConfig: {},
|
||||
shouldAcceptStream,
|
||||
onConnect,
|
||||
onDisconnect,
|
||||
});
|
||||
const server = await startUpgradeWsServer({
|
||||
urlPath: "/voice/stream",
|
||||
onUpgrade: (request, socket, head) => {
|
||||
handler.handleUpgrade(request, socket, head);
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const ws = await connectWs(server.url);
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
event: "start",
|
||||
streamSid: "MZ-first",
|
||||
start: { callSid: "CA-first" },
|
||||
}),
|
||||
);
|
||||
await vi.waitFor(() => {
|
||||
expect(onConnect).toHaveBeenCalledWith("CA-first", "MZ-first");
|
||||
});
|
||||
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
event: "start",
|
||||
streamSid: "MZ-second",
|
||||
start: { callSid: "CA-second" },
|
||||
}),
|
||||
);
|
||||
const closed = await waitForClose(ws);
|
||||
|
||||
expect(closed).toEqual({ code: 1008, reason: "Duplicate start" });
|
||||
expect(createSession).toHaveBeenCalledTimes(1);
|
||||
expect(shouldAcceptStream).toHaveBeenCalledTimes(1);
|
||||
expect(onConnect).toHaveBeenCalledTimes(1);
|
||||
await vi.waitFor(() => {
|
||||
expect(sttSession.close).toHaveBeenCalledTimes(1);
|
||||
expect(onDisconnect).toHaveBeenCalledWith("CA-first", "MZ-first");
|
||||
expect(onDisconnect).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
} finally {
|
||||
await server.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -253,65 +253,6 @@ describe("MediaStreamHandler security hardening", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("rejects duplicate start frames without creating another STT session", async () => {
|
||||
const sttSession = {
|
||||
...createStubSession(),
|
||||
close: vi.fn(),
|
||||
};
|
||||
const createSession = vi.fn(() => sttSession);
|
||||
const shouldAcceptStream = vi.fn(() => true);
|
||||
const onConnect = vi.fn();
|
||||
const onDisconnect = vi.fn();
|
||||
const handler = new MediaStreamHandler({
|
||||
transcriptionProvider: {
|
||||
createSession,
|
||||
id: "openai",
|
||||
label: "OpenAI",
|
||||
isConfigured: () => true,
|
||||
},
|
||||
providerConfig: {},
|
||||
shouldAcceptStream,
|
||||
onConnect,
|
||||
onDisconnect,
|
||||
});
|
||||
const server = await startWsServer(handler);
|
||||
|
||||
try {
|
||||
const ws = await connectWs(server.url);
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
event: "start",
|
||||
streamSid: "MZ-first",
|
||||
start: { callSid: "CA-first" },
|
||||
}),
|
||||
);
|
||||
await vi.waitFor(() => {
|
||||
expect(onConnect).toHaveBeenCalledWith("CA-first", "MZ-first");
|
||||
});
|
||||
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
event: "start",
|
||||
streamSid: "MZ-second",
|
||||
start: { callSid: "CA-second" },
|
||||
}),
|
||||
);
|
||||
const closed = await waitForClose(ws);
|
||||
|
||||
expect(closed).toEqual({ code: 1008, reason: "Duplicate start" });
|
||||
expect(createSession).toHaveBeenCalledTimes(1);
|
||||
expect(shouldAcceptStream).toHaveBeenCalledTimes(1);
|
||||
expect(onConnect).toHaveBeenCalledTimes(1);
|
||||
await vi.waitFor(() => {
|
||||
expect(sttSession.close).toHaveBeenCalledTimes(1);
|
||||
expect(onDisconnect).toHaveBeenCalledWith("CA-first", "MZ-first");
|
||||
expect(onDisconnect).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
} finally {
|
||||
await server.close();
|
||||
}
|
||||
});
|
||||
|
||||
it("emits common Talk events for telephony STT/TTS sessions", async () => {
|
||||
let callbacks: RealtimeTranscriptionSessionCreateRequest | undefined;
|
||||
const sentAudio: Buffer[] = [];
|
||||
|
||||
Reference in New Issue
Block a user