diff --git a/src/version.test.ts b/src/version.test.ts index d8d1f4fa5..c6bc5acf0 100644 --- a/src/version.test.ts +++ b/src/version.test.ts @@ -23,17 +23,22 @@ function moduleUrlFrom(root: string, relativePath: string): string { return pathToFileURL(path.join(root, relativePath)).href; } +async function ensureModuleFixture(root: string, relativePath = "dist/plugin-sdk/index.js") { + await fs.mkdir(path.dirname(path.join(root, relativePath)), { recursive: true }); + return moduleUrlFrom(root, relativePath); +} + +async function writeJsonFixture(root: string, relativePath: string, value: unknown) { + const filePath = path.join(root, relativePath); + await fs.mkdir(path.dirname(filePath), { recursive: true }); + await fs.writeFile(filePath, JSON.stringify(value), "utf-8"); +} + describe("version resolution", () => { it("resolves package version from nested dist/plugin-sdk module URL", async () => { await withTempDir(async (root) => { - await fs.mkdir(path.join(root, "dist", "plugin-sdk"), { recursive: true }); - await fs.writeFile( - path.join(root, "package.json"), - JSON.stringify({ name: "openclaw", version: "1.2.3" }), - "utf-8", - ); - - const moduleUrl = moduleUrlFrom(root, "dist/plugin-sdk/index.js"); + await writeJsonFixture(root, "package.json", { name: "openclaw", version: "1.2.3" }); + const moduleUrl = await ensureModuleFixture(root); expect(readVersionFromPackageJsonForModuleUrl(moduleUrl)).toBe("1.2.3"); expect(resolveVersionFromModuleUrl(moduleUrl)).toBe("1.2.3"); }); @@ -41,33 +46,20 @@ describe("version resolution", () => { it("ignores unrelated nearby package.json files", async () => { await withTempDir(async (root) => { - await fs.mkdir(path.join(root, "dist", "plugin-sdk"), { recursive: true }); - await fs.writeFile( - path.join(root, "package.json"), - JSON.stringify({ name: "openclaw", version: "2.3.4" }), - "utf-8", - ); - await fs.writeFile( - path.join(root, "dist", "package.json"), - JSON.stringify({ name: "other-package", version: "9.9.9" }), - "utf-8", - ); - - const moduleUrl = moduleUrlFrom(root, "dist/plugin-sdk/index.js"); + await writeJsonFixture(root, "package.json", { name: "openclaw", version: "2.3.4" }); + await writeJsonFixture(root, "dist/package.json", { + name: "other-package", + version: "9.9.9", + }); + const moduleUrl = await ensureModuleFixture(root); expect(readVersionFromPackageJsonForModuleUrl(moduleUrl)).toBe("2.3.4"); }); }); it("falls back to build-info when package metadata is unavailable", async () => { await withTempDir(async (root) => { - await fs.mkdir(path.join(root, "dist", "plugin-sdk"), { recursive: true }); - await fs.writeFile( - path.join(root, "build-info.json"), - JSON.stringify({ version: "4.5.6" }), - "utf-8", - ); - - const moduleUrl = moduleUrlFrom(root, "dist/plugin-sdk/index.js"); + await writeJsonFixture(root, "build-info.json", { version: "4.5.6" }); + const moduleUrl = await ensureModuleFixture(root); expect(readVersionFromPackageJsonForModuleUrl(moduleUrl)).toBeNull(); expect(readVersionFromBuildInfoForModuleUrl(moduleUrl)).toBe("4.5.6"); expect(resolveVersionFromModuleUrl(moduleUrl)).toBe("4.5.6"); @@ -76,15 +68,30 @@ describe("version resolution", () => { it("returns null when no version metadata exists", async () => { await withTempDir(async (root) => { - await fs.mkdir(path.join(root, "dist", "plugin-sdk"), { recursive: true }); - - const moduleUrl = moduleUrlFrom(root, "dist/plugin-sdk/index.js"); + const moduleUrl = await ensureModuleFixture(root); expect(readVersionFromPackageJsonForModuleUrl(moduleUrl)).toBeNull(); expect(readVersionFromBuildInfoForModuleUrl(moduleUrl)).toBeNull(); expect(resolveVersionFromModuleUrl(moduleUrl)).toBeNull(); }); }); + it("ignores non-openclaw package and blank build-info versions", async () => { + await withTempDir(async (root) => { + await writeJsonFixture(root, "package.json", { name: "other-package", version: "9.9.9" }); + await writeJsonFixture(root, "build-info.json", { version: " " }); + const moduleUrl = await ensureModuleFixture(root); + expect(readVersionFromPackageJsonForModuleUrl(moduleUrl)).toBeNull(); + expect(readVersionFromBuildInfoForModuleUrl(moduleUrl)).toBeNull(); + expect(resolveVersionFromModuleUrl(moduleUrl)).toBeNull(); + }); + }); + + it("returns null for malformed module URLs", () => { + expect(readVersionFromPackageJsonForModuleUrl("not-a-valid-url")).toBeNull(); + expect(readVersionFromBuildInfoForModuleUrl("not-a-valid-url")).toBeNull(); + expect(resolveVersionFromModuleUrl("not-a-valid-url")).toBeNull(); + }); + it("prefers OPENCLAW_VERSION over service and package versions", () => { expect( resolveRuntimeServiceVersion({