mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-22 14:17:14 +00:00
test: tighten gateway array assertions
This commit is contained in:
@@ -576,7 +576,7 @@ describe("callGateway url resolution", () => {
|
||||
expect(lastClientOptions?.scopes).toEqual(["operator.read"]);
|
||||
|
||||
await callGatewayScoped({ method: "health", scopes: [] });
|
||||
expect(lastClientOptions?.scopes).toEqual([]);
|
||||
expect(lastClientOptions?.scopes).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("uses backend client metadata for explicit scoped default calls", async () => {
|
||||
|
||||
@@ -394,7 +394,7 @@ describe("parseMessageWithAttachments validation errors", () => {
|
||||
|
||||
try {
|
||||
expect(parsed.images).toHaveLength(0);
|
||||
expect(parsed.imageOrder).toEqual([]);
|
||||
expect(parsed.imageOrder).toStrictEqual([]);
|
||||
expect(parsed.offloadedRefs).toHaveLength(1);
|
||||
expect(parsed.offloadedRefs[0]).toMatchObject({
|
||||
mimeType: "application/pdf",
|
||||
|
||||
@@ -64,7 +64,7 @@ describe("diffConfigPaths", () => {
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(diffConfigPaths(prev, next)).toEqual([]);
|
||||
expect(diffConfigPaths(prev, next)).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("reports changed arrays of objects", () => {
|
||||
@@ -190,7 +190,7 @@ describe("buildGatewayReloadPlan", () => {
|
||||
const plan = buildGatewayReloadPlan(["browser.enabled"]);
|
||||
expect(plan.restartGateway).toBe(true);
|
||||
expect(plan.restartReasons).toContain("browser.enabled");
|
||||
expect(plan.hotReasons).toEqual([]);
|
||||
expect(plan.hotReasons).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("restarts the Gmail watcher for hooks.gmail changes", () => {
|
||||
@@ -270,7 +270,7 @@ describe("buildGatewayReloadPlan", () => {
|
||||
expect(plan.restartGateway).toBe(true);
|
||||
expect(plan.restartReasons).toContain("models.pricing.enabled");
|
||||
expect(plan.restartHeartbeat).toBe(false);
|
||||
expect(plan.hotReasons).toEqual([]);
|
||||
expect(plan.hotReasons).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("restarts heartbeat when agents.defaults.models allowlist changes", () => {
|
||||
@@ -278,7 +278,7 @@ describe("buildGatewayReloadPlan", () => {
|
||||
expect(plan.restartGateway).toBe(false);
|
||||
expect(plan.restartHeartbeat).toBe(true);
|
||||
expect(plan.hotReasons).toContain("agents.defaults.models");
|
||||
expect(plan.noopPaths).toEqual([]);
|
||||
expect(plan.noopPaths).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("restarts heartbeat when agents.list entries change", () => {
|
||||
@@ -286,7 +286,7 @@ describe("buildGatewayReloadPlan", () => {
|
||||
expect(plan.restartGateway).toBe(false);
|
||||
expect(plan.restartHeartbeat).toBe(true);
|
||||
expect(plan.hotReasons).toContain("agents.list");
|
||||
expect(plan.noopPaths).toEqual([]);
|
||||
expect(plan.noopPaths).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("treats plugin install timestamp-only changes as no-op", () => {
|
||||
@@ -317,7 +317,7 @@ describe("buildGatewayReloadPlan", () => {
|
||||
"plugins.installs.lossless.resolvedAt",
|
||||
"plugins.installs.lossless.resolvedAt",
|
||||
]);
|
||||
expect(plan.noopPaths).toEqual([]);
|
||||
expect(plan.noopPaths).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("requires restart when plugin load paths change", () => {
|
||||
@@ -722,14 +722,14 @@ describe("startGatewayConfigReloader", () => {
|
||||
expect(onHotReload).not.toHaveBeenCalled();
|
||||
expect(onRestart).toHaveBeenCalledTimes(1);
|
||||
expect(log.error).toHaveBeenCalledWith("config restart failed: Error: restart-check failed");
|
||||
expect(unhandled).toEqual([]);
|
||||
expect(unhandled).toStrictEqual([]);
|
||||
|
||||
watcher.emit("change");
|
||||
await vi.runOnlyPendingTimersAsync();
|
||||
await Promise.resolve();
|
||||
|
||||
expect(onRestart).toHaveBeenCalledTimes(2);
|
||||
expect(unhandled).toEqual([]);
|
||||
expect(unhandled).toStrictEqual([]);
|
||||
} finally {
|
||||
process.off("unhandledRejection", onUnhandled);
|
||||
await reloader.stop();
|
||||
|
||||
@@ -63,7 +63,7 @@ describe("resolveTrustedHttpOperatorScopes", () => {
|
||||
tokenAuth,
|
||||
);
|
||||
|
||||
expect(scopes).toEqual([]);
|
||||
expect(scopes).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("keeps declared scopes for non-bearer HTTP requests", () => {
|
||||
@@ -98,7 +98,7 @@ describe("resolveTrustedHttpOperatorScopes", () => {
|
||||
{ trustDeclaredOperatorScopes: false },
|
||||
);
|
||||
|
||||
expect(scopes).toEqual([]);
|
||||
expect(scopes).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -62,11 +62,13 @@ describe("method scope resolution", () => {
|
||||
});
|
||||
|
||||
it("leaves node-only pending drain outside operator scopes", () => {
|
||||
expect(resolveLeastPrivilegeOperatorScopesForMethod("node.pending.drain")).toEqual([]);
|
||||
expect(resolveLeastPrivilegeOperatorScopesForMethod("node.pending.drain")).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("returns empty scopes for unknown methods", () => {
|
||||
expect(resolveLeastPrivilegeOperatorScopesForMethod("totally.unknown.method")).toEqual([]);
|
||||
expect(resolveLeastPrivilegeOperatorScopesForMethod("totally.unknown.method")).toStrictEqual(
|
||||
[],
|
||||
);
|
||||
});
|
||||
|
||||
it("reads plugin-registered gateway method scopes from the active plugin registry", () => {
|
||||
@@ -228,14 +230,14 @@ describe("core gateway method classification", () => {
|
||||
const unclassified = Object.keys(coreGatewayHandlers).filter(
|
||||
(method) => !isGatewayMethodClassified(method),
|
||||
);
|
||||
expect(unclassified).toEqual([]);
|
||||
expect(unclassified).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("classifies every listed gateway method name", () => {
|
||||
const unclassified = listGatewayMethods().filter(
|
||||
(method) => !isGatewayMethodClassified(method),
|
||||
);
|
||||
expect(unclassified).toEqual([]);
|
||||
expect(unclassified).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1151,7 +1151,7 @@ describe("OpenAI-compatible HTTP API (e2e)", () => {
|
||||
completion_tokens: 5,
|
||||
total_tokens: 20,
|
||||
});
|
||||
expect(usageChunk?.choices).toEqual([]);
|
||||
expect(usageChunk?.choices).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("keeps aggregate-only usage total in final stream usage chunk", async () => {
|
||||
|
||||
@@ -1217,7 +1217,7 @@ describe("OpenResponses HTTP API (e2e)", () => {
|
||||
await vi.waitFor(() => {
|
||||
expect(agentCommand.mock.calls).toHaveLength(1);
|
||||
});
|
||||
expect(openResponsesTesting.getResponseSessionIds()).toEqual([]);
|
||||
expect(openResponsesTesting.getResponseSessionIds()).toStrictEqual([]);
|
||||
|
||||
release?.({ payloads: [{ text: "hello" }] });
|
||||
|
||||
|
||||
@@ -791,14 +791,14 @@ describe("chat directive tag stripping for non-streaming final payloads", () =>
|
||||
);
|
||||
// Agent-run delivery is a live projection; Pi message_end owns persisted
|
||||
// assistant transcript entries, including stale media/text final payloads.
|
||||
expect(assistantUpdates).toEqual([]);
|
||||
expect(assistantUpdates).toStrictEqual([]);
|
||||
const transcriptLines = readTranscriptJsonLines(mockState.transcriptPath);
|
||||
const assistantEntries = transcriptLines.filter(
|
||||
(entry) =>
|
||||
(entry as { message?: { role?: string } }).message?.role === "assistant" ||
|
||||
(entry as { role?: string }).role === "assistant",
|
||||
);
|
||||
expect(assistantEntries).toEqual([]);
|
||||
expect(assistantEntries).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("does not mirror normal agent-run final text from live delivery", async () => {
|
||||
@@ -838,14 +838,14 @@ describe("chat directive tag stripping for non-streaming final payloads", () =>
|
||||
);
|
||||
// Normal agent-run final text must not be mirrored into JSONL by WebChat;
|
||||
// Pi persists the model-visible assistant turn from message_end.
|
||||
expect(assistantUpdates).toEqual([]);
|
||||
expect(assistantUpdates).toStrictEqual([]);
|
||||
const transcriptLines = readTranscriptJsonLines(mockState.transcriptPath);
|
||||
const assistantEntries = transcriptLines.filter(
|
||||
(entry) =>
|
||||
(entry as { message?: { role?: string } }).message?.role === "assistant" ||
|
||||
(entry as { role?: string }).role === "assistant",
|
||||
);
|
||||
expect(assistantEntries).toEqual([]);
|
||||
expect(assistantEntries).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("keeps visible text on non-agent TTS final media because no model transcript exists", async () => {
|
||||
@@ -2002,7 +2002,7 @@ describe("chat directive tag stripping for non-streaming final payloads", () =>
|
||||
expectBroadcast: false,
|
||||
});
|
||||
|
||||
expect(mockState.lastDispatchCtx?.GatewayClientScopes).toEqual([]);
|
||||
expect(mockState.lastDispatchCtx?.GatewayClientScopes).toStrictEqual([]);
|
||||
expect(mockState.lastDispatchCtx?.CommandBody).toBe("/scopecheck");
|
||||
});
|
||||
|
||||
@@ -2425,7 +2425,7 @@ describe("chat directive tag stripping for non-streaming final payloads", () =>
|
||||
update.message !== null &&
|
||||
(update.message as { role?: unknown }).role === "user",
|
||||
);
|
||||
expect(mockState.savedMediaCalls).toEqual([]);
|
||||
expect(mockState.savedMediaCalls).toStrictEqual([]);
|
||||
expect(userUpdate).toMatchObject({
|
||||
message: {
|
||||
role: "user",
|
||||
@@ -3361,7 +3361,7 @@ describe("chat directive tag stripping for non-streaming final payloads", () =>
|
||||
waitFor: "none",
|
||||
});
|
||||
|
||||
expect(mockState.savedMediaCalls).toEqual([]);
|
||||
expect(mockState.savedMediaCalls).toStrictEqual([]);
|
||||
expect(mockState.lastDispatchImages).toBeUndefined();
|
||||
expect(respond).toHaveBeenCalledWith(true, {
|
||||
ok: true,
|
||||
|
||||
@@ -88,7 +88,7 @@ describe("gateway restart deferral", () => {
|
||||
|
||||
expect(getTotalPendingReplies()).toBe(0);
|
||||
expect(restartTriggered).toBe(false);
|
||||
expect(replyErrors).toEqual([]);
|
||||
expect(replyErrors).toStrictEqual([]);
|
||||
expect(deliveredReplies).toEqual(["Configuration updated!"]);
|
||||
});
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@ describe("gateway server hooks", () => {
|
||||
expect(targetEvents).toEqual(
|
||||
expect.arrayContaining([expect.stringContaining("Hook Email: done")]),
|
||||
);
|
||||
expect(peekSystemEventEntries(resolveMainKey())).toEqual([]);
|
||||
expect(peekSystemEventEntries(resolveMainKey())).toStrictEqual([]);
|
||||
drainSystemEvents(HOOKS_MAIN_SESSION_KEY);
|
||||
});
|
||||
});
|
||||
@@ -362,7 +362,7 @@ describe("gateway server hooks", () => {
|
||||
});
|
||||
expect(directSilent.status).toBe(200);
|
||||
await waitForCronIsolatedRuns(1);
|
||||
expect(peekSystemEventEntries(resolveMainKey())).toEqual([]);
|
||||
expect(peekSystemEventEntries(resolveMainKey())).toStrictEqual([]);
|
||||
|
||||
cronIsolatedRun.mockResolvedValueOnce({
|
||||
status: "ok",
|
||||
@@ -372,7 +372,7 @@ describe("gateway server hooks", () => {
|
||||
const mappedSilent = await postHook(port, "/hooks/mapped-silent", { subject: "Email" });
|
||||
expect(mappedSilent.status).toBe(200);
|
||||
await waitForCronIsolatedRuns(2);
|
||||
expect(peekSystemEventEntries(resolveMainKey())).toEqual([]);
|
||||
expect(peekSystemEventEntries(resolveMainKey())).toStrictEqual([]);
|
||||
|
||||
cronIsolatedRun.mockResolvedValueOnce({
|
||||
status: "error",
|
||||
@@ -409,7 +409,7 @@ describe("gateway server hooks", () => {
|
||||
});
|
||||
expect(response.status).toBe(200);
|
||||
await waitForCronIsolatedRuns(1);
|
||||
expect(peekSystemEventEntries(resolveMainKey())).toEqual([]);
|
||||
expect(peekSystemEventEntries(resolveMainKey())).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -322,7 +322,7 @@ describe("gateway server models + voicewake", () => {
|
||||
expect(initial.ok).toBe(true);
|
||||
expect(initial.payload?.config?.version).toBe(1);
|
||||
expect(initial.payload?.config?.defaultTarget).toEqual({ mode: "current" });
|
||||
expect(initial.payload?.config?.routes).toEqual([]);
|
||||
expect(initial.payload?.config?.routes).toStrictEqual([]);
|
||||
|
||||
const changedP = onceMessage<{
|
||||
type: "event";
|
||||
@@ -444,7 +444,7 @@ describe("gateway server models + voicewake", () => {
|
||||
expect(first.event).toBe("voicewake.routing.changed");
|
||||
expect(
|
||||
(first.payload as { config?: { routes?: unknown[] } } | undefined)?.config?.routes,
|
||||
).toEqual([]);
|
||||
).toStrictEqual([]);
|
||||
|
||||
const broadcastP = onceMessage<{
|
||||
type: "event";
|
||||
@@ -528,7 +528,7 @@ describe("gateway server models + voicewake", () => {
|
||||
const discoverCallsBefore = piSdkMock.discoverCalls;
|
||||
const res = await listModels({ view: "configured" });
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.payload?.models).toEqual([]);
|
||||
expect(res.payload?.models).toStrictEqual([]);
|
||||
expect(piSdkMock.discoverCalls).toBe(discoverCallsBefore);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -154,7 +154,7 @@ describe("gateway trusted CIDR node pairing auto-approve", () => {
|
||||
expect(pending).toHaveLength(0);
|
||||
const paired = await getPairedDevice(loaded.identity.deviceId);
|
||||
expect(paired?.role).toBe("node");
|
||||
expect(paired?.approvedScopes ?? []).toEqual([]);
|
||||
expect(paired?.approvedScopes ?? []).toStrictEqual([]);
|
||||
} finally {
|
||||
ws?.close();
|
||||
await started.server.close();
|
||||
|
||||
@@ -435,7 +435,7 @@ describe("gateway hot reload", () => {
|
||||
);
|
||||
|
||||
await expect(params.applyReload()).rejects.toThrow(params.expectedError);
|
||||
expect(drainSystemEvents(params.sessionKey)).toEqual([]);
|
||||
expect(drainSystemEvents(params.sessionKey)).toStrictEqual([]);
|
||||
}
|
||||
|
||||
async function expectSecretReloadRecovered(params: {
|
||||
|
||||
@@ -37,7 +37,7 @@ describe("gateway tools.catalog", () => {
|
||||
expect(noPlugins.ok).toBe(true);
|
||||
expect(
|
||||
(noPlugins.payload?.groups ?? []).filter((group) => group.source === "plugin"),
|
||||
).toEqual([]);
|
||||
).toStrictEqual([]);
|
||||
|
||||
const unknownAgent = await rpcReq(ws, "tools.catalog", { agentId: "does-not-exist" });
|
||||
expect(unknownAgent.ok).toBe(false);
|
||||
|
||||
@@ -164,7 +164,7 @@ describe("createGatewayPluginRequestHandler", () => {
|
||||
|
||||
expect(handled).toBe(true);
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(observedScopes).toEqual([]);
|
||||
expect(observedScopes).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it("preserves gateway-authenticated plugin route runtime scopes from request auth", async () => {
|
||||
@@ -478,7 +478,7 @@ describe("createGatewayPluginUpgradeHandler", () => {
|
||||
expect(handled).toBe(true);
|
||||
expect(routeUpgradeHandler).toHaveBeenCalledTimes(1);
|
||||
expect(socket.destroyed).toBe(false);
|
||||
expect(socket.chunks).toEqual([]);
|
||||
expect(socket.chunks).toStrictEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1793,7 +1793,7 @@ describe("resolveSessionTranscriptCandidates safety", () => {
|
||||
"/tmp/openclaw/agents/main/sessions/sessions.json",
|
||||
);
|
||||
|
||||
expect(candidates).toEqual([]);
|
||||
expect(candidates).toStrictEqual([]);
|
||||
});
|
||||
|
||||
test("drops unsafe sessionFile candidates and keeps safe fallbacks", () => {
|
||||
@@ -1937,7 +1937,7 @@ describe("archiveSessionTranscripts", () => {
|
||||
reason: "reset",
|
||||
});
|
||||
|
||||
expect(archived).toEqual([]);
|
||||
expect(archived).toStrictEqual([]);
|
||||
});
|
||||
|
||||
test("skips files that do not exist and archives only existing ones", () => {
|
||||
|
||||
@@ -506,7 +506,7 @@ describe("listSessionsFromStore subagent metadata", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.sessions.map((session) => session.key)).toEqual([]);
|
||||
expect(result.sessions.map((session) => session.key)).toStrictEqual([]);
|
||||
});
|
||||
|
||||
test("reports the newest run owner for moved child session rows", () => {
|
||||
@@ -904,7 +904,7 @@ describe("listSessionsFromStore subagent metadata", () => {
|
||||
}),
|
||||
);
|
||||
|
||||
expect(result.sessions).toEqual([]);
|
||||
expect(result.sessions).toStrictEqual([]);
|
||||
const registryStatCount = statSpy.mock.calls.filter(
|
||||
([pathname]) => path.normalize(String(pathname)) === path.normalize(registryPath),
|
||||
).length;
|
||||
@@ -1005,7 +1005,7 @@ describe("listSessionsFromStore subagent metadata", () => {
|
||||
spawnedBy: "agent:main:main",
|
||||
},
|
||||
});
|
||||
expect(filtered.sessions.map((session) => session.key)).toEqual([]);
|
||||
expect(filtered.sessions.map((session) => session.key)).toStrictEqual([]);
|
||||
});
|
||||
|
||||
test("does not reattach stale orphan store-only child links without lifecycle fields", () => {
|
||||
@@ -1041,7 +1041,7 @@ describe("listSessionsFromStore subagent metadata", () => {
|
||||
spawnedBy: "agent:main:main",
|
||||
},
|
||||
});
|
||||
expect(filtered.sessions.map((session) => session.key)).toEqual([]);
|
||||
expect(filtered.sessions.map((session) => session.key)).toStrictEqual([]);
|
||||
});
|
||||
|
||||
test("does not keep old ended registry runs attached as child sessions", () => {
|
||||
@@ -1089,7 +1089,7 @@ describe("listSessionsFromStore subagent metadata", () => {
|
||||
spawnedBy: "agent:main:main",
|
||||
},
|
||||
});
|
||||
expect(filtered.sessions.map((session) => session.key)).toEqual([]);
|
||||
expect(filtered.sessions.map((session) => session.key)).toStrictEqual([]);
|
||||
});
|
||||
|
||||
test("keeps ended parents attached while live descendants are still running", () => {
|
||||
|
||||
Reference in New Issue
Block a user