mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-03 03:03:24 -04:00
test: dedupe shared setup in channel and doctor config tests
This commit is contained in:
@@ -6,7 +6,6 @@ import type { DiscordProbe } from "../../discord/probe.js";
|
||||
import type { DiscordTokenResolution } from "../../discord/token.js";
|
||||
import type { IMessageProbe } from "../../imessage/probe.js";
|
||||
import type { LineProbeResult } from "../../line/types.js";
|
||||
import type { PluginRegistry } from "../../plugins/registry.js";
|
||||
import { setActivePluginRegistry } from "../../plugins/runtime.js";
|
||||
import type { SignalProbe } from "../../signal/probe.js";
|
||||
import type { SlackProbe } from "../../slack/probe.js";
|
||||
@@ -118,23 +117,7 @@ describe("channel plugin catalog", () => {
|
||||
});
|
||||
});
|
||||
|
||||
const createRegistry = (channels: PluginRegistry["channels"]): PluginRegistry => ({
|
||||
plugins: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
typedHooks: [],
|
||||
commands: [],
|
||||
channels,
|
||||
providers: [],
|
||||
gatewayHandlers: {},
|
||||
httpHandlers: [],
|
||||
httpRoutes: [],
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
diagnostics: [],
|
||||
});
|
||||
|
||||
const emptyRegistry = createRegistry([]);
|
||||
const emptyRegistry = createTestRegistry([]);
|
||||
|
||||
const msteamsOutbound: ChannelOutboundAdapter = {
|
||||
deliveryMode: "direct",
|
||||
@@ -160,7 +143,7 @@ const msteamsPlugin: ChannelPlugin = {
|
||||
outbound: msteamsOutbound,
|
||||
};
|
||||
|
||||
const registryWithMSTeams = createRegistry([
|
||||
const registryWithMSTeams = createTestRegistry([
|
||||
{ pluginId: "msteams", plugin: msteamsPlugin, source: "test" },
|
||||
]);
|
||||
|
||||
|
||||
@@ -23,6 +23,19 @@ async function runDoctorConfigWithInput(params: {
|
||||
});
|
||||
}
|
||||
|
||||
function expectGoogleChatDmAllowFromRepaired(cfg: unknown) {
|
||||
const typed = cfg as {
|
||||
channels: {
|
||||
googlechat: {
|
||||
dm: { allowFrom: string[] };
|
||||
allowFrom?: string[];
|
||||
};
|
||||
};
|
||||
};
|
||||
expect(typed.channels.googlechat.dm.allowFrom).toEqual(["*"]);
|
||||
expect(typed.channels.googlechat.allowFrom).toBeUndefined();
|
||||
}
|
||||
|
||||
describe("doctor config flow", () => {
|
||||
it("preserves invalid config for doctor repairs", async () => {
|
||||
const result = await runDoctorConfigWithInput({
|
||||
@@ -361,20 +374,7 @@ describe("doctor config flow", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const cfg = result.cfg as unknown as {
|
||||
channels: {
|
||||
googlechat: {
|
||||
dm: {
|
||||
policy: string;
|
||||
allowFrom: string[];
|
||||
};
|
||||
allowFrom?: string[];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
expect(cfg.channels.googlechat.dm.allowFrom).toEqual(["*"]);
|
||||
expect(cfg.channels.googlechat.allowFrom).toBeUndefined();
|
||||
expectGoogleChatDmAllowFromRepaired(result.cfg);
|
||||
});
|
||||
|
||||
it("repairs googlechat account dm.policy open by setting dm.allowFrom on repair", async () => {
|
||||
@@ -430,19 +430,6 @@ describe("doctor config flow", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const cfg = result.cfg as unknown as {
|
||||
channels: {
|
||||
googlechat: {
|
||||
dm: {
|
||||
policy: string;
|
||||
allowFrom: string[];
|
||||
};
|
||||
allowFrom?: string[];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
expect(cfg.channels.googlechat.dm.allowFrom).toEqual(["*"]);
|
||||
expect(cfg.channels.googlechat.allowFrom).toBeUndefined();
|
||||
expectGoogleChatDmAllowFromRepaired(result.cfg);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,6 +51,26 @@ vi.mock("./daemon-install-helpers.js", () => ({
|
||||
|
||||
import { maybeRepairGatewayServiceConfig } from "./doctor-gateway-services.js";
|
||||
|
||||
function makeDoctorIo() {
|
||||
return { log: vi.fn(), error: vi.fn(), exit: vi.fn() };
|
||||
}
|
||||
|
||||
function makeDoctorPrompts() {
|
||||
return {
|
||||
confirm: vi.fn().mockResolvedValue(true),
|
||||
confirmRepair: vi.fn().mockResolvedValue(true),
|
||||
confirmAggressive: vi.fn().mockResolvedValue(true),
|
||||
confirmSkipInNonInteractive: vi.fn().mockResolvedValue(true),
|
||||
select: vi.fn().mockResolvedValue("node"),
|
||||
shouldRepair: false,
|
||||
shouldForce: false,
|
||||
};
|
||||
}
|
||||
|
||||
async function runRepair(cfg: OpenClawConfig) {
|
||||
await maybeRepairGatewayServiceConfig(cfg, "local", makeDoctorIo(), makeDoctorPrompts());
|
||||
}
|
||||
|
||||
describe("maybeRepairGatewayServiceConfig", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
@@ -91,20 +111,7 @@ describe("maybeRepairGatewayServiceConfig", () => {
|
||||
},
|
||||
};
|
||||
|
||||
await maybeRepairGatewayServiceConfig(
|
||||
cfg,
|
||||
"local",
|
||||
{ log: vi.fn(), error: vi.fn(), exit: vi.fn() },
|
||||
{
|
||||
confirm: vi.fn().mockResolvedValue(true),
|
||||
confirmRepair: vi.fn().mockResolvedValue(true),
|
||||
confirmAggressive: vi.fn().mockResolvedValue(true),
|
||||
confirmSkipInNonInteractive: vi.fn().mockResolvedValue(true),
|
||||
select: vi.fn().mockResolvedValue("node"),
|
||||
shouldRepair: false,
|
||||
shouldForce: false,
|
||||
},
|
||||
);
|
||||
await runRepair(cfg);
|
||||
|
||||
expect(mocks.auditGatewayServiceConfig).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
@@ -164,20 +171,7 @@ describe("maybeRepairGatewayServiceConfig", () => {
|
||||
gateway: {},
|
||||
};
|
||||
|
||||
await maybeRepairGatewayServiceConfig(
|
||||
cfg,
|
||||
"local",
|
||||
{ log: vi.fn(), error: vi.fn(), exit: vi.fn() },
|
||||
{
|
||||
confirm: vi.fn().mockResolvedValue(true),
|
||||
confirmRepair: vi.fn().mockResolvedValue(true),
|
||||
confirmAggressive: vi.fn().mockResolvedValue(true),
|
||||
confirmSkipInNonInteractive: vi.fn().mockResolvedValue(true),
|
||||
select: vi.fn().mockResolvedValue("node"),
|
||||
shouldRepair: false,
|
||||
shouldForce: false,
|
||||
},
|
||||
);
|
||||
await runRepair(cfg);
|
||||
|
||||
expect(mocks.auditGatewayServiceConfig).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import type { ChannelPlugin } from "../channels/plugins/types.js";
|
||||
import type { PluginRegistry } from "../plugins/registry.js";
|
||||
import { setActivePluginRegistry } from "../plugins/runtime.js";
|
||||
import { createTestRegistry } from "../test-utils/channel-plugins.js";
|
||||
import { resolveChannelCapabilities } from "./channel-capabilities.js";
|
||||
import type { OpenClawConfig } from "./config.js";
|
||||
|
||||
@@ -86,7 +86,7 @@ describe("resolveChannelCapabilities", () => {
|
||||
|
||||
it("supports msteams capabilities", () => {
|
||||
setActivePluginRegistry(
|
||||
createRegistry([
|
||||
createTestRegistry([
|
||||
{
|
||||
pluginId: "msteams",
|
||||
source: "test",
|
||||
@@ -127,22 +127,6 @@ describe("resolveChannelCapabilities", () => {
|
||||
});
|
||||
});
|
||||
|
||||
const createRegistry = (channels: PluginRegistry["channels"]): PluginRegistry => ({
|
||||
plugins: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
typedHooks: [],
|
||||
commands: [],
|
||||
channels,
|
||||
providers: [],
|
||||
gatewayHandlers: {},
|
||||
httpHandlers: [],
|
||||
httpRoutes: [],
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
diagnostics: [],
|
||||
});
|
||||
|
||||
const createStubPlugin = (id: string): ChannelPlugin => ({
|
||||
id,
|
||||
meta: {
|
||||
@@ -159,7 +143,7 @@ const createStubPlugin = (id: string): ChannelPlugin => ({
|
||||
},
|
||||
});
|
||||
|
||||
const baseRegistry = createRegistry([
|
||||
const baseRegistry = createTestRegistry([
|
||||
{ pluginId: "telegram", source: "test", plugin: createStubPlugin("telegram") },
|
||||
{ pluginId: "slack", source: "test", plugin: createStubPlugin("slack") },
|
||||
]);
|
||||
|
||||
@@ -15,6 +15,24 @@ installCronTestHooks({
|
||||
baseTimeIso: "2026-02-06T17:00:00.000Z",
|
||||
});
|
||||
|
||||
function createStartedCron(storePath: string) {
|
||||
const cron = new CronService({
|
||||
storePath,
|
||||
cronEnabled: true,
|
||||
log: noopLogger,
|
||||
enqueueSystemEvent: vi.fn(),
|
||||
requestHeartbeatNow: vi.fn(),
|
||||
runIsolatedAgentJob: vi.fn(async () => ({ status: "ok" as const, summary: "ok" })),
|
||||
});
|
||||
return {
|
||||
cron,
|
||||
start: async () => {
|
||||
await cron.start();
|
||||
return cron;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("CronService store migrations", () => {
|
||||
it("migrates legacy top-level agentTurn fields and initializes missing state", async () => {
|
||||
const store = await makeStorePath();
|
||||
@@ -52,16 +70,7 @@ describe("CronService store migrations", () => {
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const cron = new CronService({
|
||||
storePath: store.storePath,
|
||||
cronEnabled: true,
|
||||
log: noopLogger,
|
||||
enqueueSystemEvent: vi.fn(),
|
||||
requestHeartbeatNow: vi.fn(),
|
||||
runIsolatedAgentJob: vi.fn(async () => ({ status: "ok" as const, summary: "ok" })),
|
||||
});
|
||||
|
||||
await cron.start();
|
||||
const cron = await createStartedCron(store.storePath).start();
|
||||
|
||||
const status = await cron.status();
|
||||
expect(status.enabled).toBe(true);
|
||||
@@ -132,16 +141,7 @@ describe("CronService store migrations", () => {
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const cron = new CronService({
|
||||
storePath: store.storePath,
|
||||
cronEnabled: true,
|
||||
log: noopLogger,
|
||||
enqueueSystemEvent: vi.fn(),
|
||||
requestHeartbeatNow: vi.fn(),
|
||||
runIsolatedAgentJob: vi.fn(async () => ({ status: "ok" as const, summary: "ok" })),
|
||||
});
|
||||
|
||||
await cron.start();
|
||||
const cron = await createStartedCron(store.storePath).start();
|
||||
|
||||
const jobs = await cron.list({ includeDisabled: true });
|
||||
const job = jobs.find((entry) => entry.id === "legacy-agentturn-no-timeout");
|
||||
|
||||
Reference in New Issue
Block a user