plugin-inspector/test/issues.test.js
Vincent Koc f642fb5c9f
fix(reports): quiet resolved package entrypoint P0s
Fix compatibility report classification so built runtime package entrypoints satisfy source-form OpenClaw metadata, SDK export alias misses collapse into a single compat-gap row, and P0 live issues are not repeated under the general live section.
2026-05-05 00:34:18 -07:00

133 lines
4.9 KiB
JavaScript

import assert from "node:assert/strict";
import { test } from "node:test";
import { buildIssues, classifyIssueFinding, issueId, knownIssueCodes, summarizeIssueClasses } from "../src/advanced.js";
test("issue ids are stable fingerprints", () => {
const finding = {
fixture: "codex-app-server",
code: "sdk-export-missing",
severity: "P1",
compatRecord: "plugin-sdk-export-aliases",
evidence: ["openclaw/plugin-sdk/legacy-helper @ plugins/sample-plugin/src/controller.ts:104"],
};
assert.equal(issueId(finding), issueId({ ignored: "field", ...finding }));
assert.notEqual(issueId(finding), issueId({ ...finding, evidence: [...finding.evidence, "extra"] }));
assert.match(issueId(finding, { prefix: "PLUGIN" }), /^PLUGIN-[A-F0-9]{8}$/);
});
test("issue classification separates live breaks from compat and deprecation buckets", () => {
const cases = [
{
name: "untracked SDK alias is a compat gap",
finding: { code: "sdk-export-missing", compatRecord: "plugin-sdk-export-aliases" },
targetOpenClaw: { compatRecordStatuses: {} },
metadata: { severity: "P1" },
expected: { issueClass: "compat-gap", compatStatus: "untracked", severity: "P1", live: false },
},
{
name: "active SDK alias compat stays a compat row",
finding: { code: "sdk-export-missing", compatRecord: "plugin-sdk-export-aliases" },
targetOpenClaw: { compatRecordStatuses: { "plugin-sdk-export-aliases": "active" } },
metadata: { severity: "P1" },
expected: { issueClass: "compat-gap", compatStatus: "active", severity: "P1", live: false },
},
{
name: "deprecated compat remains warning-class even when used",
finding: { code: "legacy-before-agent-start", compatRecord: "legacy-before-agent-start" },
targetOpenClaw: { compatRecordStatuses: { "legacy-before-agent-start": "deprecated" } },
metadata: { severity: "P2" },
expected: { issueClass: "deprecation-warning", compatStatus: "deprecated", severity: "P2", deprecated: true },
},
{
name: "missing compat record is a compat gap",
finding: { code: "missing-compat-record", compatRecord: "plugin-sdk-export-aliases" },
targetOpenClaw: { compatRecordStatuses: {} },
metadata: { severity: "P1" },
expected: { issueClass: "compat-gap", compatStatus: "missing", severity: "P1", live: false },
},
{
name: "active OpenClaw probe contract stays an inspector gap",
finding: {
code: "before-tool-call-probe",
compatRecord: "hook.before_tool_call.terminal-block-approval",
},
targetOpenClaw: {
compatRecordStatuses: { "hook.before_tool_call.terminal-block-approval": "active" },
},
metadata: { severity: "P1" },
expected: { issueClass: "inspector-gap", compatStatus: "active", severity: "P1", live: false },
},
{
name: "unknown untracked hook is P0 live break",
finding: { code: "unknown-hook-name" },
targetOpenClaw: { compatRecordStatuses: {} },
metadata: { severity: "P1" },
expected: { issueClass: "live-issue", compatStatus: "none", severity: "P0", live: true },
},
];
for (const item of cases) {
assert.deepEqual(
pick(classifyIssueFinding(item.finding, item.targetOpenClaw, item.metadata), Object.keys(item.expected)),
item.expected,
item.name,
);
}
});
test("issue builder applies metadata and class summaries", () => {
const issues = buildIssues({
warnings: [
{
fixture: "codex-app-server",
code: "sdk-export-missing",
level: "warning",
message: "missing sdk export",
compatRecord: "plugin-sdk-export-aliases",
evidence: ["openclaw/plugin-sdk/legacy-helper"],
},
{
fixture: "agentchat",
code: "manifest-unknown-fields",
level: "warning",
message: "unknown field",
evidence: ["openclaw.plugin.json:channelEnvVars"],
},
],
suggestions: [
{
fixture: "wecom",
code: "registration-capture-gap",
level: "suggestion",
message: "capture registrar",
evidence: ["registerChannel"],
},
],
targetOpenClaw: { compatRecordStatuses: {} },
});
assert.ok(knownIssueCodes.has("sdk-export-missing"));
assert.ok(knownIssueCodes.has("reserved-sdk-import"));
assert.deepEqual(
issues.map((issue) => [issue.fixture, issue.code, issue.severity, issue.issueClass, issue.status]),
[
["codex-app-server", "sdk-export-missing", "P1", "compat-gap", "open"],
["agentchat", "manifest-unknown-fields", "P2", "upstream-metadata", "open"],
["wecom", "registration-capture-gap", "P2", "inspector-gap", "open"],
],
);
assert.deepEqual(summarizeIssueClasses(issues), {
"compat-gap": 1,
"deprecation-warning": 0,
"fixture-regression": 0,
"inspector-gap": 1,
"live-issue": 0,
"upstream-metadata": 1,
});
});
function pick(value, keys) {
return Object.fromEntries(keys.map((key) => [key, value[key]]));
}