Files
pi/packages/coding-agent/test/version-check.test.ts
Mario Zechner 8b57630bc9 Release v0.74.2
Fixes #4876
2026-05-22 00:18:08 +02:00

85 lines
3.0 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "vitest";
import {
checkForNewPiVersion,
comparePackageVersions,
getLatestPiRelease,
getLatestPiVersion,
isNewerPackageVersion,
isNodeVersionAtLeast,
MINIMUM_NODE_VERSION_FOR_LATEST_PI,
} from "../src/utils/version-check.js";
const originalSkipVersionCheck = process.env.PI_SKIP_VERSION_CHECK;
const originalOffline = process.env.PI_OFFLINE;
afterEach(() => {
vi.unstubAllGlobals();
if (originalSkipVersionCheck === undefined) {
delete process.env.PI_SKIP_VERSION_CHECK;
} else {
process.env.PI_SKIP_VERSION_CHECK = originalSkipVersionCheck;
}
if (originalOffline === undefined) {
delete process.env.PI_OFFLINE;
} else {
process.env.PI_OFFLINE = originalOffline;
}
});
describe("version checks", () => {
it("compares package versions", () => {
expect(comparePackageVersions("0.70.6", "0.70.5")).toBeGreaterThan(0);
expect(comparePackageVersions("0.70.5", "0.70.5")).toBe(0);
expect(comparePackageVersions("0.70.4", "0.70.5")).toBeLessThan(0);
expect(isNewerPackageVersion("0.70.5", "0.70.5")).toBe(false);
expect(isNewerPackageVersion("0.70.6", "0.70.5")).toBe(true);
});
it("checks the Node version required by current pi releases", () => {
expect(MINIMUM_NODE_VERSION_FOR_LATEST_PI).toBe("22.19.0");
expect(isNodeVersionAtLeast("20.19.4", MINIMUM_NODE_VERSION_FOR_LATEST_PI)).toBe(false);
expect(isNodeVersionAtLeast("22.19.0", MINIMUM_NODE_VERSION_FOR_LATEST_PI)).toBe(true);
expect(isNodeVersionAtLeast("23.0.0", MINIMUM_NODE_VERSION_FOR_LATEST_PI)).toBe(true);
});
it("returns only newer versions", async () => {
const fetchMock = vi.fn(async () => Response.json({ version: "1.2.3" }));
vi.stubGlobal("fetch", fetchMock);
await expect(checkForNewPiVersion("1.2.3")).resolves.toBeUndefined();
await expect(checkForNewPiVersion("1.2.2")).resolves.toBe("1.2.3");
});
it("uses the pi.dev version check api with a pi user agent", async () => {
const fetchMock = vi.fn(async () => Response.json({ version: "1.2.4" }));
vi.stubGlobal("fetch", fetchMock);
await expect(getLatestPiVersion("1.2.3")).resolves.toBe("1.2.4");
expect(fetchMock).toHaveBeenCalledWith(
"https://pi.dev/api/latest-version",
expect.objectContaining({
headers: expect.objectContaining({
"User-Agent": expect.stringMatching(/^pi\/1\.2\.3 /),
accept: "application/json",
}),
}),
);
});
it("returns the active package name from the version check api", async () => {
const fetchMock = vi.fn(async () => Response.json({ packageName: "@new-scope/pi", version: "1.2.4" }));
vi.stubGlobal("fetch", fetchMock);
await expect(getLatestPiRelease("1.2.3")).resolves.toEqual({ packageName: "@new-scope/pi", version: "1.2.4" });
});
it("skips api calls when version checks are disabled", async () => {
process.env.PI_SKIP_VERSION_CHECK = "1";
const fetchMock = vi.fn();
vi.stubGlobal("fetch", fetchMock);
await expect(getLatestPiVersion("1.2.3")).resolves.toBeUndefined();
expect(fetchMock).not.toHaveBeenCalled();
});
});