
























@@ -13,6 +13,7 @@ import {
1313setActivePluginRegistry,
1414} from "openclaw/plugin-sdk/plugin-test-runtime";
1515import { dispatchReplyWithDispatcher } from "openclaw/plugin-sdk/reply-dispatch-runtime";
16+import { getSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
1617import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
1718import { defineThrowingDiscordChannelGetter } from "../test-support/partial-channel.js";
1819import { resolveDiscordNativeInteractionRouteState } from "./native-command-route.js";
@@ -29,6 +30,7 @@ const runtimeModuleMocks = vi.hoisted(() => ({
2930executePluginCommand: vi.fn(),
3031dispatchReplyWithDispatcher: vi.fn(),
3132resolveDirectStatusReplyForSession: vi.fn(),
33+getSessionEntry: vi.fn(),
3234}));
33353436function createConfig(): OpenClawConfig {
@@ -408,6 +410,7 @@ describe("Discord native plugin command dispatch", () => {
408410discordNativeCommandTesting.setResolveDiscordNativeInteractionRouteState(
409411resolveDiscordNativeInteractionRouteState,
410412);
413+discordNativeCommandTesting.setGetSessionEntry(getSessionEntry);
411414});
412415413416beforeEach(() => {
@@ -430,6 +433,8 @@ describe("Discord native plugin command dispatch", () => {
430433runtimeModuleMocks.resolveDirectStatusReplyForSession.mockResolvedValue({
431434text: "status reply",
432435});
436+runtimeModuleMocks.getSessionEntry.mockReset();
437+runtimeModuleMocks.getSessionEntry.mockReturnValue(undefined);
433438discordNativeCommandTesting.setMatchPluginCommand(
434439runtimeModuleMocks.matchPluginCommand as typeof import("openclaw/plugin-sdk/plugin-runtime").matchPluginCommand,
435440);
@@ -450,6 +455,9 @@ describe("Discord native plugin command dispatch", () => {
450455accountId: params.accountId,
451456}),
452457);
458+discordNativeCommandTesting.setGetSessionEntry(
459+runtimeModuleMocks.getSessionEntry as typeof import("openclaw/plugin-sdk/session-store-runtime").getSessionEntry,
460+);
453461});
454462455463it("executes plugin commands from the real registry through the native Discord command path", async () => {
@@ -476,6 +484,43 @@ describe("Discord native plugin command dispatch", () => {
476484});
477485});
478486487+it("passes the active auth profile to Discord plugin commands", async () => {
488+const cfg = createConfig();
489+const interaction = createInteraction();
490+runtimeModuleMocks.getSessionEntry.mockReturnValue({
491+sessionId: "discord-session",
492+authProfileOverride: "openai-codex:owner@example.com",
493+updatedAt: Date.now(),
494+});
495+496+registerPairPlugin();
497+const command = await createPluginCommand({
498+ cfg,
499+name: "pair",
500+});
501+const executeSpy = runtimeModuleMocks.executePluginCommand.mockResolvedValue({
502+text: "paired:now",
503+});
504+505+await (command as { run: (interaction: unknown) => Promise<void> }).run(
506+Object.assign(interaction, {
507+options: {
508+getString: () => "now",
509+getBoolean: () => null,
510+getFocused: () => "",
511+},
512+}) as unknown,
513+);
514+515+expectPluginCommandExecution({
516+mock: executeSpy,
517+commandName: "pair",
518+expected: {
519+authProfileId: "openai-codex:owner@example.com",
520+},
521+});
522+});
523+479524it("does not treat Discord DM allowlist users as scoped plugin command owners", async () => {
480525const cfg = {
481526channels: {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。