Skip to content

Commit ab192eb

Browse files
committed
test: tighten helper assertion guards
1 parent c9053ff commit ab192eb

9 files changed

Lines changed: 87 additions & 54 deletions

File tree

extensions/google/google-shared.test-helpers.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ function makeZeroUsageSnapshot() {
1919
}
2020

2121
export const asRecord = (value: unknown): Record<string, unknown> => {
22-
expect(value).toBeTruthy();
23-
expect(typeof value).toBe("object");
24-
expect(Array.isArray(value)).toBe(false);
22+
if (!value || typeof value !== "object" || Array.isArray(value)) {
23+
throw new Error("expected record");
24+
}
2525
return value as Record<string, unknown>;
2626
};
2727

src/agents/sandbox/fs-bridge.test-helpers.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,11 @@ export async function expectMkdirpAllowsExistingDirectory(params?: {
225225
getDockerScript(args).includes("operation = sys.argv[1]") &&
226226
getDockerArg(args, 1) === "mkdirp",
227227
);
228-
expect(mkdirCall).toBeDefined();
229-
const mountRoot = mkdirCall ? getDockerArg(mkdirCall[0], 2) : "";
230-
const relativePath = mkdirCall ? getDockerArg(mkdirCall[0], 3) : "";
228+
if (!mkdirCall) {
229+
throw new Error("expected docker mkdirp call");
230+
}
231+
const mountRoot = getDockerArg(mkdirCall[0], 2);
232+
const relativePath = getDockerArg(mkdirCall[0], 3);
231233
expect(mountRoot).toBe("/workspace");
232234
expect(relativePath).toBe("memory/kemik");
233235
});

src/agents/test-helpers/pi-tools-fs-helpers.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,27 @@ export function getTextContent(result?: { content?: TextResultBlock[] }) {
77
return textBlock?.text ?? "";
88
}
99

10+
function expectTool<T extends { name: string }>(tools: T[], name: string): T {
11+
const tool = tools.find((entry) => entry.name === name);
12+
if (!tool) {
13+
throw new Error(`expected tool "${name}" in [${tools.map((entry) => entry.name).join(", ")}]`);
14+
}
15+
return tool;
16+
}
17+
1018
export function expectReadWriteEditTools<T extends { name: string }>(tools: T[]) {
11-
const readTool = tools.find((tool) => tool.name === "read");
12-
const writeTool = tools.find((tool) => tool.name === "write");
13-
const editTool = tools.find((tool) => tool.name === "edit");
14-
expect(readTool).toBeDefined();
15-
expect(writeTool).toBeDefined();
16-
expect(editTool).toBeDefined();
19+
expect(tools.map((tool) => tool.name)).toEqual(expect.arrayContaining(["read", "write", "edit"]));
1720
return {
18-
readTool: readTool as T,
19-
writeTool: writeTool as T,
20-
editTool: editTool as T,
21+
readTool: expectTool(tools, "read"),
22+
writeTool: expectTool(tools, "write"),
23+
editTool: expectTool(tools, "edit"),
2124
};
2225
}
2326

2427
export function expectReadWriteTools<T extends { name: string }>(tools: T[]) {
25-
const readTool = tools.find((tool) => tool.name === "read");
26-
const writeTool = tools.find((tool) => tool.name === "write");
27-
expect(readTool).toBeDefined();
28-
expect(writeTool).toBeDefined();
28+
expect(tools.map((tool) => tool.name)).toEqual(expect.arrayContaining(["read", "write"]));
2929
return {
30-
readTool: readTool as T,
31-
writeTool: writeTool as T,
30+
readTool: expectTool(tools, "read"),
31+
writeTool: expectTool(tools, "write"),
3232
};
3333
}

src/gateway/device-authz.test-helpers.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ export async function issueOperatorToken(params: {
8686
});
8787
expect(rotated.ok).toBe(true);
8888
const token = rotated.ok ? rotated.entry.token : "";
89-
expect(token).toBeTruthy();
89+
if (!token) {
90+
throw new Error(`expected rotated operator token for device ${paired.identity.deviceId}`);
91+
}
9092
return {
9193
deviceId: paired.identity.deviceId,
9294
identityPath: paired.identityPath,
@@ -96,7 +98,9 @@ export async function issueOperatorToken(params: {
9698

9799
const device = await getPairedDevice(paired.identity.deviceId);
98100
const token = device?.tokens?.operator?.token ?? "";
99-
expect(token).toBeTruthy();
101+
if (!token) {
102+
throw new Error(`expected operator token for paired device ${paired.identity.deviceId}`);
103+
}
100104
expect(device?.approvedScopes).toEqual(params.approvedScopes);
101105
return {
102106
deviceId: paired.identity.deviceId,

src/gateway/server.auth.control-ui.suite.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ export function registerControlUiAndPairingSuite(): void {
176176
deviceId: string,
177177
) => {
178178
const metadata = paired[deviceId];
179-
expect(metadata).toBeTruthy();
180179
if (!metadata) {
181180
throw new Error(`Expected paired metadata for deviceId=${deviceId}`);
182181
}
@@ -244,7 +243,9 @@ export function registerControlUiAndPairingSuite(): void {
244243
let device: Awaited<ReturnType<typeof createSignedDevice>>["device"] | null = null;
245244
if (tc.withUnpairedNodeDevice) {
246245
const challengeNonce = await readConnectChallengeNonce(ws);
247-
expect(challengeNonce, tc.name).toBeTruthy();
246+
if (!challengeNonce) {
247+
throw new Error(`expected connect challenge nonce for ${tc.name}`);
248+
}
248249
({ device } = await createSignedDevice({
249250
token: null,
250251
role: "node",
@@ -488,7 +489,9 @@ export function registerControlUiAndPairingSuite(): void {
488489
await withControlUiGatewayServer(async ({ port }) => {
489490
const staleDeviceWs = await openWs(port, { origin: originForPort(port) });
490491
const challengeNonce = await readConnectChallengeNonce(staleDeviceWs);
491-
expect(challengeNonce, "stale device challenge").toBeTruthy();
492+
if (!challengeNonce) {
493+
throw new Error("expected stale device challenge nonce");
494+
}
492495
const { device } = await createSignedDevice({
493496
token: "secret",
494497
scopes: [],
@@ -735,7 +738,9 @@ export function registerControlUiAndPairingSuite(): void {
735738
(entry) => entry.deviceId === identity.deviceId,
736739
);
737740
expect(pendingAfterRead).toHaveLength(0);
738-
expect(await getPairedDevice(identity.deviceId)).toBeTruthy();
741+
if (!(await getPairedDevice(identity.deviceId))) {
742+
throw new Error(`expected paired device ${identity.deviceId}`);
743+
}
739744
wsRemoteRead.close();
740745

741746
const ws2 = await openWs(port, { host: "gateway.example" });
@@ -759,7 +764,9 @@ export function registerControlUiAndPairingSuite(): void {
759764
);
760765
expect(pendingAfterAdmin).toHaveLength(1);
761766
expect(pendingAfterAdmin[0]?.scopes ?? []).toEqual(expect.arrayContaining(["operator.admin"]));
762-
expect(await getPairedDevice(identity.deviceId)).toBeTruthy();
767+
if (!(await getPairedDevice(identity.deviceId))) {
768+
throw new Error(`expected paired device ${identity.deviceId}`);
769+
}
763770
ws2.close();
764771
await server.close();
765772
restoreGatewayToken(prevToken);
@@ -941,8 +948,9 @@ export function registerControlUiAndPairingSuite(): void {
941948
const issuedOperatorToken = initialPayload?.auth?.deviceTokens?.find(
942949
(entry) => entry.role === "operator",
943950
)?.deviceToken;
944-
expect(issuedDeviceToken).toBeDefined();
945-
expect(issuedOperatorToken).toBeDefined();
951+
if (!issuedDeviceToken || !issuedOperatorToken) {
952+
throw new Error("expected issued device and operator tokens");
953+
}
946954
expect(initialPayload?.auth?.role).toBe("node");
947955
expect(initialPayload?.auth?.scopes ?? []).toEqual([]);
948956
expect(initialPayload?.auth?.deviceTokens?.some((entry) => entry.role === "node")).toBe(
@@ -1498,7 +1506,9 @@ export function registerControlUiAndPairingSuite(): void {
14981506
const pendingUpgrade = (await listDevicePairing()).pending.find(
14991507
(entry) => entry.deviceId === identity.deviceId,
15001508
);
1501-
expect(pendingUpgrade).toBeTruthy();
1509+
if (!pendingUpgrade) {
1510+
throw new Error(`expected pending upgrade for device ${identity.deviceId}`);
1511+
}
15021512
expect(pendingUpgrade?.scopes ?? []).toEqual(expect.arrayContaining(["operator.admin"]));
15031513
const repaired = await getPairedDevice(identity.deviceId);
15041514
expect(repaired?.role).toBe("operator");
@@ -1596,7 +1606,9 @@ export function registerControlUiAndPairingSuite(): void {
15961606
expect(dockerCli.ok).toBe(true);
15971607
const pending = await listDevicePairing();
15981608
expect(pending.pending.filter((entry) => entry.deviceId === identity.deviceId)).toEqual([]);
1599-
expect(await getPairedDevice(identity.deviceId)).toBeTruthy();
1609+
if (!(await getPairedDevice(identity.deviceId))) {
1610+
throw new Error(`expected paired device ${identity.deviceId}`);
1611+
}
16001612
} finally {
16011613
wsDockerCli.close();
16021614
await server.close();

src/gateway/server.auth.default-token.suite.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,9 @@ export function registerDefaultAuthTokenSuite(): void {
361361
const presence = helloOk?.snapshot?.presence;
362362
expect(Array.isArray(presence)).toBe(true);
363363
const mine = presence?.find((entry) => entry.deviceId === identity.deviceId);
364-
expect(mine).toBeTruthy();
364+
if (!mine) {
365+
throw new Error(`expected presence entry for device ${identity.deviceId}`);
366+
}
365367
const presenceScopes = Array.isArray(mine?.scopes) ? mine?.scopes : [];
366368
expect(presenceScopes).toEqual([]);
367369
expect(presenceScopes).not.toContain("operator.admin");

src/gateway/server.auth.shared.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,20 +204,22 @@ function resolveGatewayTokenOrEnv(): string {
204204
typeof (testState.gatewayAuth as { token?: unknown } | undefined)?.token === "string"
205205
? ((testState.gatewayAuth as { token?: string }).token ?? undefined)
206206
: process.env.OPENCLAW_GATEWAY_TOKEN;
207-
expect(typeof token).toBe("string");
208-
return token ?? "";
207+
if (typeof token !== "string") {
208+
throw new Error("expected gateway token in test state or OPENCLAW_GATEWAY_TOKEN");
209+
}
210+
return token;
209211
}
210212

211213
async function approvePendingPairingIfNeeded() {
212214
const { approveDevicePairing, listDevicePairing } = await import("../infra/device-pairing.js");
213215
const list = await listDevicePairing();
214216
const pending = list.pending.at(0);
215-
expect(pending?.requestId).toBeDefined();
216-
if (pending?.requestId) {
217-
await approveDevicePairing(pending.requestId, {
218-
callerScopes: pending.scopes ?? ["operator.admin"],
219-
});
217+
if (!pending?.requestId) {
218+
throw new Error("expected pending pairing request");
220219
}
220+
await approveDevicePairing(pending.requestId, {
221+
callerScopes: pending.scopes ?? ["operator.admin"],
222+
});
221223
}
222224

223225
async function configureTrustedProxyControlUiAuth() {
@@ -325,8 +327,10 @@ async function resolvePairedTokenForDeviceIdentityPath(deviceIdentityPath: strin
325327
const paired = await getPairedDevice(identity.deviceId);
326328
const deviceToken = paired?.tokens?.operator?.token;
327329
expect(paired?.deviceId).toBe(identity.deviceId);
328-
expect(deviceToken).toBeDefined();
329-
return { identity: { deviceId: identity.deviceId }, deviceToken: deviceToken ?? "" };
330+
if (!deviceToken) {
331+
throw new Error(`expected operator token for paired device ${identity.deviceId}`);
332+
}
333+
return { identity: { deviceId: identity.deviceId }, deviceToken };
330334
}
331335

332336
async function startRateLimitedTokenServerWithPairedDeviceToken() {

src/plugins/contracts/tts-contract-suites.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,10 @@ export function describeTtsSummarizationContract() {
944944
`Invalid targetLength: ${testCase.targetLength}`,
945945
);
946946
} else {
947-
await expect(call, String(testCase.targetLength)).resolves.toBeDefined();
947+
await expect(call, String(testCase.targetLength)).resolves.toMatchObject({
948+
summary: expect.any(String),
949+
inputLength: 4,
950+
});
948951
}
949952
});
950953

@@ -1159,8 +1162,10 @@ export function describeTtsProviderRuntimeContract() {
11591162
if (result.success) {
11601163
throw new Error("expected synthesis failure");
11611164
}
1162-
expect(result.error).toBeDefined();
1163-
const errorMessage = result.error ?? "";
1165+
const errorMessage = result.error;
1166+
if (typeof errorMessage !== "string") {
1167+
throw new Error("expected synthesis failure error message");
1168+
}
11641169
expect(errorMessage).toBe("TTS conversion failed: openai: provider failed");
11651170
expect(errorMessage).not.toContain("TTS conversion failed: TTS conversion failed:");
11661171
expect(errorMessage.match(/TTS conversion failed:/g)).toHaveLength(1);
@@ -1259,7 +1264,9 @@ export function describeTtsAutoApplyContract() {
12591264
if (params.expectSamePayload) {
12601265
expect(result).toBe(params.payload);
12611266
} else {
1262-
expect(result.mediaUrl).toBeDefined();
1267+
if (typeof result.mediaUrl !== "string" || result.mediaUrl.length === 0) {
1268+
throw new Error("expected auto TTS to attach mediaUrl");
1269+
}
12631270
}
12641271
});
12651272
}

src/test-helpers/resolve-target-error-cases.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ export function installCommonResolveTargetErrorCases(params: {
1919
implicitAllowFrom: string[];
2020
}) {
2121
const { resolveTarget, implicitAllowFrom } = params;
22+
const expectResolveTargetError = (result: ResolveTargetResult) => {
23+
expect(result.ok).toBe(false);
24+
if (result.error === undefined) {
25+
throw new Error("expected resolveTarget to return an error");
26+
}
27+
};
2228

2329
it("should error on normalization failure with allowlist (implicit mode)", () => {
2430
const result = resolveTarget({
@@ -27,8 +33,7 @@ export function installCommonResolveTargetErrorCases(params: {
2733
allowFrom: implicitAllowFrom,
2834
});
2935

30-
expect(result.ok).toBe(false);
31-
expect(result.error).toBeDefined();
36+
expectResolveTargetError(result);
3237
});
3338

3439
it("should error when no target provided with allowlist", () => {
@@ -38,8 +43,7 @@ export function installCommonResolveTargetErrorCases(params: {
3843
allowFrom: implicitAllowFrom,
3944
});
4045

41-
expect(result.ok).toBe(false);
42-
expect(result.error).toBeDefined();
46+
expectResolveTargetError(result);
4347
});
4448

4549
it("should error when no target and no allowlist", () => {
@@ -49,8 +53,7 @@ export function installCommonResolveTargetErrorCases(params: {
4953
allowFrom: [],
5054
});
5155

52-
expect(result.ok).toBe(false);
53-
expect(result.error).toBeDefined();
56+
expectResolveTargetError(result);
5457
});
5558

5659
it("should handle whitespace-only target", () => {
@@ -60,7 +63,6 @@ export function installCommonResolveTargetErrorCases(params: {
6063
allowFrom: [],
6164
});
6265

63-
expect(result.ok).toBe(false);
64-
expect(result.error).toBeDefined();
66+
expectResolveTargetError(result);
6567
});
6668
}

0 commit comments

Comments
 (0)