Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { ChannelId, ChannelPlugin } from "../channels/plugins/types.public.js";
import {
loadFreshAgentsBindCommandModuleForTest,
readConfigFileSnapshotMock,
resetAgentsBindTestHarness,
runtime,
writeConfigFileMock,
} from "./agents.bind.test-support.js";
import { baseConfigSnapshot } from "./test-runtime-config-helpers.js";
vi.mock("../agents/agent-scope.js", () => ({
listAgentEntries: (
cfg: {
agents?: { list?: Array<{ id: string; default?: boolean }> };
} | null,
) => cfg?.agents?.list ?? [],
resolveDefaultAgentId: (
cfg: {
agents?: { list?: Array<{ id: string; default?: boolean }> };
} | null,
) => cfg?.agents?.list?.find((agent) => agent.default)?.id ?? "main",
}));
vi.mock("../config/bindings.js", () => ({
isRouteBinding: (binding: { match?: unknown }) => Boolean(binding.match),
listRouteBindings: (cfg: { bindings?: Array<{ match?: unknown }> }) =>
(cfg.bindings ?? []).filter((binding) => Boolean(binding.match)),
}));
type BindingResolverTestPlugin = Pick<ChannelPlugin, "id" | "meta" | "capabilities" | "config"> & {
setup?: Pick<NonNullable<ChannelPlugin["setup"]>, "resolveBindingAccountId">;
};
function createBindingResolverTestPlugin(params: {
id: ChannelId;
config: Partial<ChannelPlugin["config"]>;
resolveBindingAccountId?: NonNullable<ChannelPlugin["setup"]>["resolveBindingAccountId"];
}): BindingResolverTestPlugin {
return {
id: params.id,
meta: {
id: params.id,
label: params.id,
selectionLabel: params.id,
docsPath: `/channels/${params.id}`,
blurb: "test stub.",
},
capabilities: { chatTypes: ["direct"] },
config: {
listAccountIds: () => ["default"],
resolveAccount: () => ({}),
...params.config,
},
...(params.resolveBindingAccountId
? { setup: { resolveBindingAccountId: params.resolveBindingAccountId } }
: {}),
};
}
vi.mock("../channels/plugins/index.js", () => {
const knownChannels = new Map([
[
"discord",
createBindingResolverTestPlugin({ id: "discord", config: { listAccountIds: () => [] } }),
],
[
"matrix",
createBindingResolverTestPlugin({
id: "matrix",
config: { listAccountIds: () => [] },
resolveBindingAccountId: ({ agentId }) => agentId.toLowerCase(),
}),
],
[
"telegram",
createBindingResolverTestPlugin({ id: "telegram", config: { listAccountIds: () => [] } }),
],
]);
return {
getChannelPlugin: (channel: string) => {
const normalized = channel.trim().toLowerCase();
return knownChannels.get(normalized);
},
normalizeChannelId: (channel: string) => {
const normalized = channel.trim().toLowerCase();
if (knownChannels.has(normalized)) {
return normalized;
}
return undefined;
},
};
});
let agentsBindCommand: typeof import("./agents.commands.bind.js").agentsBindCommand;
let agentsBindingsCommand: typeof import("./agents.commands.bind.js").agentsBindingsCommand;
let agentsUnbindCommand: typeof import("./agents.commands.bind.js").agentsUnbindCommand;
describe("agents bind/unbind commands", () => {
beforeAll(async () => {
({ agentsBindCommand, agentsBindingsCommand, agentsUnbindCommand } =
await loadFreshAgentsBindCommandModuleForTest());
});
beforeEach(() => {
resetAgentsBindTestHarness();
});
it("lists all bindings by default", async () => {
readConfigFileSnapshotMock.mockResolvedValue({
...baseConfigSnapshot,
config: {
bindings: [
{ agentId: "main", match: { channel: "matrix" } },
{ agentId: "ops", match: { channel: "telegram", accountId: "work" } },
],
},
});
await agentsBindingsCommand({}, runtime);
expect(runtime.log).toHaveBeenCalledWith(expect.stringContaining("main <- matrix"));
expect(runtime.log).toHaveBeenCalledWith(
expect.stringContaining("ops <- telegram accountId=work"),
);
});
it("binds routes to default agent when --agent is omitted", async () => {
readConfigFileSnapshotMock.mockResolvedValue({
...baseConfigSnapshot,
config: {},
});
await agentsBindCommand({ bind: ["telegram"] }, runtime);
expect(writeConfigFileMock).toHaveBeenCalledWith(
expect.objectContaining({
bindings: [{ type: "route", agentId: "main", match: { channel: "telegram" } }],
}),
);
expect(runtime.exit).not.toHaveBeenCalled();
});
it("unbinds all routes for an agent", async () => {
readConfigFileSnapshotMock.mockResolvedValue({
...baseConfigSnapshot,
config: {
agents: { list: [{ id: "ops", workspace: "/tmp/ops" }] },
bindings: [
{ agentId: "main", match: { channel: "matrix" } },
{ agentId: "ops", match: { channel: "telegram", accountId: "work" } },
],
},
});
await agentsUnbindCommand({ agent: "ops", all: true }, runtime);
expect(writeConfigFileMock).toHaveBeenCalledWith(
expect.objectContaining({
bindings: [{ agentId: "main", match: { channel: "matrix" } }],
}),
);
expect(runtime.exit).not.toHaveBeenCalled();
});
it("reports ownership conflicts during unbind and exits 1", async () => {
readConfigFileSnapshotMock.mockResolvedValue({
...baseConfigSnapshot,
config: {
agents: { list: [{ id: "ops", workspace: "/tmp/ops" }] },
bindings: [{ agentId: "main", match: { channel: "telegram", accountId: "ops" } }],
},
});
await agentsUnbindCommand({ agent: "ops", bind: ["telegram:ops"] }, runtime);
expect(writeConfigFileMock).not.toHaveBeenCalled();
expect(runtime.error).toHaveBeenCalledWith("Bindings are owned by another agent:");
expect(runtime.exit).toHaveBeenCalledWith(1);
});
});
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-04-27)
¤
*© Formatika GbR, Deutschland
|
|