test(plugins): drop stale core test files

This commit is contained in:
Peter Steinberger
2026-04-04 00:11:54 +01:00
parent ab318de8b7
commit d02fc365b4
5 changed files with 0 additions and 890 deletions

View File

@@ -1,387 +0,0 @@
import { describe, expect, it } from "vitest";
import { hasLineDirectives, parseLineDirectives } from "./line-directives.js";
const getLineData = (result: ReturnType<typeof parseLineDirectives>) =>
(result.channelData?.line as Record<string, unknown> | undefined) ?? {};
describe("hasLineDirectives", () => {
it("matches expected detection across directive patterns", () => {
const cases: Array<{ text: string; expected: boolean }> = [
{ text: "Here are options [[quick_replies: A, B, C]]", expected: true },
{ text: "[[location: Place | Address | 35.6 | 139.7]]", expected: true },
{ text: "[[confirm: Continue? | Yes | No]]", expected: true },
{ text: "[[buttons: Menu | Choose | Opt1:data1, Opt2:data2]]", expected: true },
{ text: "Just regular text", expected: false },
{ text: "[[not_a_directive: something]]", expected: false },
{ text: "[[media_player: Song | Artist | Speaker]]", expected: true },
{ text: "[[event: Meeting | Jan 24 | 2pm]]", expected: true },
{ text: "[[agenda: Today | Meeting:9am, Lunch:12pm]]", expected: true },
{ text: "[[device: TV | Room]]", expected: true },
{ text: "[[appletv_remote: Apple TV | Playing]]", expected: true },
];
for (const testCase of cases) {
expect(hasLineDirectives(testCase.text)).toBe(testCase.expected);
}
});
});
describe("parseLineDirectives", () => {
describe("quick_replies", () => {
it("parses quick replies variants", () => {
const cases: Array<{
text: string;
channelData?: { line: { quickReplies: string[] } };
quickReplies: string[];
outputText?: string;
}> = [
{
text: "Choose one:\n[[quick_replies: Option A, Option B, Option C]]",
quickReplies: ["Option A", "Option B", "Option C"],
outputText: "Choose one:",
},
{
text: "Before [[quick_replies: A, B]] After",
quickReplies: ["A", "B"],
outputText: "Before After",
},
{
text: "Text [[quick_replies: C, D]]",
channelData: { line: { quickReplies: ["A", "B"] } },
quickReplies: ["A", "B", "C", "D"],
outputText: "Text",
},
];
for (const testCase of cases) {
const result = parseLineDirectives({
text: testCase.text,
channelData: testCase.channelData,
});
expect(getLineData(result).quickReplies).toEqual(testCase.quickReplies);
if (testCase.outputText !== undefined) {
expect(result.text).toBe(testCase.outputText);
}
}
});
});
describe("location", () => {
it("parses location variants", () => {
const existing = { title: "Existing", address: "Addr", latitude: 1, longitude: 2 };
const cases: Array<{
text: string;
channelData?: { line: { location: typeof existing } };
location?: typeof existing;
outputText?: string;
}> = [
{
text: "Here's the location:\n[[location: Tokyo Station | Tokyo, Japan | 35.6812 | 139.7671]]",
location: {
title: "Tokyo Station",
address: "Tokyo, Japan",
latitude: 35.6812,
longitude: 139.7671,
},
outputText: "Here's the location:",
},
{
text: "[[location: Place | Address | invalid | 139.7]]",
location: undefined,
},
{
text: "[[location: New | New Addr | 35.6 | 139.7]]",
channelData: { line: { location: existing } },
location: existing,
},
];
for (const testCase of cases) {
const result = parseLineDirectives({
text: testCase.text,
channelData: testCase.channelData,
});
expect(getLineData(result).location).toEqual(testCase.location);
if (testCase.outputText !== undefined) {
expect(result.text).toBe(testCase.outputText);
}
}
});
});
describe("confirm", () => {
it("parses confirm directives with default and custom action payloads", () => {
const cases = [
{
name: "default yes/no data",
text: "[[confirm: Delete this item? | Yes | No]]",
expectedTemplate: {
type: "confirm",
text: "Delete this item?",
confirmLabel: "Yes",
confirmData: "yes",
cancelLabel: "No",
cancelData: "no",
altText: "Delete this item?",
},
expectedText: undefined,
},
{
name: "custom action data",
text: "[[confirm: Proceed? | OK:action=confirm | Cancel:action=cancel]]",
expectedTemplate: {
type: "confirm",
text: "Proceed?",
confirmLabel: "OK",
confirmData: "action=confirm",
cancelLabel: "Cancel",
cancelData: "action=cancel",
altText: "Proceed?",
},
expectedText: undefined,
},
] as const;
for (const testCase of cases) {
const result = parseLineDirectives({ text: testCase.text });
expect(getLineData(result).templateMessage, testCase.name).toEqual(
testCase.expectedTemplate,
);
expect(result.text, testCase.name).toBe(testCase.expectedText);
}
});
});
describe("buttons", () => {
it("parses message/uri/postback button actions and enforces action caps", () => {
const cases = [
{
name: "message actions",
text: "[[buttons: Menu | Select an option | Help:/help, Status:/status]]",
expectedTemplate: {
type: "buttons",
title: "Menu",
text: "Select an option",
actions: [
{ type: "message", label: "Help", data: "/help" },
{ type: "message", label: "Status", data: "/status" },
],
altText: "Menu: Select an option",
},
},
{
name: "uri action",
text: "[[buttons: Links | Visit us | Site:https://example.com]]",
expectedFirstAction: {
type: "uri",
label: "Site",
uri: "https://example.com",
},
},
{
name: "postback action",
text: "[[buttons: Actions | Choose | Select:action=select&id=1]]",
expectedFirstAction: {
type: "postback",
label: "Select",
data: "action=select&id=1",
},
},
{
name: "action cap",
text: "[[buttons: Menu | Text | A:a, B:b, C:c, D:d, E:e, F:f]]",
expectedActionCount: 4,
},
] as const;
for (const testCase of cases) {
const result = parseLineDirectives({ text: testCase.text });
const templateMessage = getLineData(result).templateMessage as {
type?: string;
actions?: Array<Record<string, unknown>>;
};
expect(templateMessage?.type, testCase.name).toBe("buttons");
if ("expectedTemplate" in testCase) {
expect(templateMessage, testCase.name).toEqual(testCase.expectedTemplate);
}
if ("expectedFirstAction" in testCase) {
expect(templateMessage?.actions?.[0], testCase.name).toEqual(
testCase.expectedFirstAction,
);
}
if ("expectedActionCount" in testCase) {
expect(templateMessage?.actions?.length, testCase.name).toBe(
testCase.expectedActionCount,
);
}
}
});
});
describe("media_player", () => {
it("parses media_player directives across full/minimal/paused variants", () => {
const cases = [
{
name: "all fields",
text: "Now playing:\n[[media_player: Bohemian Rhapsody | Queen | Speaker | https://example.com/album.jpg | playing]]",
expectedAltText: "🎵 Bohemian Rhapsody - Queen",
expectedText: "Now playing:",
expectFooter: true,
expectBodyContents: false,
},
{
name: "minimal",
text: "[[media_player: Unknown Track]]",
expectedAltText: "🎵 Unknown Track",
expectedText: undefined,
expectFooter: false,
expectBodyContents: false,
},
{
name: "paused status",
text: "[[media_player: Song | Artist | Player | | paused]]",
expectedAltText: undefined,
expectedText: undefined,
expectFooter: false,
expectBodyContents: true,
},
] as const;
for (const testCase of cases) {
const result = parseLineDirectives({ text: testCase.text });
const flexMessage = getLineData(result).flexMessage as {
altText?: string;
contents?: { footer?: { contents?: unknown[] }; body?: { contents?: unknown[] } };
};
expect(flexMessage, testCase.name).toBeDefined();
if (testCase.expectedAltText !== undefined) {
expect(flexMessage?.altText, testCase.name).toBe(testCase.expectedAltText);
}
if (testCase.expectedText !== undefined) {
expect(result.text, testCase.name).toBe(testCase.expectedText);
}
if (testCase.expectFooter) {
expect(flexMessage?.contents?.footer?.contents?.length, testCase.name).toBeGreaterThan(0);
}
if ("expectBodyContents" in testCase && testCase.expectBodyContents) {
expect(flexMessage?.contents?.body?.contents, testCase.name).toBeDefined();
}
}
});
});
describe("event", () => {
it("parses event variants", () => {
const cases = [
{
text: "[[event: Team Meeting | January 24, 2026 | 2:00 PM - 3:00 PM | Conference Room A | Discuss Q1 roadmap]]",
altText: "📅 Team Meeting - January 24, 2026 2:00 PM - 3:00 PM",
},
{
text: "[[event: Birthday Party | March 15]]",
altText: "📅 Birthday Party - March 15",
},
];
for (const testCase of cases) {
const result = parseLineDirectives({ text: testCase.text });
const flexMessage = getLineData(result).flexMessage as { altText?: string };
expect(flexMessage).toBeDefined();
expect(flexMessage?.altText).toBe(testCase.altText);
}
});
});
describe("agenda", () => {
it("parses agenda variants", () => {
const cases = [
{
text: "[[agenda: Today's Schedule | Team Meeting:9:00 AM, Lunch:12:00 PM, Review:3:00 PM]]",
altText: "📋 Today's Schedule (3 events)",
},
{
text: "[[agenda: Tasks | Buy groceries, Call mom, Workout]]",
altText: "📋 Tasks (3 events)",
},
];
for (const testCase of cases) {
const result = parseLineDirectives({ text: testCase.text });
const flexMessage = getLineData(result).flexMessage as { altText?: string };
expect(flexMessage).toBeDefined();
expect(flexMessage?.altText).toBe(testCase.altText);
}
});
});
describe("device", () => {
it("parses device variants", () => {
const cases = [
{
text: "[[device: TV | Streaming Box | Playing | Play/Pause:toggle, Menu:menu]]",
altText: "📱 TV: Playing",
},
{
text: "[[device: Speaker]]",
altText: "📱 Speaker",
},
];
for (const testCase of cases) {
const result = parseLineDirectives({ text: testCase.text });
const flexMessage = getLineData(result).flexMessage as { altText?: string };
expect(flexMessage).toBeDefined();
expect(flexMessage?.altText).toBe(testCase.altText);
}
});
});
describe("appletv_remote", () => {
it("parses appletv remote variants", () => {
const cases = [
{
text: "[[appletv_remote: Apple TV | Playing]]",
contains: "Apple TV",
},
{
text: "[[appletv_remote: Apple TV]]",
contains: undefined,
},
];
for (const testCase of cases) {
const result = parseLineDirectives({ text: testCase.text });
const flexMessage = getLineData(result).flexMessage as { altText?: string };
expect(flexMessage).toBeDefined();
if (testCase.contains) {
expect(flexMessage?.altText).toContain(testCase.contains);
}
}
});
});
describe("combined directives", () => {
it("handles text with no directives", () => {
const result = parseLineDirectives({
text: "Just plain text here",
});
expect(result.text).toBe("Just plain text here");
expect(getLineData(result).quickReplies).toBeUndefined();
expect(getLineData(result).location).toBeUndefined();
expect(getLineData(result).templateMessage).toBeUndefined();
});
it("preserves other payload fields", () => {
const result = parseLineDirectives({
text: "Hello [[quick_replies: A, B]]",
mediaUrl: "https://example.com/image.jpg",
replyToId: "msg123",
});
expect(result.mediaUrl).toBe("https://example.com/image.jpg");
expect(result.replyToId).toBe("msg123");
expect(getLineData(result).quickReplies).toEqual(["A", "B"]);
});
});
});

View File

@@ -1,61 +0,0 @@
import { describe, expect, it } from "vitest";
import { normalizeIMessageMessagingTarget } from "./normalize/imessage.js";
import { looksLikeSignalTargetId, normalizeSignalMessagingTarget } from "./normalize/signal.js";
describe("imessage target normalization", () => {
it("preserves service prefixes for handles", () => {
expect(normalizeIMessageMessagingTarget("sms:+1 (555) 222-3333")).toBe("sms:+15552223333");
});
it("drops service prefixes for chat targets", () => {
expect(normalizeIMessageMessagingTarget("sms:chat_id:123")).toBe("chat_id:123");
expect(normalizeIMessageMessagingTarget("imessage:CHAT_GUID:abc")).toBe("chat_guid:abc");
expect(normalizeIMessageMessagingTarget("auto:ChatIdentifier:foo")).toBe("chatidentifier:foo");
});
});
describe("signal target normalization", () => {
it("normalizes uuid targets by stripping uuid:", () => {
expect(normalizeSignalMessagingTarget("uuid:123E4567-E89B-12D3-A456-426614174000")).toBe(
"123e4567-e89b-12d3-a456-426614174000",
);
});
it("normalizes signal:uuid targets", () => {
expect(normalizeSignalMessagingTarget("signal:uuid:123E4567-E89B-12D3-A456-426614174000")).toBe(
"123e4567-e89b-12d3-a456-426614174000",
);
});
it("preserves case for group targets", () => {
expect(
normalizeSignalMessagingTarget("signal:group:VWATOdKF2hc8zdOS76q9tb0+5BI522e03QLDAq/9yPg="),
).toBe("group:VWATOdKF2hc8zdOS76q9tb0+5BI522e03QLDAq/9yPg=");
});
it("preserves case for base64-like group IDs without signal prefix", () => {
expect(
normalizeSignalMessagingTarget("group:AbCdEfGhIjKlMnOpQrStUvWxYz0123456789+/ABCD="),
).toBe("group:AbCdEfGhIjKlMnOpQrStUvWxYz0123456789+/ABCD=");
});
it("accepts uuid prefixes for target detection", () => {
expect(looksLikeSignalTargetId("uuid:123e4567-e89b-12d3-a456-426614174000")).toBe(true);
expect(looksLikeSignalTargetId("signal:uuid:123e4567-e89b-12d3-a456-426614174000")).toBe(true);
});
it("accepts signal-prefixed E.164 targets for detection", () => {
expect(looksLikeSignalTargetId("signal:+15551234567")).toBe(true);
expect(looksLikeSignalTargetId("signal:15551234567")).toBe(true);
});
it("accepts compact UUIDs for target detection", () => {
expect(looksLikeSignalTargetId("123e4567e89b12d3a456426614174000")).toBe(true);
expect(looksLikeSignalTargetId("uuid:123e4567e89b12d3a456426614174000")).toBe(true);
});
it("rejects invalid uuid prefixes", () => {
expect(looksLikeSignalTargetId("uuid:")).toBe(false);
expect(looksLikeSignalTargetId("uuid:not-a-uuid")).toBe(false);
});
});

View File

@@ -1,194 +0,0 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import JSZip from "jszip";
import * as tar from "tar";
import { describe, expect, it } from "vitest";
import type { ReleaseAsset } from "./signal-install.js";
import { extractSignalCliArchive, looksLikeArchive, pickAsset } from "./signal-install.js";
// Realistic asset list modelled after an actual signal-cli GitHub release.
const SAMPLE_ASSETS: ReleaseAsset[] = [
{
name: "signal-cli-0.13.14-Linux-native.tar.gz",
browser_download_url: "https://example.com/linux-native.tar.gz",
},
{
name: "signal-cli-0.13.14-Linux-native.tar.gz.asc",
browser_download_url: "https://example.com/linux-native.tar.gz.asc",
},
{
name: "signal-cli-0.13.14-macOS-native.tar.gz",
browser_download_url: "https://example.com/macos-native.tar.gz",
},
{
name: "signal-cli-0.13.14-macOS-native.tar.gz.asc",
browser_download_url: "https://example.com/macos-native.tar.gz.asc",
},
{
name: "signal-cli-0.13.14-Windows-native.zip",
browser_download_url: "https://example.com/windows-native.zip",
},
{
name: "signal-cli-0.13.14-Windows-native.zip.asc",
browser_download_url: "https://example.com/windows-native.zip.asc",
},
{ name: "signal-cli-0.13.14.tar.gz", browser_download_url: "https://example.com/jvm.tar.gz" },
{
name: "signal-cli-0.13.14.tar.gz.asc",
browser_download_url: "https://example.com/jvm.tar.gz.asc",
},
];
describe("looksLikeArchive", () => {
it("recognises .tar.gz", () => {
expect(looksLikeArchive("foo.tar.gz")).toBe(true);
});
it("recognises .tgz", () => {
expect(looksLikeArchive("foo.tgz")).toBe(true);
});
it("recognises .zip", () => {
expect(looksLikeArchive("foo.zip")).toBe(true);
});
it("rejects signature files", () => {
expect(looksLikeArchive("foo.tar.gz.asc")).toBe(false);
});
it("rejects unrelated files", () => {
expect(looksLikeArchive("README.md")).toBe(false);
});
});
describe("pickAsset", () => {
describe("linux", () => {
it("selects the Linux-native asset on x64", () => {
const result = pickAsset(SAMPLE_ASSETS, "linux", "x64");
expect(result).toBeDefined();
expect(result!.name).toContain("Linux-native");
expect(result!.name).toMatch(/\.tar\.gz$/);
});
it("returns undefined on arm64 (triggers brew fallback)", () => {
const result = pickAsset(SAMPLE_ASSETS, "linux", "arm64");
expect(result).toBeUndefined();
});
it("returns undefined on arm (32-bit)", () => {
const result = pickAsset(SAMPLE_ASSETS, "linux", "arm");
expect(result).toBeUndefined();
});
});
describe("darwin", () => {
it("selects the macOS-native asset", () => {
const result = pickAsset(SAMPLE_ASSETS, "darwin", "arm64");
expect(result).toBeDefined();
expect(result!.name).toContain("macOS-native");
});
it("selects the macOS-native asset on x64", () => {
const result = pickAsset(SAMPLE_ASSETS, "darwin", "x64");
expect(result).toBeDefined();
expect(result!.name).toContain("macOS-native");
});
});
describe("win32", () => {
it("selects the Windows-native asset", () => {
const result = pickAsset(SAMPLE_ASSETS, "win32", "x64");
expect(result).toBeDefined();
expect(result!.name).toContain("Windows-native");
expect(result!.name).toMatch(/\.zip$/);
});
});
describe("edge cases", () => {
it("returns undefined for an empty asset list", () => {
expect(pickAsset([], "linux", "x64")).toBeUndefined();
});
it("skips assets with missing name or url", () => {
const partial: ReleaseAsset[] = [
{ name: "signal-cli.tar.gz" },
{ browser_download_url: "https://example.com/file.tar.gz" },
];
expect(pickAsset(partial, "linux", "x64")).toBeUndefined();
});
it("falls back to first archive for unknown platform", () => {
const result = pickAsset(SAMPLE_ASSETS, "freebsd" as NodeJS.Platform, "x64");
expect(result).toBeDefined();
expect(result!.name).toMatch(/\.tar\.gz$/);
});
it("never selects .asc signature files", () => {
const result = pickAsset(SAMPLE_ASSETS, "linux", "x64");
expect(result).toBeDefined();
expect(result!.name).not.toMatch(/\.asc$/);
});
});
});
describe("extractSignalCliArchive", () => {
async function withArchiveWorkspace(run: (workDir: string) => Promise<void>) {
const workDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-signal-install-"));
try {
await run(workDir);
} finally {
await fs.rm(workDir, { recursive: true, force: true }).catch(() => undefined);
}
}
it("rejects zip slip path traversal", async () => {
await withArchiveWorkspace(async (workDir) => {
const archivePath = path.join(workDir, "bad.zip");
const extractDir = path.join(workDir, "extract");
await fs.mkdir(extractDir, { recursive: true });
const zip = new JSZip();
zip.file("../pwned.txt", "pwnd");
await fs.writeFile(archivePath, await zip.generateAsync({ type: "nodebuffer" }));
await expect(extractSignalCliArchive(archivePath, extractDir, 5_000)).rejects.toThrow(
/(escapes destination|absolute)/i,
);
});
});
it("extracts zip archives", async () => {
await withArchiveWorkspace(async (workDir) => {
const archivePath = path.join(workDir, "ok.zip");
const extractDir = path.join(workDir, "extract");
await fs.mkdir(extractDir, { recursive: true });
const zip = new JSZip();
zip.file("root/signal-cli", "bin");
await fs.writeFile(archivePath, await zip.generateAsync({ type: "nodebuffer" }));
await extractSignalCliArchive(archivePath, extractDir, 5_000);
const extracted = await fs.readFile(path.join(extractDir, "root", "signal-cli"), "utf-8");
expect(extracted).toBe("bin");
});
});
it("extracts tar.gz archives", async () => {
await withArchiveWorkspace(async (workDir) => {
const archivePath = path.join(workDir, "ok.tgz");
const extractDir = path.join(workDir, "extract");
const rootDir = path.join(workDir, "root");
await fs.mkdir(rootDir, { recursive: true });
await fs.writeFile(path.join(rootDir, "signal-cli"), "bin", "utf-8");
await tar.c({ cwd: workDir, file: archivePath, gzip: true }, ["root"]);
await fs.mkdir(extractDir, { recursive: true });
await extractSignalCliArchive(archivePath, extractDir, 5_000);
const extracted = await fs.readFile(path.join(extractDir, "root", "signal-cli"), "utf-8");
expect(extracted).toBe("bin");
});
});
});

View File

@@ -1,228 +0,0 @@
import path from "node:path";
import { describe, expect, it } from "vitest";
import { withTempHome } from "../../test/helpers/temp-home.js";
import type { OpenClawConfig } from "../config/config.js";
import { resolveMatrixMigrationAccountTarget } from "./matrix-migration-config.js";
import {
MATRIX_OPS_ACCESS_TOKEN,
MATRIX_OPS_ACCOUNT_ID,
MATRIX_OPS_USER_ID,
MATRIX_TEST_HOMESERVER,
writeMatrixCredentials,
} from "./matrix.test-helpers.js";
function resolveOpsTarget(cfg: OpenClawConfig, env = process.env) {
return resolveMatrixMigrationAccountTarget({
cfg,
env,
accountId: MATRIX_OPS_ACCOUNT_ID,
});
}
describe("resolveMatrixMigrationAccountTarget", () => {
it("reuses stored user identity for token-only configs when the access token matches", async () => {
await withTempHome(async (home) => {
const stateDir = path.join(home, ".openclaw");
writeMatrixCredentials(stateDir, {
accountId: MATRIX_OPS_ACCOUNT_ID,
deviceId: "DEVICE-OPS",
accessToken: MATRIX_OPS_ACCESS_TOKEN,
});
const cfg: OpenClawConfig = {
channels: {
matrix: {
accounts: {
ops: {
homeserver: MATRIX_TEST_HOMESERVER,
accessToken: MATRIX_OPS_ACCESS_TOKEN,
},
},
},
},
};
const target = resolveOpsTarget(cfg);
expect(target).not.toBeNull();
expect(target?.userId).toBe(MATRIX_OPS_USER_ID);
expect(target?.storedDeviceId).toBe("DEVICE-OPS");
});
});
it("ignores stored device IDs from stale cached Matrix credentials", async () => {
await withTempHome(async (home) => {
const stateDir = path.join(home, ".openclaw");
writeMatrixCredentials(stateDir, {
accountId: MATRIX_OPS_ACCOUNT_ID,
userId: "@old-bot:example.org",
accessToken: "tok-old",
deviceId: "DEVICE-OLD",
});
const cfg: OpenClawConfig = {
channels: {
matrix: {
accounts: {
ops: {
homeserver: MATRIX_TEST_HOMESERVER,
userId: "@new-bot:example.org",
accessToken: "tok-new",
},
},
},
},
};
const target = resolveOpsTarget(cfg);
expect(target).not.toBeNull();
expect(target?.userId).toBe("@new-bot:example.org");
expect(target?.accessToken).toBe("tok-new");
expect(target?.storedDeviceId).toBeNull();
});
});
it("does not trust stale stored creds on the same homeserver when the token changes", async () => {
await withTempHome(async (home) => {
const stateDir = path.join(home, ".openclaw");
writeMatrixCredentials(stateDir, {
accountId: MATRIX_OPS_ACCOUNT_ID,
userId: "@old-bot:example.org",
accessToken: "tok-old",
deviceId: "DEVICE-OLD",
});
const cfg: OpenClawConfig = {
channels: {
matrix: {
accounts: {
ops: {
homeserver: MATRIX_TEST_HOMESERVER,
accessToken: "tok-new",
},
},
},
},
};
const target = resolveOpsTarget(cfg);
expect(target).toBeNull();
});
});
it("does not inherit the base userId for non-default token-only accounts", async () => {
await withTempHome(async (home) => {
const stateDir = path.join(home, ".openclaw");
writeMatrixCredentials(stateDir, {
accountId: MATRIX_OPS_ACCOUNT_ID,
deviceId: "DEVICE-OPS",
accessToken: MATRIX_OPS_ACCESS_TOKEN,
});
const cfg: OpenClawConfig = {
channels: {
matrix: {
homeserver: MATRIX_TEST_HOMESERVER,
userId: "@base-bot:example.org",
accounts: {
ops: {
homeserver: MATRIX_TEST_HOMESERVER,
accessToken: MATRIX_OPS_ACCESS_TOKEN,
},
},
},
},
};
const target = resolveOpsTarget(cfg);
expect(target).not.toBeNull();
expect(target?.userId).toBe(MATRIX_OPS_USER_ID);
expect(target?.storedDeviceId).toBe("DEVICE-OPS");
});
});
it("does not inherit the base access token for non-default accounts", async () => {
await withTempHome(async () => {
const cfg: OpenClawConfig = {
channels: {
matrix: {
homeserver: MATRIX_TEST_HOMESERVER,
userId: "@base-bot:example.org",
accessToken: "tok-base",
accounts: {
ops: {
homeserver: MATRIX_TEST_HOMESERVER,
userId: MATRIX_OPS_USER_ID,
},
},
},
},
};
const target = resolveOpsTarget(cfg);
expect(target).toBeNull();
});
});
it("does not inherit the global Matrix access token for non-default accounts", async () => {
await withTempHome(
async () => {
const cfg: OpenClawConfig = {
channels: {
matrix: {
accounts: {
ops: {
homeserver: MATRIX_TEST_HOMESERVER,
userId: MATRIX_OPS_USER_ID,
},
},
},
},
};
const target = resolveOpsTarget(cfg);
expect(target).toBeNull();
},
{
env: {
MATRIX_ACCESS_TOKEN: "tok-global",
},
},
);
});
it("uses the same scoped env token encoding as runtime account auth", async () => {
await withTempHome(async () => {
const cfg: OpenClawConfig = {
channels: {
matrix: {
accounts: {
"ops-prod": {},
},
},
},
};
const env = {
MATRIX_OPS_X2D_PROD_HOMESERVER: "https://matrix.example.org",
MATRIX_OPS_X2D_PROD_USER_ID: "@ops-prod:example.org",
MATRIX_OPS_X2D_PROD_ACCESS_TOKEN: "tok-ops-prod",
} as NodeJS.ProcessEnv;
const target = resolveMatrixMigrationAccountTarget({
cfg,
env,
accountId: "ops-prod",
});
expect(target).not.toBeNull();
expect(target?.homeserver).toBe("https://matrix.example.org");
expect(target?.userId).toBe("@ops-prod:example.org");
expect(target?.accessToken).toBe("tok-ops-prod");
});
});
});

View File

@@ -1,20 +0,0 @@
import { afterEach, describe, expect, it } from "vitest";
import {
listImportedBundledPluginFacadeIds,
resetFacadeRuntimeStateForTest,
} from "../plugin-sdk/facade-runtime.js";
import { createIMessageTestPlugin } from "./imessage-test-plugin.js";
afterEach(() => {
resetFacadeRuntimeStateForTest();
});
describe("createIMessageTestPlugin", () => {
it("does not load the bundled iMessage facade by default", () => {
expect(listImportedBundledPluginFacadeIds()).toEqual([]);
createIMessageTestPlugin();
expect(listImportedBundledPluginFacadeIds()).toEqual([]);
});
});