test(discord): share empty config fixture

This commit is contained in:
Peter Steinberger
2026-04-25 00:16:13 +01:00
parent 0270428645
commit 989193b4b4
15 changed files with 69 additions and 54 deletions

View File

@@ -1,6 +1,7 @@
import { PermissionFlagsBits } from "discord-api-types/v10";
import type { DiscordActionConfig, OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import type { DiscordActionConfig } from "openclaw/plugin-sdk/config-runtime";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
import {
discordModerationActionRuntime,
handleDiscordModerationAction,
@@ -13,7 +14,7 @@ const timeoutMemberDiscord = vi.fn(async () => ({ id: "user-1" }));
const hasAnyGuildPermissionDiscord = vi.fn(async () => false);
const enableAllActions = (_key: keyof DiscordActionConfig, _defaultValue = true) => true;
const DISCORD_TEST_CFG = {} as OpenClawConfig;
const DISCORD_TEST_CFG = EMPTY_DISCORD_TEST_CONFIG;
function handleModerationAction(action: string, params: Record<string, unknown>) {
return handleDiscordModerationAction(action, params, enableAllActions, DISCORD_TEST_CFG);

View File

@@ -2,6 +2,7 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import type { DiscordActionConfig } from "openclaw/plugin-sdk/config-runtime";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { clearPresences, setPresence } from "../monitor/presence-cache.js";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
import { discordGuildActionRuntime, handleDiscordGuildAction } from "./runtime.guild.js";
import { handleDiscordAction } from "./runtime.js";
import {
@@ -83,7 +84,7 @@ const {
} = discordSendMocks;
const enableAllActions = () => true;
const DISCORD_TEST_CFG = {} as OpenClawConfig;
const DISCORD_TEST_CFG = EMPTY_DISCORD_TEST_CONFIG;
function handleMessagingAction(
action: string,

View File

@@ -6,6 +6,7 @@ import { createStartAccountContext } from "../../../test/helpers/plugins/start-a
import type { ResolvedDiscordAccount } from "./accounts.js";
import type { OpenClawConfig } from "./runtime-api.js";
import * as sendModule from "./send.js";
import { EMPTY_DISCORD_TEST_CONFIG } from "./test-support/config.js";
let discordPlugin: typeof import("./channel.js").discordPlugin;
let setDiscordRuntime: typeof import("./runtime.js").setDiscordRuntime;
@@ -144,7 +145,7 @@ describe("discordPlugin outbound", () => {
const mediaReadFile = vi.fn(async () => Buffer.from("media"));
const result = await discordPlugin.outbound!.sendMedia!({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
to: "channel:123",
text: "hi",
mediaUrl: "/tmp/image.png",
@@ -178,7 +179,7 @@ describe("discordPlugin outbound", () => {
.mockResolvedValueOnce({ messageId: "video-1" });
const result = await discordPlugin.outbound!.sendMedia!({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
to: "channel:123",
text: "done - tiny cyber-lobster clip incoming",
mediaUrl: "/tmp/molty.mp4",
@@ -218,7 +219,7 @@ describe("discordPlugin outbound", () => {
const sendPollSpy = vi.spyOn(sendModule, "sendPollDiscord").mockImplementation(sendPollDiscord);
try {
const result = await discordPlugin.outbound!.sendPoll!({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
to: "channel:123",
poll: {
question: "Best shell?",

View File

@@ -1,10 +1,11 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { describe, expect, it } from "vitest";
import { resolveDiscordDraftStreamingChunking } from "./draft-chunking.js";
import { EMPTY_DISCORD_TEST_CONFIG } from "./test-support/config.js";
describe("resolveDiscordDraftStreamingChunking", () => {
it("returns sane defaults when discord draft chunking is unset", () => {
expect(resolveDiscordDraftStreamingChunking({} as OpenClawConfig)).toEqual({
expect(resolveDiscordDraftStreamingChunking(EMPTY_DISCORD_TEST_CONFIG)).toEqual({
minChars: 200,
maxChars: 800,
breakPreference: "paragraph",

View File

@@ -1,7 +1,7 @@
import { serializePayload } from "@buape/carbon";
import { ComponentType } from "discord-api-types/v10";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { describe, expect, it, vi } from "vitest";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
import {
DISCORD_CUSTOM_ID_MAX_CHARS,
DISCORD_MODEL_PICKER_MODEL_PAGE_SIZE,
@@ -80,7 +80,7 @@ function requireValue<T>(value: T | null | undefined, message: string): T {
describe("loadDiscordModelPickerData", () => {
it("reuses buildModelsProviderData as source of truth with agent scope", async () => {
const expected = createModelsProviderData({ openai: ["gpt-4o"] });
const cfg = {} as OpenClawConfig;
const cfg = EMPTY_DISCORD_TEST_CONFIG;
buildModelsProviderDataMock.mockResolvedValue(expected);
const result = await loadDiscordModelPickerData(cfg, "support");

View File

@@ -1,8 +1,8 @@
import type { Client } from "@buape/carbon";
import type { GatewayPresenceUpdate } from "discord-api-types/v10";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
import { beforeEach, describe, expect, it } from "vitest";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
import type { DiscordChannelConfigResolved } from "./allow-list.js";
import {
resolveDiscordMemberAllowed,
@@ -24,8 +24,6 @@ import {
resolveDiscordReplyDeliveryPlan,
} from "./threading.js";
const DEFAULT_CFG = {} as OpenClawConfig;
describe("resolveDiscordOwnerAllowFrom", () => {
it("returns undefined when no allowlist is configured", () => {
const result = resolveDiscordOwnerAllowFrom({
@@ -435,7 +433,7 @@ describe("maybeCreateDiscordAutoThread", () => {
threadChannel: null,
baseText: "hello",
combinedBody: "hello",
cfg: DEFAULT_CFG,
cfg: EMPTY_DISCORD_TEST_CONFIG,
};
}
@@ -493,7 +491,7 @@ describe("resolveDiscordAutoThreadReplyPlan", () => {
threadChannel: overrides?.threadChannel ?? null,
baseText: "hello",
combinedBody: "hello",
cfg: DEFAULT_CFG,
cfg: EMPTY_DISCORD_TEST_CONFIG,
replyToMode: "all" as const,
agentId: "agent",
channel: "discord" as const,

View File

@@ -1,6 +1,7 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
import {
__testing as threadBindingTesting,
createThreadBindingManager,
@@ -13,7 +14,6 @@ const sendDiscordTextMock = vi.hoisted(() => vi.fn());
const buildDiscordSendErrorMock = vi.hoisted(() =>
vi.fn<(err: unknown, ctx?: unknown) => Promise<unknown>>(async (err: unknown) => err),
);
const DEFAULT_CFG = {} as OpenClawConfig;
const retryAsyncMock = vi.hoisted(() =>
vi.fn(
async (
@@ -101,7 +101,7 @@ describe("deliverDiscordReply", () => {
}> = {},
) => {
const threadBindings = createThreadBindingManager({
cfg: DEFAULT_CFG,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
persist: false,
enableSweeper: false,

View File

@@ -3,13 +3,13 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import * as discordClientModule from "../client.js";
import * as discordSendModule from "../send.js";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
import type { ThreadBindingRecord } from "./thread-bindings.types.js";
const DEFAULT_SEND_RESULT = {
messageId: "msg-1",
channelId: "thread-1",
};
const DEFAULT_CFG = {} as OpenClawConfig;
const restGet = vi.fn<(...args: unknown[]) => Promise<unknown>>();
const sendMessageDiscord = vi.fn<typeof discordSendModule.sendMessageDiscord>();
@@ -37,7 +37,7 @@ function resolveTestChannelIdForBinding(
},
) {
return resolveChannelIdForBinding({
cfg: DEFAULT_CFG,
cfg: EMPTY_DISCORD_TEST_CONFIG,
...params,
});
}

View File

@@ -9,6 +9,7 @@ import {
type OpenClawConfig,
} from "openclaw/plugin-sdk/runtime-config-snapshot";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
const hoisted = vi.hoisted(() => {
const sendMessageDiscord = vi.fn(async (_to: string, _text: string, _opts?: unknown) => ({}));
@@ -76,7 +77,7 @@ function createTestThreadBindingManager(
},
) {
return createThreadBindingManager({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
...params,
});
}
@@ -270,7 +271,7 @@ describe("thread binding lifecycle", () => {
try {
const manager = createTestThreadBindingManager({
accountId: "default",
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
persist: false,
enableSweeper: false,
idleTimeoutMs: 60_000,
@@ -310,7 +311,7 @@ describe("thread binding lifecycle", () => {
try {
const manager = createTestThreadBindingManager({
accountId: "default",
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
persist: false,
enableSweeper: false,
idleTimeoutMs: 0,
@@ -786,7 +787,7 @@ describe("thread binding lifecycle", () => {
hoisted.createThreadDiscord.mockResolvedValueOnce({ id: "thread-created-2" });
const childBinding = await autoBindSpawnedDiscordSubagent({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
channel: "discord",
to: "channel:thread-1",
@@ -827,7 +828,7 @@ describe("thread binding lifecycle", () => {
hoisted.createThreadDiscord.mockResolvedValueOnce({ id: "thread-created-lookup" });
const childBinding = await autoBindSpawnedDiscordSubagent({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
channel: "discord",
to: "channel:thread-lookup",
@@ -1314,7 +1315,7 @@ describe("thread binding lifecycle", () => {
});
const result = await reconcileAcpThreadBindingsOnStartup({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
});
@@ -1358,7 +1359,7 @@ describe("thread binding lifecycle", () => {
hoisted.readAcpSessionEntry.mockReturnValue({
sessionKey: "agent:codex:acp:uncertain",
storeSessionKey: "agent:codex:acp:uncertain",
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
storePath: "/tmp/mock-sessions.json",
storeReadFailed: true,
entry: undefined,
@@ -1366,7 +1367,7 @@ describe("thread binding lifecycle", () => {
});
const result = await reconcileAcpThreadBindingsOnStartup({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
});
@@ -1405,7 +1406,7 @@ describe("thread binding lifecycle", () => {
hoisted.readAcpSessionEntry.mockReturnValue(null);
const result = await reconcileAcpThreadBindingsOnStartup({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
});
@@ -1454,7 +1455,7 @@ describe("thread binding lifecycle", () => {
});
const result = await reconcileAcpThreadBindingsOnStartup({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
healthProbe: async () => ({ status: "stale", reason: "status-timeout-running-stale" }),
});
@@ -1498,7 +1499,7 @@ describe("thread binding lifecycle", () => {
});
const result = await reconcileAcpThreadBindingsOnStartup({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
healthProbe: async () => ({ status: "uncertain", reason: "status-timeout" }),
});
@@ -1546,7 +1547,7 @@ describe("thread binding lifecycle", () => {
});
const result = await reconcileAcpThreadBindingsOnStartup({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
});
@@ -1612,7 +1613,7 @@ describe("thread binding lifecycle", () => {
let secondProbeStartedBeforeFirstResolved = false;
const reconcilePromise = reconcileAcpThreadBindingsOnStartup({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
healthProbe: async () => {
probeCallCount += 1;
@@ -1684,7 +1685,7 @@ describe("thread binding lifecycle", () => {
});
const reconcilePromise = reconcileAcpThreadBindingsOnStartup({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "default",
healthProbe: async () => {
probeCalls += 1;

View File

@@ -1,5 +1,5 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { beforeEach, describe, expect, it } from "vitest";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
import {
__testing as threadBindingsTesting,
createThreadBindingManager,
@@ -24,7 +24,7 @@ describe("thread binding manager state", () => {
const viaJiti = await loadThreadBindingsViaAlternateLoader();
createThreadBindingManager({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "work",
persist: false,
enableSweeper: false,

View File

@@ -1,6 +1,7 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import * as agentRuntimeModule from "openclaw/plugin-sdk/simple-completion-runtime";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
const completeWithPreparedSimpleCompletionModelMock =
vi.fn<typeof agentRuntimeModule.completeWithPreparedSimpleCompletionModel>();
@@ -92,7 +93,7 @@ describe("generateThreadTitle", () => {
});
it("passes model override refs into shared model prep", async () => {
const cfg = {} as OpenClawConfig;
const cfg = EMPTY_DISCORD_TEST_CONFIG;
await generateThreadTitle({
cfg,
agentId: "main",
@@ -114,7 +115,7 @@ describe("generateThreadTitle", () => {
} as Awaited<ReturnType<typeof agentRuntimeModule.prepareSimpleCompletionModelForAgent>>);
const result = await generateThreadTitle({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
agentId: "main",
messageText: "Need a thread title.",
});
@@ -134,7 +135,7 @@ describe("generateThreadTitle", () => {
} as Awaited<ReturnType<typeof agentRuntimeModule.prepareSimpleCompletionModelForAgent>>);
const result = await generateThreadTitle({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
agentId: "main",
messageText: "Need a thread title.",
});
@@ -145,7 +146,7 @@ describe("generateThreadTitle", () => {
it("builds contextual prompt and forwards completion options", async () => {
const result = await generateThreadTitle({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
agentId: "main",
messageText: "Summarize deployment blockers and owner follow-ups.",
channelName: "release-status",
@@ -186,7 +187,7 @@ describe("generateThreadTitle", () => {
);
const result = await generateThreadTitle({
cfg: {} as OpenClawConfig,
cfg: EMPTY_DISCORD_TEST_CONFIG,
agentId: "main",
messageText: "Generate title.",
});

View File

@@ -1,6 +1,7 @@
import { ChannelType } from "@buape/carbon";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { EMPTY_DISCORD_TEST_CONFIG } from "../test-support/config.js";
type MaybeCreateDiscordAutoThreadFn = typeof import("./threading.js").maybeCreateDiscordAutoThread;
const { generateThreadTitleMock } = vi.hoisted(() => ({
@@ -12,7 +13,6 @@ vi.mock("./thread-title.js", () => ({
}));
let maybeCreateDiscordAutoThread: MaybeCreateDiscordAutoThreadFn;
const DEFAULT_CFG = {} as OpenClawConfig;
const postMock = vi.fn();
const getMock = vi.fn();
@@ -38,7 +38,7 @@ function createBaseParams(
channelType: ChannelType.GuildText,
baseText: "test",
combinedBody: "test",
cfg: DEFAULT_CFG,
cfg: EMPTY_DISCORD_TEST_CONFIG,
...overrides,
};
}

View File

@@ -1,12 +1,11 @@
import type { RequestClient } from "@buape/carbon";
import { PermissionFlagsBits, Routes } from "discord-api-types/v10";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { EMPTY_DISCORD_TEST_OPTS } from "./test-support/config.js";
const mockRest = vi.hoisted(() => ({
get: vi.fn(),
}));
const DISCORD_TEST_OPTS = { cfg: {} as OpenClawConfig };
vi.mock("./client.js", () => ({
resolveDiscordRest: () => mockRest as unknown as RequestClient,
@@ -64,7 +63,7 @@ describe("discord guild permission authorization", () => {
const result = await fetchMemberGuildPermissionsDiscord(
"guild-1",
"user-1",
DISCORD_TEST_OPTS,
EMPTY_DISCORD_TEST_OPTS,
);
expect(result).toBeNull();
});
@@ -81,7 +80,7 @@ describe("discord guild permission authorization", () => {
const result = await fetchMemberGuildPermissionsDiscord(
"guild-1",
"user-1",
DISCORD_TEST_OPTS,
EMPTY_DISCORD_TEST_OPTS,
);
expect(result).not.toBeNull();
expect((result! & PermissionFlagsBits.ViewChannel) === PermissionFlagsBits.ViewChannel).toBe(
@@ -107,7 +106,7 @@ describe("discord guild permission authorization", () => {
"guild-1",
"user-1",
[PermissionFlagsBits.KickMembers],
DISCORD_TEST_OPTS,
EMPTY_DISCORD_TEST_OPTS,
);
expect(result).toBe(true);
});
@@ -128,7 +127,7 @@ describe("discord guild permission authorization", () => {
"guild-1",
"user-1",
[PermissionFlagsBits.KickMembers],
DISCORD_TEST_OPTS,
EMPTY_DISCORD_TEST_OPTS,
);
expect(result).toBe(true);
});
@@ -143,7 +142,7 @@ describe("discord guild permission authorization", () => {
"guild-1",
"user-1",
[PermissionFlagsBits.BanMembers, PermissionFlagsBits.KickMembers],
DISCORD_TEST_OPTS,
EMPTY_DISCORD_TEST_OPTS,
);
expect(result).toBe(false);
});
@@ -163,7 +162,7 @@ describe("discord guild permission authorization", () => {
"guild-1",
"user-1",
[PermissionFlagsBits.KickMembers, PermissionFlagsBits.BanMembers],
DISCORD_TEST_OPTS,
EMPTY_DISCORD_TEST_OPTS,
);
expect(result).toBe(false);
});
@@ -181,7 +180,7 @@ describe("discord guild permission authorization", () => {
"guild-1",
"user-1",
[PermissionFlagsBits.KickMembers, PermissionFlagsBits.BanMembers],
DISCORD_TEST_OPTS,
EMPTY_DISCORD_TEST_OPTS,
);
expect(result).toBe(true);
});

View File

@@ -1,10 +1,9 @@
import type { RequestClient } from "@buape/carbon";
import { Routes } from "discord-api-types/v10";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { EMPTY_DISCORD_TEST_CONFIG } from "./test-support/config.js";
const resolveDiscordRestMock = vi.hoisted(() => vi.fn());
const DEFAULT_CFG = {} as OpenClawConfig;
vi.mock("./client.js", () => ({
resolveDiscordRest: resolveDiscordRestMock,
@@ -27,9 +26,15 @@ describe("sendTypingDiscord", () => {
post,
} as unknown as RequestClient);
const result = await sendTypingDiscord("12345", { cfg: DEFAULT_CFG, accountId: "ops" });
const result = await sendTypingDiscord("12345", {
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "ops",
});
expect(resolveDiscordRestMock).toHaveBeenCalledWith({ cfg: DEFAULT_CFG, accountId: "ops" });
expect(resolveDiscordRestMock).toHaveBeenCalledWith({
cfg: EMPTY_DISCORD_TEST_CONFIG,
accountId: "ops",
});
expect(post).toHaveBeenCalledWith(Routes.channelTyping("12345"));
expect(result).toEqual({ ok: true, channelId: "12345" });
});

View File

@@ -0,0 +1,7 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
export const EMPTY_DISCORD_TEST_CONFIG = {} as OpenClawConfig;
export const EMPTY_DISCORD_TEST_OPTS = {
cfg: EMPTY_DISCORD_TEST_CONFIG,
};