diff --git a/src/infra/node-pairing.test.ts b/src/infra/node-pairing.test.ts index bb48d8d5e0c..14e86538acb 100644 --- a/src/infra/node-pairing.test.ts +++ b/src/infra/node-pairing.test.ts @@ -1,5 +1,5 @@ -import { describe, expect, test } from "vitest"; -import { withTempDir } from "../test-helpers/temp-dir.js"; +import { afterAll, beforeAll, describe, expect, test } from "vitest"; +import { createSuiteTempRootTracker } from "../test-helpers/temp-dir.js"; import { approveNodePairing, getPairedNode, @@ -30,11 +30,21 @@ async function setupPairedNode(baseDir: string): Promise { return paired.token; } +const tempDirs = createSuiteTempRootTracker({ prefix: "openclaw-node-pairing-" }); + async function withNodePairingDir(run: (baseDir: string) => Promise): Promise { - return await withTempDir({ prefix: "openclaw-node-pairing-" }, run); + return await run(await tempDirs.make("case")); } describe("node pairing tokens", () => { + beforeAll(async () => { + await tempDirs.setup(); + }); + + afterAll(async () => { + await tempDirs.cleanup(); + }); + test("reuses existing pending requests for the same node", async () => { await withNodePairingDir(async (baseDir) => { const first = await requestNodePairing( diff --git a/src/plugins/web-provider-public-artifacts.test.ts b/src/plugins/web-provider-public-artifacts.test.ts index 65d7a5f5d4f..d095cd8511a 100644 --- a/src/plugins/web-provider-public-artifacts.test.ts +++ b/src/plugins/web-provider-public-artifacts.test.ts @@ -1,10 +1,5 @@ import { describe, expect, it } from "vitest"; -import { - loadPluginManifestRegistry, - resolveManifestContractOwnerPluginId, - resolveManifestContractPluginIds, - resolveManifestContractPluginIdsByCompatibilityRuntimePath, -} from "./manifest-registry.js"; +import { loadPluginManifestRegistry } from "./manifest-registry.js"; import { hasBundledWebFetchProviderPublicArtifact, hasBundledWebSearchProviderPublicArtifact, @@ -34,12 +29,34 @@ function supportsSecretRefWebSearchApiKey( return Array.isArray(typeValue) && typeValue.includes("object"); } +const registry = loadPluginManifestRegistry(); + +function bundledPluginIdsWithContract( + contract: "webSearchProviders" | "webFetchProviders", +): string[] { + return registry.plugins + .filter( + (plugin) => plugin.origin === "bundled" && (plugin.contracts?.[contract]?.length ?? 0) > 0, + ) + .map((plugin) => plugin.id) + .toSorted((left, right) => left.localeCompare(right)); +} + +function ownerPluginIdForContractValue( + contract: "webSearchProviders" | "webFetchProviders", + value: string, +): string | undefined { + const normalized = value.toLowerCase(); + return registry.plugins.find( + (plugin) => + plugin.origin === "bundled" && + plugin.contracts?.[contract]?.some((candidate) => candidate.toLowerCase() === normalized), + )?.id; +} + describe("web provider public artifacts", () => { it("has a public artifact for every bundled web search provider declared in manifests", () => { - const pluginIds = resolveManifestContractPluginIds({ - contract: "webSearchProviders", - origin: "bundled", - }); + const pluginIds = bundledPluginIdsWithContract("webSearchProviders"); expect(pluginIds).not.toHaveLength(0); for (const pluginId of pluginIds) { @@ -48,10 +65,7 @@ describe("web provider public artifacts", () => { }); it("keeps public web search artifacts mapped to their manifest owner plugin", () => { - const pluginIds = resolveManifestContractPluginIds({ - contract: "webSearchProviders", - origin: "bundled", - }); + const pluginIds = bundledPluginIdsWithContract("webSearchProviders"); const providers = resolveBundledExplicitWebSearchProvidersFromPublicArtifacts({ onlyPluginIds: pluginIds, @@ -59,18 +73,13 @@ describe("web provider public artifacts", () => { expect(providers).not.toBeNull(); for (const provider of providers ?? []) { - expect( - resolveManifestContractOwnerPluginId({ - contract: "webSearchProviders", - value: provider.id, - origin: "bundled", - }), - ).toBe(provider.pluginId); + expect(ownerPluginIdForContractValue("webSearchProviders", provider.id)).toBe( + provider.pluginId, + ); } }); it("registers compatibility runtime paths for bundled SecretRef-capable web search providers", () => { - const registry = loadPluginManifestRegistry({ cache: false }); const expectedPluginIds = registry.plugins .filter( (plugin) => @@ -82,20 +91,22 @@ describe("web provider public artifacts", () => { .toSorted((left, right) => left.localeCompare(right)); expect(expectedPluginIds).not.toHaveLength(0); - expect( - resolveManifestContractPluginIdsByCompatibilityRuntimePath({ - contract: "webSearchProviders", - path: "tools.web.search.apiKey", - origin: "bundled", - }), - ).toEqual(expectedPluginIds); + const actualPluginIds = registry.plugins + .filter( + (plugin) => + plugin.origin === "bundled" && + (plugin.contracts?.webSearchProviders?.length ?? 0) > 0 && + (plugin.configContracts?.compatibilityRuntimePaths ?? []).includes( + "tools.web.search.apiKey", + ), + ) + .map((plugin) => plugin.id) + .toSorted((left, right) => left.localeCompare(right)); + expect(actualPluginIds).toEqual(expectedPluginIds); }); it("has a public artifact for every bundled web fetch provider declared in manifests", () => { - const pluginIds = resolveManifestContractPluginIds({ - contract: "webFetchProviders", - origin: "bundled", - }); + const pluginIds = bundledPluginIdsWithContract("webFetchProviders"); expect(pluginIds).not.toHaveLength(0); for (const pluginId of pluginIds) { diff --git a/test/extension-import-boundaries.test.ts b/test/extension-import-boundaries.test.ts index 0cd278d8f24..6761be2dfa7 100644 --- a/test/extension-import-boundaries.test.ts +++ b/test/extension-import-boundaries.test.ts @@ -1,29 +1,11 @@ import { describe, expect, it } from "vitest"; -import { - collectExtensionPluginSdkBoundaryInventory, - main as extensionPluginSdkMain, -} from "../scripts/check-extension-plugin-sdk-boundary.mjs"; -import { - collectSdkPackageExtensionImportBoundaryInventory, - main as sdkPackageMain, -} from "../scripts/check-sdk-package-extension-import-boundary.mjs"; -import { - collectSrcExtensionImportBoundaryInventory, - main as srcExtensionMain, -} from "../scripts/check-src-extension-import-boundary.mjs"; +import { main as extensionPluginSdkMain } from "../scripts/check-extension-plugin-sdk-boundary.mjs"; +import { main as sdkPackageMain } from "../scripts/check-sdk-package-extension-import-boundary.mjs"; +import { main as srcExtensionMain } from "../scripts/check-src-extension-import-boundary.mjs"; import { createCapturedIo } from "./helpers/captured-io.js"; -const srcInventoryPromise = collectSrcExtensionImportBoundaryInventory(); const srcJsonOutputPromise = getJsonOutput(srcExtensionMain, ["--json"]); -const sdkPackageInventoryPromise = collectSdkPackageExtensionImportBoundaryInventory(); const sdkPackageJsonOutputPromise = getJsonOutput(sdkPackageMain, ["--json"]); -const srcOutsideInventoryPromise = - collectExtensionPluginSdkBoundaryInventory("src-outside-plugin-sdk"); -const pluginSdkInternalInventoryPromise = - collectExtensionPluginSdkBoundaryInventory("plugin-sdk-internal"); -const relativeOutsidePackageInventoryPromise = collectExtensionPluginSdkBoundaryInventory( - "relative-outside-package", -); const srcOutsideJsonOutputPromise = getJsonOutput(extensionPluginSdkMain, [ "--mode=src-outside-plugin-sdk", "--json", @@ -53,10 +35,6 @@ async function getJsonOutput( } describe("src extension import boundary inventory", () => { - it("stays empty", async () => { - expect(await srcInventoryPromise).toEqual([]); - }); - it("script json output stays empty", async () => { const jsonOutput = await srcJsonOutputPromise; @@ -67,10 +45,6 @@ describe("src extension import boundary inventory", () => { }); describe("sdk/package extension import boundary inventory", () => { - it("stays empty", async () => { - expect(await sdkPackageInventoryPromise).toEqual([]); - }); - it("script json output stays empty", async () => { const jsonOutput = await sdkPackageJsonOutputPromise; @@ -81,22 +55,9 @@ describe("sdk/package extension import boundary inventory", () => { }); describe("extension src outside plugin-sdk boundary inventory", () => { - it("stays empty and sorted", async () => { - const inventory = await srcOutsideInventoryPromise; + it("script json output stays empty", async () => { const jsonResult = await srcOutsideJsonOutputPromise; - expect(inventory).toEqual([]); - expect( - [...inventory].toSorted( - (left, right) => - left.file.localeCompare(right.file) || - left.line - right.line || - left.kind.localeCompare(right.kind) || - left.specifier.localeCompare(right.specifier) || - left.resolvedPath.localeCompare(right.resolvedPath) || - left.reason.localeCompare(right.reason), - ), - ).toEqual(inventory); expect(jsonResult.exitCode).toBe(0); expect(jsonResult.stderr).toBe(""); expect(jsonResult.json).toEqual([]); @@ -104,11 +65,9 @@ describe("extension src outside plugin-sdk boundary inventory", () => { }); describe("extension plugin-sdk-internal boundary inventory", () => { - it("stays empty", async () => { - const inventory = await pluginSdkInternalInventoryPromise; + it("script json output stays empty", async () => { const jsonResult = await pluginSdkInternalJsonOutputPromise; - expect(inventory).toEqual([]); expect(jsonResult.exitCode).toBe(0); expect(jsonResult.stderr).toBe(""); expect(jsonResult.json).toEqual([]); @@ -116,11 +75,9 @@ describe("extension plugin-sdk-internal boundary inventory", () => { }); describe("extension relative-outside-package boundary inventory", () => { - it("stays empty", async () => { - const inventory = await relativeOutsidePackageInventoryPromise; + it("script json output stays empty", async () => { const jsonResult = await relativeOutsidePackageJsonOutputPromise; - expect(inventory).toEqual([]); expect(jsonResult.exitCode).toBe(0); expect(jsonResult.stderr).toBe(""); expect(jsonResult.json).toEqual([]); diff --git a/test/test-helper-extension-import-boundary.test.ts b/test/test-helper-extension-import-boundary.test.ts index 1e0a3d73f0c..2f7633cffd7 100644 --- a/test/test-helper-extension-import-boundary.test.ts +++ b/test/test-helper-extension-import-boundary.test.ts @@ -10,13 +10,6 @@ describe("test-helper extension import boundary inventory", () => { expect(await collectTestHelperExtensionImportBoundaryInventory()).toEqual([]); }); - it("produces stable sorted output", async () => { - const first = await collectTestHelperExtensionImportBoundaryInventory(); - const second = await collectTestHelperExtensionImportBoundaryInventory(); - - expect(second).toEqual(first); - }); - it("script json output stays empty", async () => { const captured = createCapturedIo(); const exitCode = await main(["--json"], captured.io);