mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 11:10:45 +00:00
test: share matrix runtime fixtures
This commit is contained in:
@@ -35,6 +35,23 @@ describe("matrix doctor", () => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
function normalizeMatrixDmConfig(dm: Record<string, unknown>) {
|
||||
const normalize = matrixDoctor.normalizeCompatibilityConfig;
|
||||
expect(normalize).toBeDefined();
|
||||
if (!normalize) {
|
||||
throw new Error("expected Matrix doctor compatibility normalizer");
|
||||
}
|
||||
return normalize({
|
||||
cfg: {
|
||||
channels: {
|
||||
matrix: {
|
||||
dm,
|
||||
},
|
||||
},
|
||||
} as never,
|
||||
});
|
||||
}
|
||||
|
||||
it("formats state and crypto previews", () => {
|
||||
expect(
|
||||
formatMatrixLegacyStatePreview({
|
||||
@@ -283,24 +300,10 @@ describe("matrix doctor", () => {
|
||||
// so they must not count toward the allowFrom population check — otherwise
|
||||
// the migration would emit policy="allowlist" with an effectively empty
|
||||
// allowlist, silently blocking all DMs.
|
||||
const normalize = matrixDoctor.normalizeCompatibilityConfig;
|
||||
expect(normalize).toBeDefined();
|
||||
if (!normalize) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = normalize({
|
||||
cfg: {
|
||||
channels: {
|
||||
matrix: {
|
||||
dm: {
|
||||
enabled: true,
|
||||
policy: "trusted",
|
||||
allowFrom: [" ", "\t", ""],
|
||||
},
|
||||
},
|
||||
},
|
||||
} as never,
|
||||
const result = normalizeMatrixDmConfig({
|
||||
enabled: true,
|
||||
policy: "trusted",
|
||||
allowFrom: [" ", "\t", ""],
|
||||
});
|
||||
|
||||
const matrixDm = (result.config.channels?.matrix as { dm?: { policy?: string } })?.dm;
|
||||
@@ -313,23 +316,9 @@ describe("matrix doctor", () => {
|
||||
});
|
||||
|
||||
it("migrates legacy channels.matrix.dm.policy 'trusted' without allowFrom to 'pairing'", () => {
|
||||
const normalize = matrixDoctor.normalizeCompatibilityConfig;
|
||||
expect(normalize).toBeDefined();
|
||||
if (!normalize) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = normalize({
|
||||
cfg: {
|
||||
channels: {
|
||||
matrix: {
|
||||
dm: {
|
||||
enabled: true,
|
||||
policy: "trusted",
|
||||
},
|
||||
},
|
||||
},
|
||||
} as never,
|
||||
const result = normalizeMatrixDmConfig({
|
||||
enabled: true,
|
||||
policy: "trusted",
|
||||
});
|
||||
|
||||
const matrixDm = (result.config.channels?.matrix as { dm?: { policy?: string } })?.dm;
|
||||
|
||||
@@ -22,6 +22,34 @@ import { resolveMatrixAccountStorageRoot } from "./storage-paths.js";
|
||||
|
||||
const createBackupArchiveMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
const MATRIX_CREDENTIALS = {
|
||||
homeserver: "https://matrix.example.org",
|
||||
userId: "@bot:example.org",
|
||||
accessToken: "tok-123",
|
||||
} as const;
|
||||
|
||||
function makeMatrixMigrationConfig() {
|
||||
return {
|
||||
channels: {
|
||||
matrix: MATRIX_CREDENTIALS,
|
||||
},
|
||||
} as never;
|
||||
}
|
||||
|
||||
function seedLegacyMatrixCrypto(home: string) {
|
||||
const stateDir = path.join(home, ".openclaw");
|
||||
const { rootDir } = resolveMatrixAccountStorageRoot({
|
||||
stateDir,
|
||||
...MATRIX_CREDENTIALS,
|
||||
});
|
||||
fs.mkdirSync(path.join(rootDir, "crypto"), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(rootDir, "crypto", "bot-sdk.json"),
|
||||
JSON.stringify({ deviceId: "DEVICE123" }),
|
||||
"utf8",
|
||||
);
|
||||
}
|
||||
|
||||
describe("matrix migration snapshots", () => {
|
||||
beforeEach(() => {
|
||||
createBackupArchiveMock.mockReset();
|
||||
@@ -96,29 +124,8 @@ describe("matrix migration snapshots", () => {
|
||||
|
||||
it("treats legacy Matrix crypto as actionable when the extension inspector is present", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const stateDir = path.join(home, ".openclaw");
|
||||
const { rootDir } = resolveMatrixAccountStorageRoot({
|
||||
stateDir,
|
||||
homeserver: "https://matrix.example.org",
|
||||
userId: "@bot:example.org",
|
||||
accessToken: "tok-123",
|
||||
});
|
||||
fs.mkdirSync(path.join(rootDir, "crypto"), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(rootDir, "crypto", "bot-sdk.json"),
|
||||
JSON.stringify({ deviceId: "DEVICE123" }),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const cfg = {
|
||||
channels: {
|
||||
matrix: {
|
||||
homeserver: "https://matrix.example.org",
|
||||
userId: "@bot:example.org",
|
||||
accessToken: "tok-123",
|
||||
},
|
||||
},
|
||||
} as never;
|
||||
seedLegacyMatrixCrypto(home);
|
||||
const cfg = makeMatrixMigrationConfig();
|
||||
|
||||
const detection = detectLegacyMatrixCrypto({
|
||||
cfg,
|
||||
@@ -140,29 +147,8 @@ describe("matrix migration snapshots", () => {
|
||||
legacyCryptoInspectorAvailability.available = false;
|
||||
|
||||
await withTempHome(async (home) => {
|
||||
const stateDir = path.join(home, ".openclaw");
|
||||
const { rootDir } = resolveMatrixAccountStorageRoot({
|
||||
stateDir,
|
||||
homeserver: "https://matrix.example.org",
|
||||
userId: "@bot:example.org",
|
||||
accessToken: "tok-123",
|
||||
});
|
||||
fs.mkdirSync(path.join(rootDir, "crypto"), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(rootDir, "crypto", "bot-sdk.json"),
|
||||
JSON.stringify({ deviceId: "DEVICE123" }),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const cfg = {
|
||||
channels: {
|
||||
matrix: {
|
||||
homeserver: "https://matrix.example.org",
|
||||
userId: "@bot:example.org",
|
||||
accessToken: "tok-123",
|
||||
},
|
||||
},
|
||||
} as never;
|
||||
seedLegacyMatrixCrypto(home);
|
||||
const cfg = makeMatrixMigrationConfig();
|
||||
|
||||
const detection = detectLegacyMatrixCrypto({
|
||||
cfg,
|
||||
|
||||
@@ -143,6 +143,51 @@ function writeTrustedOpenClawBinFixture(
|
||||
writeFixtureFile(fixtureRoot, "dist/plugin-sdk/group-access.js", "export {};\n");
|
||||
}
|
||||
|
||||
function writeSourceRuntimeWrapperFixture(fixtureRoot: string) {
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/src/plugin-entry.runtime.js",
|
||||
MATRIX_RUNTIME_WRAPPER_SOURCE,
|
||||
);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/plugin-entry.handlers.runtime.js",
|
||||
PACKAGED_RUNTIME_STUB,
|
||||
);
|
||||
}
|
||||
|
||||
function importFixtureModule(fixtureRoot: string, relativePath: string) {
|
||||
const wrapperUrl = pathToFileURL(path.join(fixtureRoot, relativePath));
|
||||
return import(`${wrapperUrl.href}?t=${Date.now()}`);
|
||||
}
|
||||
|
||||
function expectRuntimeWrapperExports(mod: unknown) {
|
||||
expect(mod).toMatchObject({
|
||||
ensureMatrixCryptoRuntime: expect.any(Function),
|
||||
handleVerifyRecoveryKey: expect.any(Function),
|
||||
handleVerificationBootstrap: expect.any(Function),
|
||||
handleVerificationStatus: expect.any(Function),
|
||||
});
|
||||
}
|
||||
|
||||
function writeCapturingSourceRuntimeWrapperFixture(fixtureRoot: string) {
|
||||
delete matrixWrapperGlobal.__openclawMatrixWrapperJitiOptions;
|
||||
writeOpenClawAliasFixture(fixtureRoot);
|
||||
writeCapturingJitiFixture(fixtureRoot);
|
||||
writeSourceRuntimeWrapperFixture(fixtureRoot);
|
||||
}
|
||||
|
||||
function expectSourcePluginSdkAliases(fixtureRoot: string) {
|
||||
expect(matrixWrapperGlobal.__openclawMatrixWrapperJitiOptions).toMatchObject({
|
||||
alias: {
|
||||
[PLUGIN_SDK_ROOT]: path.join(fixtureRoot, "src", "plugin-sdk", "root-alias.cjs"),
|
||||
[SCOPED_PLUGIN_SDK_ROOT]: path.join(fixtureRoot, "src", "plugin-sdk", "root-alias.cjs"),
|
||||
[GROUP_ACCESS_SUBPATH]: path.join(fixtureRoot, "src", "plugin-sdk", "group-access.ts"),
|
||||
[SCOPED_GROUP_ACCESS_SUBPATH]: path.join(fixtureRoot, "src", "plugin-sdk", "group-access.ts"),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
for (const dir of tempDirs.splice(0)) {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
@@ -154,28 +199,11 @@ it("loads the source-checkout runtime wrapper through native ESM import", async
|
||||
|
||||
writeOpenClawPackageFixture(fixtureRoot);
|
||||
writeJitiFixture(fixtureRoot);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/src/plugin-entry.runtime.js",
|
||||
MATRIX_RUNTIME_WRAPPER_SOURCE,
|
||||
);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/plugin-entry.handlers.runtime.js",
|
||||
PACKAGED_RUNTIME_STUB,
|
||||
);
|
||||
writeSourceRuntimeWrapperFixture(fixtureRoot);
|
||||
|
||||
const wrapperUrl = pathToFileURL(
|
||||
path.join(fixtureRoot, "extensions", "matrix", "src", "plugin-entry.runtime.js"),
|
||||
expectRuntimeWrapperExports(
|
||||
await importFixtureModule(fixtureRoot, "extensions/matrix/src/plugin-entry.runtime.js"),
|
||||
);
|
||||
const mod = await import(`${wrapperUrl.href}?t=${Date.now()}`);
|
||||
|
||||
expect(mod).toMatchObject({
|
||||
ensureMatrixCryptoRuntime: expect.any(Function),
|
||||
handleVerifyRecoveryKey: expect.any(Function),
|
||||
handleVerificationBootstrap: expect.any(Function),
|
||||
handleVerificationStatus: expect.any(Function),
|
||||
});
|
||||
}, 240_000);
|
||||
|
||||
it("loads the packaged runtime wrapper without recursing through the stable root alias", async () => {
|
||||
@@ -199,73 +227,26 @@ it("loads the packaged runtime wrapper without recursing through the stable root
|
||||
PACKAGED_RUNTIME_STUB,
|
||||
);
|
||||
|
||||
const wrapperUrl = pathToFileURL(
|
||||
path.join(fixtureRoot, "dist", "plugin-entry.runtime-C88YIa_v.js"),
|
||||
expectRuntimeWrapperExports(
|
||||
await importFixtureModule(fixtureRoot, "dist/plugin-entry.runtime-C88YIa_v.js"),
|
||||
);
|
||||
const mod = await import(`${wrapperUrl.href}?t=${Date.now()}`);
|
||||
|
||||
expect(mod).toMatchObject({
|
||||
ensureMatrixCryptoRuntime: expect.any(Function),
|
||||
handleVerifyRecoveryKey: expect.any(Function),
|
||||
handleVerificationBootstrap: expect.any(Function),
|
||||
handleVerificationStatus: expect.any(Function),
|
||||
});
|
||||
}, 240_000);
|
||||
|
||||
it("builds scoped and unscoped plugin-sdk aliases for the wrapper jiti loader", async () => {
|
||||
const fixtureRoot = makeFixtureRoot(".tmp-matrix-runtime-aliases-");
|
||||
|
||||
delete matrixWrapperGlobal.__openclawMatrixWrapperJitiOptions;
|
||||
writeOpenClawAliasFixture(fixtureRoot);
|
||||
writeCapturingJitiFixture(fixtureRoot);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/src/plugin-entry.runtime.js",
|
||||
MATRIX_RUNTIME_WRAPPER_SOURCE,
|
||||
);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/plugin-entry.handlers.runtime.js",
|
||||
PACKAGED_RUNTIME_STUB,
|
||||
);
|
||||
writeCapturingSourceRuntimeWrapperFixture(fixtureRoot);
|
||||
await importFixtureModule(fixtureRoot, "extensions/matrix/src/plugin-entry.runtime.js");
|
||||
|
||||
const wrapperUrl = pathToFileURL(
|
||||
path.join(fixtureRoot, "extensions", "matrix", "src", "plugin-entry.runtime.js"),
|
||||
);
|
||||
await import(`${wrapperUrl.href}?t=${Date.now()}`);
|
||||
|
||||
expect(matrixWrapperGlobal.__openclawMatrixWrapperJitiOptions).toMatchObject({
|
||||
alias: {
|
||||
[PLUGIN_SDK_ROOT]: path.join(fixtureRoot, "src", "plugin-sdk", "root-alias.cjs"),
|
||||
[SCOPED_PLUGIN_SDK_ROOT]: path.join(fixtureRoot, "src", "plugin-sdk", "root-alias.cjs"),
|
||||
[GROUP_ACCESS_SUBPATH]: path.join(fixtureRoot, "src", "plugin-sdk", "group-access.ts"),
|
||||
[SCOPED_GROUP_ACCESS_SUBPATH]: path.join(fixtureRoot, "src", "plugin-sdk", "group-access.ts"),
|
||||
},
|
||||
});
|
||||
expectSourcePluginSdkAliases(fixtureRoot);
|
||||
}, 240_000);
|
||||
|
||||
it("resolves extension-api aliases through the same source extension family", async () => {
|
||||
const fixtureRoot = makeFixtureRoot(".tmp-matrix-runtime-extension-api-");
|
||||
|
||||
delete matrixWrapperGlobal.__openclawMatrixWrapperJitiOptions;
|
||||
writeOpenClawAliasFixture(fixtureRoot);
|
||||
writeFixtureFile(fixtureRoot, "src/extensionAPI.mts", "export {};\n");
|
||||
writeCapturingJitiFixture(fixtureRoot);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/src/plugin-entry.runtime.js",
|
||||
MATRIX_RUNTIME_WRAPPER_SOURCE,
|
||||
);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/plugin-entry.handlers.runtime.js",
|
||||
PACKAGED_RUNTIME_STUB,
|
||||
);
|
||||
|
||||
const wrapperUrl = pathToFileURL(
|
||||
path.join(fixtureRoot, "extensions", "matrix", "src", "plugin-entry.runtime.js"),
|
||||
);
|
||||
await import(`${wrapperUrl.href}?t=${Date.now()}`);
|
||||
writeCapturingSourceRuntimeWrapperFixture(fixtureRoot);
|
||||
await importFixtureModule(fixtureRoot, "extensions/matrix/src/plugin-entry.runtime.js");
|
||||
|
||||
expect(matrixWrapperGlobal.__openclawMatrixWrapperJitiOptions).toMatchObject({
|
||||
alias: {
|
||||
@@ -286,21 +267,8 @@ it("keeps wrapper plugin-sdk aliases deterministic and ignores unsafe subpaths",
|
||||
writeFixtureFile(fixtureRoot, "src/plugin-sdk/alpha.ts", "export {};\n");
|
||||
writeFixtureFile(fixtureRoot, "src/plugin-sdk/zeta.ts", "export {};\n");
|
||||
writeCapturingJitiFixture(fixtureRoot);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/src/plugin-entry.runtime.js",
|
||||
MATRIX_RUNTIME_WRAPPER_SOURCE,
|
||||
);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/plugin-entry.handlers.runtime.js",
|
||||
PACKAGED_RUNTIME_STUB,
|
||||
);
|
||||
|
||||
const wrapperUrl = pathToFileURL(
|
||||
path.join(fixtureRoot, "extensions", "matrix", "src", "plugin-entry.runtime.js"),
|
||||
);
|
||||
await import(`${wrapperUrl.href}?t=${Date.now()}`);
|
||||
writeSourceRuntimeWrapperFixture(fixtureRoot);
|
||||
await importFixtureModule(fixtureRoot, "extensions/matrix/src/plugin-entry.runtime.js");
|
||||
|
||||
const aliasKeys = Object.keys(
|
||||
(
|
||||
@@ -349,30 +317,10 @@ it("ignores nearby untrusted openclaw package stubs when resolving the wrapper r
|
||||
);
|
||||
writeFixtureFile(fixtureRoot, "extensions/src/plugin-sdk/group-access.ts", "export {};\n");
|
||||
writeCapturingJitiFixture(fixtureRoot);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/src/plugin-entry.runtime.js",
|
||||
MATRIX_RUNTIME_WRAPPER_SOURCE,
|
||||
);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/plugin-entry.handlers.runtime.js",
|
||||
PACKAGED_RUNTIME_STUB,
|
||||
);
|
||||
writeSourceRuntimeWrapperFixture(fixtureRoot);
|
||||
await importFixtureModule(fixtureRoot, "extensions/matrix/src/plugin-entry.runtime.js");
|
||||
|
||||
const wrapperUrl = pathToFileURL(
|
||||
path.join(fixtureRoot, "extensions", "matrix", "src", "plugin-entry.runtime.js"),
|
||||
);
|
||||
await import(`${wrapperUrl.href}?t=${Date.now()}`);
|
||||
|
||||
expect(matrixWrapperGlobal.__openclawMatrixWrapperJitiOptions).toMatchObject({
|
||||
alias: {
|
||||
[PLUGIN_SDK_ROOT]: path.join(fixtureRoot, "src", "plugin-sdk", "root-alias.cjs"),
|
||||
[SCOPED_PLUGIN_SDK_ROOT]: path.join(fixtureRoot, "src", "plugin-sdk", "root-alias.cjs"),
|
||||
[GROUP_ACCESS_SUBPATH]: path.join(fixtureRoot, "src", "plugin-sdk", "group-access.ts"),
|
||||
[SCOPED_GROUP_ACCESS_SUBPATH]: path.join(fixtureRoot, "src", "plugin-sdk", "group-access.ts"),
|
||||
},
|
||||
});
|
||||
expectSourcePluginSdkAliases(fixtureRoot);
|
||||
}, 240_000);
|
||||
|
||||
it("treats string bin hints case-insensitively when trusting wrapper package roots", async () => {
|
||||
@@ -381,21 +329,8 @@ it("treats string bin hints case-insensitively when trusting wrapper package roo
|
||||
delete matrixWrapperGlobal.__openclawMatrixWrapperJitiOptions;
|
||||
writeTrustedOpenClawBinFixture(fixtureRoot, "OpenClaw.MJS");
|
||||
writeCapturingJitiFixture(fixtureRoot);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/src/plugin-entry.runtime.js",
|
||||
MATRIX_RUNTIME_WRAPPER_SOURCE,
|
||||
);
|
||||
writeFixtureFile(
|
||||
fixtureRoot,
|
||||
"extensions/matrix/plugin-entry.handlers.runtime.js",
|
||||
PACKAGED_RUNTIME_STUB,
|
||||
);
|
||||
|
||||
const wrapperUrl = pathToFileURL(
|
||||
path.join(fixtureRoot, "extensions", "matrix", "src", "plugin-entry.runtime.js"),
|
||||
);
|
||||
await import(`${wrapperUrl.href}?t=${Date.now()}`);
|
||||
writeSourceRuntimeWrapperFixture(fixtureRoot);
|
||||
await importFixtureModule(fixtureRoot, "extensions/matrix/src/plugin-entry.runtime.js");
|
||||
|
||||
expect(matrixWrapperGlobal.__openclawMatrixWrapperJitiOptions).toMatchObject({
|
||||
alias: {
|
||||
|
||||
Reference in New Issue
Block a user