惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
博客园_首页
量子位
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
H
Help Net Security
The Cloudflare Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
A
About on SuperTechFans
腾讯CDC
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
DataBreaches.Net
L
LangChain Blog
Stack Overflow Blog
Stack Overflow Blog
Jina AI
Jina AI
月光博客
月光博客
云风的 BLOG
云风的 BLOG
博客园 - 聂微东
Hugging Face - Blog
Hugging Face - Blog
雷峰网
雷峰网
C
Check Point Blog
V
V2EX
T
Tailwind CSS Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Security Blog
Microsoft Security Blog

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
test: tighten voice call media stream assertions · opencl...
steipete · 2026-05-10 · via Recent Commits to openclaw:main

@@ -74,6 +74,21 @@ const startWsServer = async (

7474

},

7575

});

767677+

const requireRecord = (value: unknown, label: string): Record<string, unknown> => {

78+

if (value === null || typeof value !== "object" || Array.isArray(value)) {

79+

throw new Error(`Expected ${label} to be a record`);

80+

}

81+

return value as Record<string, unknown>;

82+

};

83+84+

const requireTalkEvent = (events: TalkEvent[], type: TalkEvent["type"]) => {

85+

const event = events.find((candidate) => candidate.type === type);

86+

if (!event) {

87+

throw new Error(`Expected ${type} Talk event`);

88+

}

89+

return requireRecord(event, `${type} Talk event`);

90+

};

91+7792

describe("MediaStreamHandler TTS queue", () => {

7893

it("serializes TTS playback and resolves in order", async () => {

7994

const handler = new MediaStreamHandler({

@@ -260,30 +275,26 @@ describe("MediaStreamHandler security hardening", () => {

260275

"turn.cancelled",

261276

"session.closed",

262277

]);

263-

expect(talkEvents[0]).toEqual(

264-

expect.objectContaining({

265-

sessionId: "voice-call:CA-talk:MZ-talk",

266-

mode: "stt-tts",

267-

transport: "gateway-relay",

268-

brain: "agent-consult",

269-

provider: "openai",

270-

seq: 1,

271-

}),

272-

);

273-

expect(talkEvents.find((event) => event.type === "transcript.done")).toEqual(

274-

expect.objectContaining({

275-

final: true,

276-

turnId: "MZ-talk:turn-1",

277-

payload: expect.objectContaining({ text: "hello there", role: "user" }),

278-

}),

279-

);

280-

expect(talkEvents.find((event) => event.type === "turn.cancelled")).toEqual(

281-

expect.objectContaining({

282-

final: true,

283-

turnId: "MZ-talk:turn-2",

284-

payload: expect.objectContaining({ reason: "barge-in" }),

285-

}),

286-

);

278+

const startedEvent = requireRecord(talkEvents[0], "session started Talk event");

279+

expect(startedEvent.sessionId).toBe("voice-call:CA-talk:MZ-talk");

280+

expect(startedEvent.mode).toBe("stt-tts");

281+

expect(startedEvent.transport).toBe("gateway-relay");

282+

expect(startedEvent.brain).toBe("agent-consult");

283+

expect(startedEvent.provider).toBe("openai");

284+

expect(startedEvent.seq).toBe(1);

285+286+

const transcriptDone = requireTalkEvent(talkEvents, "transcript.done");

287+

expect(transcriptDone.final).toBe(true);

288+

expect(transcriptDone.turnId).toBe("MZ-talk:turn-1");

289+

const transcriptPayload = requireRecord(transcriptDone.payload, "transcript payload");

290+

expect(transcriptPayload.text).toBe("hello there");

291+

expect(transcriptPayload.role).toBe("user");

292+293+

const cancelled = requireTalkEvent(talkEvents, "turn.cancelled");

294+

expect(cancelled.final).toBe(true);

295+

expect(cancelled.turnId).toBe("MZ-talk:turn-2");

296+

const cancelledPayload = requireRecord(cancelled.payload, "cancelled payload");

297+

expect(cancelledPayload.reason).toBe("barge-in");

287298

} finally {

288299

await server.close();

289300

}

@@ -568,11 +579,16 @@ describe("MediaStreamHandler security hardening", () => {

568579

throw new Error("Expected upgrade callback to be registered");

569580

}

570581

completeUpgrade({} as WebSocket);

571-

expect(fakeWss.emit).toHaveBeenCalledWith(

572-

"connection",

573-

expect.anything(),

574-

expect.objectContaining({ socket: { remoteAddress: "127.0.0.1" } }),

575-

);

582+

expect(fakeWss.emit).toHaveBeenCalledOnce();

583+

const emitCall = fakeWss.emit.mock.calls[0];

584+

if (emitCall === undefined) {

585+

throw new Error("Expected websocket connection emit call");

586+

}

587+

expect(emitCall[0]).toBe("connection");

588+

expect(emitCall[1]).toBeDefined();

589+

const request = requireRecord(emitCall[2], "connection request");

590+

const socket = requireRecord(request.socket, "connection request socket");

591+

expect(socket.remoteAddress).toBe("127.0.0.1");

576592

});

577593578594

it("releases in-flight reservations when ws rejects a malformed upgrade before the callback", async () => {

@@ -624,7 +640,9 @@ describe("MediaStreamHandler security hardening", () => {

624640

});

625641626642

it("clears pending state after valid start", async () => {

627-

const shouldAcceptStream = vi.fn(() => true);

643+

const shouldAcceptStream = vi.fn(

644+

(_params: { callId: string; streamSid: string; token?: string }) => true,

645+

);

628646

const handler = new MediaStreamHandler({

629647

transcriptionProvider: createStubSttProvider(),

630648

providerConfig: {},

@@ -646,14 +664,15 @@ describe("MediaStreamHandler security hardening", () => {

646664

);

647665648666

await vi.waitFor(() => {

649-

expect(shouldAcceptStream).toHaveBeenCalledWith(

650-

expect.objectContaining({

651-

callId: "CA123",

652-

streamSid: "MZ123",

653-

token: "token-123",

654-

}),

655-

);

667+

expect(shouldAcceptStream).toHaveBeenCalledOnce();

656668

});

669+

const acceptedStream = requireRecord(

670+

shouldAcceptStream.mock.calls[0]?.[0],

671+

"accepted stream params",

672+

);

673+

expect(acceptedStream.callId).toBe("CA123");

674+

expect(acceptedStream.streamSid).toBe("MZ123");

675+

expect(acceptedStream.token).toBe("token-123");

657676

expect(ws.readyState).toBe(WebSocket.OPEN);

658677659678

const second = await connectWs(server.url);