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

推荐订阅源

Vercel News
Vercel News
博客园 - 【当耐特】
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
Hugging Face - Blog
Hugging Face - Blog
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学
G
Google Developers Blog
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
P
Proofpoint News Feed
J
Java Code Geeks
U
Unit 42
云风的 BLOG
云风的 BLOG
阮一峰的网络日志
阮一峰的网络日志
N
Netflix TechBlog - Medium
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
D
Docker
V
Visual Studio Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
H
Help Net Security
V
V2EX
T
Tailwind CSS 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 reset hook assertions · openclaw/openclaw@d...
steipete · 2026-05-11 · via Recent Commits to openclaw:main

@@ -105,6 +105,34 @@ function buildResetParams(

105105

};

106106

}

107107108+

function mockCall(mock: unknown, index = 0): Array<unknown> {

109+

const calls = (mock as { mock?: { calls?: Array<Array<unknown>> } }).mock?.calls ?? [];

110+

const call = calls.at(index);

111+

expect(call, `mock call ${index + 1}`).toBeDefined();

112+

return call as Array<unknown>;

113+

}

114+115+

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

116+

expect(value, label).toBeTypeOf("object");

117+

expect(value, label).not.toBeNull();

118+

return value as Record<string, unknown>;

119+

}

120+121+

function expectObjectFields(

122+

value: unknown,

123+

expected: Record<string, unknown>,

124+

label = "object",

125+

): void {

126+

const record = requireRecord(value, label);

127+

for (const [key, expectedValue] of Object.entries(expected)) {

128+

expect(record[key], `${label}.${key}`).toEqual(expectedValue);

129+

}

130+

}

131+132+

function firstHookEvent(): Record<string, unknown> {

133+

return requireRecord(mockCall(triggerInternalHookMock)[0], "hook event");

134+

}

135+108136

describe("handleCommands reset hooks", () => {

109137

let clearBootstrapSnapshotSpy: ReturnType<typeof vi.spyOn>;

110138

@@ -128,7 +156,7 @@ describe("handleCommands reset hooks", () => {

128156

commands: { text: true },

129157

channels: { whatsapp: { allowFrom: ["*"] } },

130158

} as OpenClawConfig),

131-

expectedCall: expect.objectContaining({ type: "command", action: "new" }),

159+

expectedEvent: { type: "command", action: "new" },

132160

},

133161

{

134162

name: "native command routed to target session",

@@ -154,20 +182,24 @@ describe("handleCommands reset hooks", () => {

154182

params.sessionKey = "agent:main:telegram:direct:123";

155183

return params;

156184

})(),

157-

expectedCall: expect.objectContaining({

185+

expectedEvent: {

158186

type: "command",

159187

action: "new",

160188

sessionKey: "agent:main:telegram:direct:123",

161-

context: expect.objectContaining({

162-

workspaceDir: "/tmp/openclaw-commands",

163-

}),

164-

}),

189+

},

190+

expectedContext: {

191+

workspaceDir: "/tmp/openclaw-commands",

192+

},

165193

},

166194

] as const;

167195168196

for (const testCase of cases) {

169197

await maybeHandleResetCommand(testCase.params);

170-

expect(triggerInternalHookMock, testCase.name).toHaveBeenCalledWith(testCase.expectedCall);

198+

const event = firstHookEvent();

199+

expectObjectFields(event, testCase.expectedEvent, testCase.name);

200+

if ("expectedContext" in testCase) {

201+

expectObjectFields(event.context, testCase.expectedContext, `${testCase.name}.context`);

202+

}

171203

triggerInternalHookMock.mockClear();

172204

}

173205

});

@@ -191,8 +223,13 @@ describe("handleCommands reset hooks", () => {

191223192224

const result = await maybeHandleResetCommand(params);

193225194-

expect(resetMocks.resetConfiguredBindingTargetInPlace).toHaveBeenCalledWith({

195-

cfg: expect.any(Object),

226+

const resetArgs = requireRecord(

227+

mockCall(resetMocks.resetConfiguredBindingTargetInPlace)[0],

228+

"reset args",

229+

);

230+

expect(resetArgs.cfg).toBeTypeOf("object");

231+

expect(resetArgs.cfg).not.toBeNull();

232+

expectObjectFields(resetArgs, {

196233

sessionKey: "agent:claude:acp:binding:discord:default:9373ab192b2317f4",

197234

reason: "reset",

198235

commandSource: "discord:native",

@@ -253,15 +290,13 @@ describe("handleCommands reset hooks", () => {

253290254291

const result = await maybeHandleResetCommand(params);

255292256-

expect(routeReplyMock).toHaveBeenCalledWith(

257-

expect.objectContaining({

258-

requesterSenderId: "id:whatsapp:123",

259-

requesterSenderName: "Alice",

260-

requesterSenderUsername: "alice_u",

261-

requesterSenderE164: "+15551234567",

262-

threadId: "thread-1",

263-

}),

264-

);

293+

expectObjectFields(mockCall(routeReplyMock)[0], {

294+

requesterSenderId: "id:whatsapp:123",

295+

requesterSenderName: "Alice",

296+

requesterSenderUsername: "alice_u",

297+

requesterSenderE164: "+15551234567",

298+

threadId: "thread-1",

299+

});

265300

expect(result).toEqual({ shouldContinue: false });

266301

});

267302

@@ -283,15 +318,9 @@ describe("handleCommands reset hooks", () => {

283318284319

await maybeHandleResetCommand(params);

285320286-

expect(triggerInternalHookMock).toHaveBeenCalledWith(

287-

expect.objectContaining({

288-

context: expect.objectContaining({

289-

sessionEntry: expect.objectContaining({

290-

sessionId: "target-session",

291-

}),

292-

}),

293-

}),

294-

);

321+

const event = firstHookEvent();

322+

const context = requireRecord(event.context, "hook context");

323+

expectObjectFields(context.sessionEntry, { sessionId: "target-session" }, "session entry");

295324

});

296325297326

it("marks soft reset turns and emits reset hooks", async () => {

@@ -315,17 +344,10 @@ describe("handleCommands reset hooks", () => {

315344

const result = await maybeHandleResetCommand(params);

316345317346

expect(result).toBeNull();

318-

expect(triggerInternalHookMock).toHaveBeenCalledWith(

319-

expect.objectContaining({

320-

type: "command",

321-

action: "reset",

322-

context: expect.objectContaining({

323-

previousSessionEntry: expect.objectContaining({

324-

sessionId: "session-1",

325-

}),

326-

}),

327-

}),

328-

);

347+

const event = firstHookEvent();

348+

expectObjectFields(event, { type: "command", action: "reset" }, "hook event");

349+

const context = requireRecord(event.context, "hook context");

350+

expectObjectFields(context.previousSessionEntry, { sessionId: "session-1" }, "session entry");

329351

expect(params.command.resetHookTriggered).toBe(true);

330352

expect(params.command.softResetTriggered).toBe(true);

331353

expect(params.command.softResetTail).toBe("");

@@ -444,9 +466,7 @@ describe("handleCommands reset hooks", () => {

444466

shouldContinue: false,

445467

reply: { text: "✅ Session reset." },

446468

});

447-

expect(triggerInternalHookMock).toHaveBeenCalledWith(

448-

expect.objectContaining({ type: "command", action: "reset" }),

449-

);

469+

expectObjectFields(firstHookEvent(), { type: "command", action: "reset" }, "hook event");

450470

});

451471452472

it("acknowledges bare /new without falling through to model execution", async () => {

@@ -461,9 +481,7 @@ describe("handleCommands reset hooks", () => {

461481

shouldContinue: false,

462482

reply: { text: "✅ New session started." },

463483

});

464-

expect(triggerInternalHookMock).toHaveBeenCalledWith(

465-

expect.objectContaining({ type: "command", action: "new" }),

466-

);

484+

expectObjectFields(firstHookEvent(), { type: "command", action: "new" }, "hook event");

467485

});

468486469487

it("keeps reset tails falling through so the model receives the user input", async () => {

@@ -475,8 +493,6 @@ describe("handleCommands reset hooks", () => {

475493

const result = await maybeHandleResetCommand(params);

476494477495

expect(result).toBeNull();

478-

expect(triggerInternalHookMock).toHaveBeenCalledWith(

479-

expect.objectContaining({ type: "command", action: "new" }),

480-

);

496+

expectObjectFields(firstHookEvent(), { type: "command", action: "new" }, "hook event");

481497

});

482498

});