mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
test(plugins): repair prerelease fixture contracts (#113877)
* test(plugins): repair prerelease fixtures * test(onepassword): run resolver fixture from source * test(moonshot): align catalog input fixtures
This commit is contained in:
committed by
GitHub
parent
81d9d1a1f4
commit
7be5c0a7c9
@@ -108,8 +108,6 @@ describe("Cohere provider plugin", () => {
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: "command-a-03-2025",
|
||||
status: "deprecated",
|
||||
replacedBy: COHERE_COMMAND_A_PLUS_MODEL_ID,
|
||||
compat: {
|
||||
supportsStore: false,
|
||||
supportsUsageInStreaming: false,
|
||||
@@ -118,8 +116,6 @@ describe("Cohere provider plugin", () => {
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: COHERE_COMMAND_A_REASONING_MODEL_ID,
|
||||
status: "deprecated",
|
||||
replacedBy: COHERE_COMMAND_A_PLUS_MODEL_ID,
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
contextWindow: 256000,
|
||||
@@ -127,8 +123,6 @@ describe("Cohere provider plugin", () => {
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: COHERE_COMMAND_A_VISION_MODEL_ID,
|
||||
status: "deprecated",
|
||||
replacedBy: COHERE_COMMAND_A_PLUS_MODEL_ID,
|
||||
reasoning: false,
|
||||
input: ["text", "image"],
|
||||
contextWindow: 128000,
|
||||
|
||||
@@ -54,6 +54,10 @@ function createDynamicConfig() {
|
||||
};
|
||||
}
|
||||
|
||||
function createCanonicalAgentRoster() {
|
||||
return { list: [{ id: "main", default: true }] };
|
||||
}
|
||||
|
||||
async function pathExists(target: string): Promise<boolean> {
|
||||
return fs.promises
|
||||
.stat(target)
|
||||
@@ -75,7 +79,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
dynamicAgentCreation: createDynamicConfig(),
|
||||
},
|
||||
},
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig;
|
||||
const { runtime, mutateConfigFile } = createRuntime(cfg);
|
||||
@@ -98,7 +102,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
it("persists a sender agent and direct binding when config writes are allowed", async () => {
|
||||
const cfg = {
|
||||
channels: { feishu: { dynamicAgentCreation: createDynamicConfig() } },
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig;
|
||||
const { runtime, mutateConfigFile } = createRuntime(cfg);
|
||||
@@ -121,6 +125,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
mutate: expect.any(Function),
|
||||
});
|
||||
expect(result.updatedCfg.agents?.list).toEqual([
|
||||
{ id: "main", default: true },
|
||||
{
|
||||
id: "feishu-ou_sender",
|
||||
workspace: path.join(tempRoot, "workspace-feishu-ou_sender"),
|
||||
@@ -144,7 +149,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
it("does not create persistent state when current ingress denies the sender", async () => {
|
||||
const cfg = {
|
||||
channels: { feishu: { dynamicAgentCreation: createDynamicConfig() } },
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig;
|
||||
const { runtime, mutateConfigFile } = createRuntime(cfg);
|
||||
@@ -167,7 +172,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
it("rechecks current ingress inside the config mutation lock", async () => {
|
||||
const cfg = {
|
||||
channels: { feishu: { dynamicAgentCreation: createDynamicConfig() } },
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig;
|
||||
const { runtime, commitConfig, mutateConfigFile } = createRuntime(cfg);
|
||||
@@ -189,7 +194,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
expect(canCreateForConfig).toHaveBeenCalledTimes(2);
|
||||
expect(mutateConfigFile).toHaveBeenCalledTimes(1);
|
||||
expect(commitConfig).not.toHaveBeenCalled();
|
||||
expect(result.updatedCfg.agents?.list).toEqual([]);
|
||||
expect(result.updatedCfg.agents?.list).toEqual([{ id: "main", default: true }]);
|
||||
expect(result.updatedCfg.bindings).toEqual([]);
|
||||
expect(await pathExists(path.join(tempRoot, "workspace-feishu-ou_sender"))).toBe(false);
|
||||
expect(await pathExists(path.join(tempRoot, "agent-feishu-ou_sender"))).toBe(false);
|
||||
@@ -198,7 +203,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
it("preserves a non-peer route added before the config mutation lock", async () => {
|
||||
const cfg = {
|
||||
channels: { feishu: { dynamicAgentCreation: createDynamicConfig() } },
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig;
|
||||
const mutationCfg = {
|
||||
@@ -230,7 +235,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
it("scopes bindings to the normalized account id", async () => {
|
||||
const cfg = {
|
||||
channels: { feishu: { dynamicAgentCreation: createDynamicConfig() } },
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig;
|
||||
const { runtime } = createRuntime(cfg);
|
||||
@@ -262,7 +267,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
const accountId = "a".repeat(64);
|
||||
const cfg = {
|
||||
channels: { feishu: { dynamicAgentCreation: createDynamicConfig() } },
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig;
|
||||
const { runtime } = createRuntime(cfg);
|
||||
@@ -288,6 +293,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
expect(second.agentId).toHaveLength(52);
|
||||
expect(first.agentId).not.toBe(second.agentId);
|
||||
expect(second.updatedCfg.agents?.list?.map((agent) => agent.id)).toEqual([
|
||||
"main",
|
||||
first.agentId,
|
||||
second.agentId,
|
||||
]);
|
||||
@@ -305,6 +311,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
},
|
||||
agents: {
|
||||
list: [
|
||||
{ id: "main", default: true },
|
||||
{
|
||||
id: "feishu-ou_existing",
|
||||
workspace: path.join(tempRoot, "existing-workspace"),
|
||||
@@ -345,6 +352,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
channels: { feishu: { dynamicAgentCreation: createDynamicConfig() } },
|
||||
agents: {
|
||||
list: [
|
||||
{ id: "main", default: true },
|
||||
{
|
||||
id: "feishu-ou_existing",
|
||||
workspace: path.join(tempRoot, "existing-workspace"),
|
||||
@@ -365,7 +373,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
const { runtime, mutateConfigFile } = createRuntime(currentCfg);
|
||||
|
||||
const result = await maybeCreateDynamicAgent({
|
||||
cfg: { agents: { list: [] }, bindings: [] } as OpenClawConfig,
|
||||
cfg: { agents: createCanonicalAgentRoster(), bindings: [] } as OpenClawConfig,
|
||||
runtime,
|
||||
accountId: "default",
|
||||
senderOpenId: "ou_sender",
|
||||
@@ -407,7 +415,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
dynamicAgentCreation: createDynamicConfig(),
|
||||
},
|
||||
},
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig;
|
||||
const persistedCfg = {
|
||||
@@ -417,7 +425,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
dynamicAgentCreation: createDynamicConfig(),
|
||||
},
|
||||
},
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig;
|
||||
const { runtime } = createRuntime(currentCfg, persistedCfg);
|
||||
@@ -440,6 +448,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
channels: { feishu: { configWrites: false } },
|
||||
agents: {
|
||||
list: [
|
||||
{ id: "main", default: true },
|
||||
{
|
||||
id: "feishu-ou_sender",
|
||||
workspace: path.join(tempRoot, "existing-workspace"),
|
||||
@@ -461,7 +470,7 @@ describe("maybeCreateDynamicAgent", () => {
|
||||
|
||||
const result = await maybeCreateDynamicAgent({
|
||||
cfg: {
|
||||
agents: { list: [] },
|
||||
agents: createCanonicalAgentRoster(),
|
||||
bindings: [],
|
||||
} as OpenClawConfig,
|
||||
runtime,
|
||||
|
||||
@@ -2,18 +2,61 @@ import { spawn } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { DEFAULT_SECRET_FILE_MAX_BYTES } from "openclaw/plugin-sdk/secret-file-runtime";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
|
||||
import { encodeOnePasswordSecretId } from "../onepassword-secret-id.js";
|
||||
import { createTrustedNodeFixture } from "./trusted-node.test-support.js";
|
||||
|
||||
const resolverPath = fileURLToPath(
|
||||
const sourceResolverPath = fileURLToPath(
|
||||
new URL("../onepassword-secret-ref-resolver.js", import.meta.url),
|
||||
);
|
||||
const sourceStaticAssetPaths = [
|
||||
sourceResolverPath,
|
||||
fileURLToPath(new URL("../onepassword-op-path.js", import.meta.url)),
|
||||
fileURLToPath(new URL("../onepassword-secret-id.js", import.meta.url)),
|
||||
];
|
||||
const manifestPath = fileURLToPath(new URL("../openclaw.plugin.json", import.meta.url));
|
||||
const packagePath = fileURLToPath(new URL("../package.json", import.meta.url));
|
||||
const tsxCliPath = fileURLToPath(import.meta.resolve("tsx/cli"));
|
||||
const rootTsconfigPath = path.resolve("tsconfig.json");
|
||||
const secretRefRuntimeSourceUrl = pathToFileURL(
|
||||
path.resolve("src/plugin-sdk/secret-ref-runtime.ts"),
|
||||
).href;
|
||||
const tempDirs: string[] = [];
|
||||
let resolverPath = sourceResolverPath;
|
||||
let stagedResolverRoot: string | undefined;
|
||||
|
||||
beforeAll(() => {
|
||||
const tempRoot = path.join(process.cwd(), ".tmp");
|
||||
fs.mkdirSync(tempRoot, { recursive: true });
|
||||
stagedResolverRoot = fs.mkdtempSync(path.join(tempRoot, "onepassword-resolver-"));
|
||||
for (const sourcePath of sourceStaticAssetPaths) {
|
||||
const stagedPath = path.join(stagedResolverRoot, path.basename(sourcePath));
|
||||
if (sourcePath.endsWith("onepassword-op-path.js")) {
|
||||
fs.writeFileSync(
|
||||
stagedPath,
|
||||
fs
|
||||
.readFileSync(sourcePath, "utf8")
|
||||
.replace(
|
||||
'"openclaw/plugin-sdk/secret-ref-runtime"',
|
||||
JSON.stringify(secretRefRuntimeSourceUrl),
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
fs.copyFileSync(sourcePath, stagedPath);
|
||||
}
|
||||
// Keep the relative static assets together, but resolve the real SDK from source so this
|
||||
// focused test does not depend on a parallel build producing dist/plugin-sdk first.
|
||||
resolverPath = path.join(stagedResolverRoot, path.basename(sourceResolverPath));
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
if (stagedResolverRoot) {
|
||||
fs.rmSync(stagedResolverRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
function makeTempDir(): string {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-1password-test-"));
|
||||
@@ -50,17 +93,21 @@ function runResolver(params: {
|
||||
);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn(process.execPath, [resolverPath], {
|
||||
...(params.cwd ? { cwd: params.cwd } : {}),
|
||||
stdio: ["pipe", "pipe", "pipe"],
|
||||
env: {
|
||||
...process.env,
|
||||
OP_SERVICE_ACCOUNT_TOKEN: "",
|
||||
CLAW_1PASSWORD_OP: "",
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
...params.env,
|
||||
const child = spawn(
|
||||
process.execPath,
|
||||
[tsxCliPath, "--tsconfig", rootTsconfigPath, resolverPath],
|
||||
{
|
||||
...(params.cwd ? { cwd: params.cwd } : {}),
|
||||
stdio: ["pipe", "pipe", "pipe"],
|
||||
env: {
|
||||
...process.env,
|
||||
OP_SERVICE_ACCOUNT_TOKEN: "",
|
||||
CLAW_1PASSWORD_OP: "",
|
||||
OPENCLAW_STATE_DIR: stateDir,
|
||||
...params.env,
|
||||
},
|
||||
},
|
||||
});
|
||||
);
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
child.stdout.setEncoding("utf8");
|
||||
@@ -87,7 +134,7 @@ afterEach(() => {
|
||||
|
||||
describe("plugin manifest", () => {
|
||||
it("declares the 1Password resolver as a managed Node SecretRef preset", () => {
|
||||
const resolverSource = fs.readFileSync(resolverPath, "utf8");
|
||||
const resolverSource = fs.readFileSync(sourceResolverPath, "utf8");
|
||||
const readIntegerConstant = (name: string): number => {
|
||||
const match = new RegExp(`const ${name} = (\\d[\\d_]*)`, "u").exec(resolverSource);
|
||||
return Number(match?.[1]?.replaceAll("_", ""));
|
||||
|
||||
Reference in New Issue
Block a user