test: tighten warning and npm integrity coverage

This commit is contained in:
Peter Steinberger 2026-03-13 19:01:16 +00:00
parent 2622b05c0b
commit e928f55537
2 changed files with 110 additions and 32 deletions

View File

@ -6,23 +6,34 @@ import {
describe("resolveNpmIntegrityDrift", () => {
it("returns proceed=true when integrity is missing or unchanged", async () => {
await expect(
resolveNpmIntegrityDrift({
spec: "@openclaw/test@1.0.0",
expectedIntegrity: "sha512-same",
const createPayload = vi.fn(() => "unused");
const cases = [
{
expectedIntegrity: undefined,
resolution: { integrity: "sha512-same", resolvedAt: "2026-01-01T00:00:00.000Z" },
createPayload: () => "unused",
}),
).resolves.toEqual({ proceed: true });
await expect(
resolveNpmIntegrityDrift({
spec: "@openclaw/test@1.0.0",
},
{
expectedIntegrity: "sha512-same",
resolution: { resolvedAt: "2026-01-01T00:00:00.000Z" },
createPayload: () => "unused",
}),
).resolves.toEqual({ proceed: true });
},
{
expectedIntegrity: "sha512-same",
resolution: { integrity: "sha512-same", resolvedAt: "2026-01-01T00:00:00.000Z" },
},
];
for (const testCase of cases) {
await expect(
resolveNpmIntegrityDrift({
spec: "@openclaw/test@1.0.0",
expectedIntegrity: testCase.expectedIntegrity,
resolution: testCase.resolution,
createPayload,
}),
).resolves.toEqual({ proceed: true });
}
expect(createPayload).not.toHaveBeenCalled();
});
it("uses callback on integrity drift", async () => {
@ -52,6 +63,31 @@ describe("resolveNpmIntegrityDrift", () => {
});
});
it("returns payload when the drift callback allows continuing", async () => {
const result = await resolveNpmIntegrityDrift({
spec: "@openclaw/test@1.0.0",
expectedIntegrity: "sha512-old",
resolution: {
integrity: "sha512-new",
resolvedAt: "2026-01-01T00:00:00.000Z",
},
createPayload: ({ spec, actualIntegrity }) => ({ spec, actualIntegrity }),
onIntegrityDrift: async () => true,
});
expect(result).toEqual({
integrityDrift: {
expectedIntegrity: "sha512-old",
actualIntegrity: "sha512-new",
},
payload: {
spec: "@openclaw/test@1.0.0",
actualIntegrity: "sha512-new",
},
proceed: true,
});
});
it("warns by default when no callback is provided", async () => {
const warn = vi.fn();
const result = await resolveNpmIntegrityDrift({
@ -100,4 +136,22 @@ describe("resolveNpmIntegrityDrift", () => {
"aborted: npm package integrity drift detected for @openclaw/test@1.0.0",
);
});
it("falls back to the original spec when resolvedSpec is missing", async () => {
const warn = vi.fn();
await resolveNpmIntegrityDriftWithDefaultMessage({
spec: "@openclaw/test@1.0.0",
expectedIntegrity: "sha512-old",
resolution: {
integrity: "sha512-new",
resolvedAt: "2026-01-01T00:00:00.000Z",
},
warn,
});
expect(warn).toHaveBeenCalledWith(
"Integrity drift detected for @openclaw/test@1.0.0: expected sha512-old, got sha512-new",
);
});
});

View File

@ -12,6 +12,10 @@ function resetWarningFilterInstallState(): void {
process.emitWarning = baseEmitWarning;
}
async function flushWarnings(): Promise<void> {
await new Promise((resolve) => setImmediate(resolve));
}
describe("warning filter", () => {
beforeEach(() => {
resetWarningFilterInstallState();
@ -23,36 +27,49 @@ describe("warning filter", () => {
});
it("suppresses known deprecation and experimental warning signatures", () => {
expect(
shouldIgnoreWarning({
const ignoredWarnings = [
{
name: "DeprecationWarning",
code: "DEP0040",
message: "The punycode module is deprecated.",
}),
).toBe(true);
expect(
shouldIgnoreWarning({
},
{
name: "DeprecationWarning",
code: "DEP0060",
message: "The `util._extend` API is deprecated.",
}),
).toBe(true);
expect(
shouldIgnoreWarning({
},
{
name: "ExperimentalWarning",
message: "SQLite is an experimental feature and might change at any time",
}),
).toBe(true);
},
];
for (const warning of ignoredWarnings) {
expect(shouldIgnoreWarning(warning)).toBe(true);
}
});
it("keeps unknown warnings visible", () => {
expect(
shouldIgnoreWarning({
const visibleWarnings = [
{
name: "DeprecationWarning",
code: "DEP9999",
message: "Totally new warning",
}),
).toBe(false);
},
{
name: "ExperimentalWarning",
message: "Different experimental warning",
},
{
name: "DeprecationWarning",
code: "DEP0040",
message: "Different deprecated module",
},
];
for (const warning of visibleWarnings) {
expect(shouldIgnoreWarning(warning)).toBe(false);
}
});
it("installs once and suppresses known warnings at emit time", async () => {
@ -82,11 +99,18 @@ describe("warning filter", () => {
type: "DeprecationWarning",
code: "DEP0060",
});
await new Promise((resolve) => setImmediate(resolve));
emitWarning(
Object.assign(new Error("The punycode module is deprecated."), {
name: "DeprecationWarning",
code: "DEP0040",
}),
);
await flushWarnings();
expect(seenWarnings.find((warning) => warning.code === "DEP0060")).toBeUndefined();
expect(seenWarnings.find((warning) => warning.code === "DEP0040")).toBeUndefined();
emitWarning("Visible warning", { type: "Warning", code: "OPENCLAW_TEST_WARNING" });
await new Promise((resolve) => setImmediate(resolve));
await flushWarnings();
expect(
seenWarnings.find((warning) => warning.code === "OPENCLAW_TEST_WARNING"),
).toBeDefined();