Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  approval-native.test.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { describe, expect, it } from "vitest";
import { matrixApprovalCapability } from "./approval-native.js";

function buildConfig(
  overrides?: Partial<NonNullable<NonNullable<OpenClawConfig["channels"]>["matrix"]>>,
): OpenClawConfig {
  return {
    channels: {
      matrix: {
        homeserver: "https://matrix.example.org",
        userId: "@bot:example.org",
        accessToken: "tok",
        execApprovals: {
          enabled: true,
          approvers: ["@owner:example.org"],
          target: "both",
        },
        ...overrides,
      },
    },
  } as OpenClawConfig;
}

describe("matrix approval capability", () => {
  it("describes the correct Matrix exec-approval setup path", () => {
    const text = matrixApprovalCapability.describeExecApprovalSetup?.({
      channel: "matrix",
      channelLabel: "Matrix",
    });

    expect(text).toContain("`channels.matrix.execApprovals.approvers`");
    expect(text).toContain("`channels.matrix.dm.allowFrom`");
  });

  it("describes the named-account Matrix exec-approval setup path", () => {
    const text = matrixApprovalCapability.describeExecApprovalSetup?.({
      channel: "matrix",
      channelLabel: "Matrix",
      accountId: "work",
    });

    expect(text).toContain("`channels.matrix.accounts.work.execApprovals.approvers`");
    expect(text).toContain("`channels.matrix.accounts.work.dm.allowFrom`");
    expect(text).not.toContain("`channels.matrix.execApprovals.approvers`");
  });

  it("describes native matrix approval delivery capabilities", () => {
    const capabilities = matrixApprovalCapability.native?.describeDeliveryCapabilities({
      cfg: buildConfig(),
      accountId: "default",
      approvalKind: "exec",
      request: {
        id: "req-1",
        request: {
          command: "echo hi",
          turnSourceChannel: "matrix",
          turnSourceTo: "room:!ops:example.org",
          turnSourceAccountId: "default",
          sessionKey: "agent:main:matrix:channel:!ops:example.org",
        },
        createdAtMs: 0,
        expiresAtMs: 1000,
      },
    });

    expect(capabilities).toEqual({
      enabled: true,
      preferredSurface: "both",
      supportsOriginSurface: true,
      supportsApproverDmSurface: true,
      notifyOriginWhenDmOnly: true,
    });
  });

  it("resolves origin targets from matrix turn source", async () => {
    const target = await matrixApprovalCapability.native?.resolveOriginTarget?.({
      cfg: buildConfig(),
      accountId: "default",
      approvalKind: "exec",
      request: {
        id: "req-1",
        request: {
          command: "echo hi",
          turnSourceChannel: "matrix",
          turnSourceTo: "room:!ops:example.org",
          turnSourceThreadId: "$thread",
          turnSourceAccountId: "default",
          sessionKey: "agent:main:matrix:channel:!ops:example.org",
        },
        createdAtMs: 0,
        expiresAtMs: 1000,
      },
    });

    expect(target).toEqual({
      to: "room:!ops:example.org",
      threadId: "$thread",
    });
  });

  it("resolves approver dm targets", async () => {
    const targets = await matrixApprovalCapability.native?.resolveApproverDmTargets?.({
      cfg: buildConfig(),
      accountId: "default",
      approvalKind: "exec",
      request: {
        id: "req-1",
        request: {
          command: "echo hi",
        },
        createdAtMs: 0,
        expiresAtMs: 1000,
      },
    });

    expect(targets).toEqual([{ to: "user:@owner:example.org" }]);
  });

  it("suppresses same-channel plugin forwarding when Matrix native delivery is available", () => {
    const shouldSuppress = matrixApprovalCapability.delivery?.shouldSuppressForwardingFallback;
    if (!shouldSuppress) {
      throw new Error("delivery suppression helper unavailable");
    }

    expect(
      shouldSuppress({
        cfg: buildConfig({
          dm: { allowFrom: ["@owner:example.org"] },
        }),
        approvalKind: "plugin",
        target: {
          channel: "matrix",
          to: "room:!ops:example.org",
          accountId: "default",
        },
        request: {
          id: "plugin:req-1",
          request: {
            title: "Plugin Approval Required",
            description: "Allow plugin action",
            pluginId: "git-tools",
            turnSourceChannel: "matrix",
            turnSourceTo: "room:!ops:example.org",
            turnSourceAccountId: "default",
          },
          createdAtMs: 0,
          expiresAtMs: 1000,
        },
      } as never),
    ).toBe(true);
  });

  it("preserves room-id case when matching Matrix origin targets", async () => {
    const target = await matrixApprovalCapability.native?.resolveOriginTarget?.({
      cfg: buildConfig(),
      accountId: "default",
      approvalKind: "exec",
      request: {
        id: "req-1",
        request: {
          command: "echo hi",
          turnSourceChannel: "matrix",
          turnSourceTo: "room:!Ops:Example.org",
          turnSourceThreadId: "$thread",
          turnSourceAccountId: "default",
          sessionKey: "agent:main:matrix:channel:!Ops:Example.org",
        },
        createdAtMs: 0,
        expiresAtMs: 1000,
      },
    });

    expect(target).toEqual({
      to: "room:!Ops:Example.org",
      threadId: "$thread",
    });
  });

  it("keeps plugin approval auth independent from exec approvers", () => {
    const cfg = buildConfig({
      dm: { allowFrom: ["@owner:example.org"] },
      execApprovals: {
        enabled: true,
        approvers: ["@exec:example.org"],
        target: "both",
      },
    });

    expect(
      matrixApprovalCapability.authorizeActorAction?.({
        cfg,
        accountId: "default",
        senderId: "@owner:example.org",
        action: "approve",
        approvalKind: "plugin",
      }),
    ).toEqual({ authorized: true });

    expect(
      matrixApprovalCapability.authorizeActorAction?.({
        cfg,
        accountId: "default",
        senderId: "@exec:example.org",
        action: "approve",
        approvalKind: "plugin",
      }),
    ).toEqual({
      authorized: false,
      reason: "❌ You are not authorized to approve plugin requests on Matrix.",
    });

    expect(
      matrixApprovalCapability.authorizeActorAction?.({
        cfg,
        accountId: "default",
        senderId: "@exec:example.org",
        action: "approve",
        approvalKind: "exec",
      }),
    ).toEqual({ authorized: true });
  });

  it("requires Matrix DM approvers before enabling plugin approval auth", () => {
    const cfg = buildConfig({
      dm: { allowFrom: [] },
      execApprovals: {
        enabled: true,
        approvers: ["@exec:example.org"],
        target: "both",
      },
    });

    expect(
      matrixApprovalCapability.authorizeActorAction?.({
        cfg,
        accountId: "default",
        senderId: "@exec:example.org",
        action: "approve",
        approvalKind: "plugin",
      }),
    ).toEqual({
      authorized: false,
      reason: "❌ Matrix plugin approvals are not enabled for this bot account.",
    });
  });

  it("reports exec initiating-surface availability independently from plugin auth", () => {
    const cfg = buildConfig({
      dm: { allowFrom: ["@owner:example.org"] },
      execApprovals: {
        enabled: false,
        approvers: [],
        target: "both",
      },
    });

    expect(
      matrixApprovalCapability.getActionAvailabilityState?.({
        cfg,
        accountId: "default",
        action: "approve",
        approvalKind: "plugin",
      }),
    ).toEqual({ kind: "enabled" });

    expect(
      matrixApprovalCapability.getExecInitiatingSurfaceState?.({
        cfg,
        accountId: "default",
        action: "approve",
      }),
    ).toEqual({ kind: "disabled" });
  });

  it("enables matrix-native plugin approval delivery when DM approvers are configured", () => {
    const capabilities = matrixApprovalCapability.native?.describeDeliveryCapabilities({
      cfg: buildConfig({
        dm: { allowFrom: ["@owner:example.org"] },
      }),
      accountId: "default",
      approvalKind: "plugin",
      request: {
        id: "plugin:req-1",
        request: {
          title: "Plugin Approval Required",
          description: "Allow plugin access",
          pluginId: "git-tools",
        },
        createdAtMs: 0,
        expiresAtMs: 1000,
      },
    });

    expect(capabilities).toEqual({
      enabled: true,
      preferredSurface: "both",
      supportsOriginSurface: true,
      supportsApproverDmSurface: true,
      notifyOriginWhenDmOnly: true,
    });
  });

  it("keeps matrix-native plugin approval delivery disabled without DM approvers", () => {
    const capabilities = matrixApprovalCapability.native?.describeDeliveryCapabilities({
      cfg: buildConfig(),
      accountId: "default",
      approvalKind: "plugin",
      request: {
        id: "plugin:req-1",
        request: {
          title: "Plugin Approval Required",
          description: "Allow plugin access",
          pluginId: "git-tools",
        },
        createdAtMs: 0,
        expiresAtMs: 1000,
      },
    });

    expect(capabilities).toEqual({
      enabled: false,
      preferredSurface: "both",
      supportsOriginSurface: true,
      supportsApproverDmSurface: true,
      notifyOriginWhenDmOnly: true,
    });
  });
});

¤ Dauer der Verarbeitung: 0.44 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge