mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 05:50:42 +00:00
test: tighten official channel catalog assertions
This commit is contained in:
@@ -42,6 +42,28 @@ function requireNpmInstallSource(source: ReturnType<typeof describePluginInstall
|
||||
return source.npm;
|
||||
}
|
||||
|
||||
function findCatalogEntry(
|
||||
entries: OfficialChannelCatalogEntry[],
|
||||
predicate: (entry: OfficialChannelCatalogEntry) => boolean,
|
||||
): OfficialChannelCatalogEntry {
|
||||
const entry = entries.find(predicate);
|
||||
if (!entry) {
|
||||
throw new Error("expected official channel catalog entry");
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
function summarizeCatalogEntry(entry: OfficialChannelCatalogEntry) {
|
||||
return {
|
||||
name: entry.name,
|
||||
description: entry.description,
|
||||
source: entry.source,
|
||||
plugin: entry.openclaw?.plugin,
|
||||
channel: entry.openclaw?.channel,
|
||||
install: entry.openclaw?.install,
|
||||
};
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
cleanupTempDirs(tempDirs);
|
||||
});
|
||||
@@ -91,66 +113,93 @@ describe("buildOfficialChannelCatalog", () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(buildOfficialChannelCatalog({ repoRoot }).entries).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "@wecom/wecom-openclaw-plugin",
|
||||
openclaw: expect.objectContaining({
|
||||
plugin: {
|
||||
id: "wecom-openclaw-plugin",
|
||||
label: "WeCom",
|
||||
},
|
||||
channel: expect.objectContaining({
|
||||
id: "wecom",
|
||||
label: "WeCom",
|
||||
}),
|
||||
install: {
|
||||
npmSpec: "@wecom/wecom-openclaw-plugin@2026.4.23",
|
||||
defaultChoice: "npm",
|
||||
expectedIntegrity:
|
||||
"sha512-bnzfdIEEu1/LFvcdyjaTkyxt27w6c7dqhkPezU62OWaqmcdFsUGR3T55USK/O9pIKsNcnL1Tnu1pqKYCWHFgWQ==",
|
||||
},
|
||||
}),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
name: "openclaw-plugin-yuanbao",
|
||||
openclaw: expect.objectContaining({
|
||||
plugin: {
|
||||
id: "openclaw-plugin-yuanbao",
|
||||
label: "Yuanbao",
|
||||
},
|
||||
channel: expect.objectContaining({
|
||||
id: "yuanbao",
|
||||
label: "Yuanbao",
|
||||
}),
|
||||
install: {
|
||||
npmSpec: "openclaw-plugin-yuanbao@2.13.0",
|
||||
defaultChoice: "npm",
|
||||
expectedIntegrity:
|
||||
"sha512-mx6b2gO8oqZxECG9NLLQofScaIZXjmQXqJxevagVx8IKXLGeLrpTWlvnW1P2NP5dqaSMrkvBsgJqtW+rVM7h4w==",
|
||||
},
|
||||
}),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
name: "@openclaw/whatsapp",
|
||||
description: "OpenClaw WhatsApp channel plugin",
|
||||
source: "official",
|
||||
openclaw: expect.objectContaining({
|
||||
channel: expect.objectContaining({
|
||||
id: "whatsapp",
|
||||
label: "WhatsApp",
|
||||
selectionLabel: "WhatsApp (QR link)",
|
||||
detailLabel: "WhatsApp Web",
|
||||
docsPath: "/channels/whatsapp",
|
||||
}),
|
||||
install: expect.objectContaining({
|
||||
npmSpec: "@openclaw/whatsapp",
|
||||
defaultChoice: "npm",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
const entries = buildOfficialChannelCatalog({ repoRoot }).entries;
|
||||
|
||||
expect(
|
||||
summarizeCatalogEntry(
|
||||
findCatalogEntry(entries, (entry) => entry.name === "@wecom/wecom-openclaw-plugin"),
|
||||
),
|
||||
).toEqual({
|
||||
name: "@wecom/wecom-openclaw-plugin",
|
||||
description: "OpenClaw WeCom channel plugin by the Tencent WeCom team.",
|
||||
source: "external",
|
||||
plugin: {
|
||||
id: "wecom-openclaw-plugin",
|
||||
label: "WeCom",
|
||||
},
|
||||
channel: {
|
||||
id: "wecom",
|
||||
label: "WeCom",
|
||||
selectionLabel: "WeCom(企业微信)",
|
||||
detailLabel: "WeCom",
|
||||
docsLabel: "wecom",
|
||||
docsPath: "/plugins/community#wecom",
|
||||
blurb: "Enterprise messaging and documents, scheduling, task tools.",
|
||||
order: 45,
|
||||
aliases: ["qywx", "wework", "enterprise-wechat"],
|
||||
},
|
||||
install: {
|
||||
npmSpec: "@wecom/wecom-openclaw-plugin@2026.4.23",
|
||||
defaultChoice: "npm",
|
||||
expectedIntegrity:
|
||||
"sha512-bnzfdIEEu1/LFvcdyjaTkyxt27w6c7dqhkPezU62OWaqmcdFsUGR3T55USK/O9pIKsNcnL1Tnu1pqKYCWHFgWQ==",
|
||||
},
|
||||
});
|
||||
expect(
|
||||
summarizeCatalogEntry(
|
||||
findCatalogEntry(entries, (entry) => entry.name === "openclaw-plugin-yuanbao"),
|
||||
),
|
||||
).toEqual({
|
||||
name: "openclaw-plugin-yuanbao",
|
||||
description: "OpenClaw Yuanbao channel plugin by the Tencent Yuanbao team.",
|
||||
source: "external",
|
||||
plugin: {
|
||||
id: "openclaw-plugin-yuanbao",
|
||||
label: "Yuanbao",
|
||||
},
|
||||
channel: {
|
||||
id: "yuanbao",
|
||||
label: "Yuanbao",
|
||||
selectionLabel: "Yuanbao (元宝)",
|
||||
detailLabel: "Yuanbao",
|
||||
docsLabel: "yuanbao",
|
||||
docsPath: "/plugins/community#yuanbao",
|
||||
blurb: "Tencent Yuanbao AI assistant conversation channel.",
|
||||
order: 85,
|
||||
aliases: ["yuanbao", "yb", "tencent-yuanbao", "元宝"],
|
||||
},
|
||||
install: {
|
||||
npmSpec: "openclaw-plugin-yuanbao@2.13.0",
|
||||
defaultChoice: "npm",
|
||||
expectedIntegrity:
|
||||
"sha512-mx6b2gO8oqZxECG9NLLQofScaIZXjmQXqJxevagVx8IKXLGeLrpTWlvnW1P2NP5dqaSMrkvBsgJqtW+rVM7h4w==",
|
||||
},
|
||||
});
|
||||
expect(
|
||||
summarizeCatalogEntry(
|
||||
findCatalogEntry(entries, (entry) => entry.name === "@openclaw/whatsapp"),
|
||||
),
|
||||
).toEqual({
|
||||
name: "@openclaw/whatsapp",
|
||||
description: "OpenClaw WhatsApp channel plugin",
|
||||
source: "official",
|
||||
plugin: undefined,
|
||||
channel: {
|
||||
id: "whatsapp",
|
||||
label: "WhatsApp",
|
||||
selectionLabel: "WhatsApp (QR link)",
|
||||
detailLabel: "WhatsApp Web",
|
||||
docsLabel: "whatsapp",
|
||||
docsPath: "/channels/whatsapp",
|
||||
blurb: "works with your own number; recommend a separate phone + eSIM.",
|
||||
systemImage: "message",
|
||||
},
|
||||
install: {
|
||||
npmSpec: "@openclaw/whatsapp",
|
||||
defaultChoice: "npm",
|
||||
minHostVersion: ">=2026.4.25",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps third-party official external catalog npm sources exactly pinned", () => {
|
||||
@@ -173,18 +222,17 @@ describe("buildOfficialChannelCatalog", () => {
|
||||
(entry) => entry.openclaw?.channel?.id === "twitch",
|
||||
);
|
||||
|
||||
expect(twitch).toEqual(
|
||||
expect.objectContaining({
|
||||
name: "@openclaw/twitch",
|
||||
openclaw: expect.objectContaining({
|
||||
install: {
|
||||
npmSpec: "@openclaw/twitch",
|
||||
defaultChoice: "npm",
|
||||
minHostVersion: ">=2026.4.10",
|
||||
},
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect({
|
||||
name: twitch?.name,
|
||||
install: twitch?.openclaw?.install,
|
||||
}).toEqual({
|
||||
name: "@openclaw/twitch",
|
||||
install: {
|
||||
npmSpec: "@openclaw/twitch",
|
||||
defaultChoice: "npm",
|
||||
minHostVersion: ">=2026.4.10",
|
||||
},
|
||||
});
|
||||
const installSource = describePluginInstallSource(requireInstall(twitch));
|
||||
expect(requireNpmInstallSource(installSource).pinState).toBe("floating-without-integrity");
|
||||
expect(installSource.warnings).toEqual(["npm-spec-floating", "npm-spec-missing-integrity"]);
|
||||
@@ -249,33 +297,40 @@ describe("buildOfficialChannelCatalog", () => {
|
||||
|
||||
const outputPath = path.join(repoRoot, OFFICIAL_CHANNEL_CATALOG_RELATIVE_PATH);
|
||||
expect(fs.existsSync(outputPath)).toBe(true);
|
||||
expect(JSON.parse(fs.readFileSync(outputPath, "utf8")).entries).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
name: "@wecom/wecom-openclaw-plugin",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
name: "openclaw-plugin-yuanbao",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
name: "@openclaw/whatsapp",
|
||||
source: "official",
|
||||
openclaw: expect.objectContaining({
|
||||
channel: expect.objectContaining({
|
||||
id: "whatsapp",
|
||||
label: "WhatsApp",
|
||||
selectionLabel: "WhatsApp (QR link)",
|
||||
docsPath: "/channels/whatsapp",
|
||||
}),
|
||||
install: expect.objectContaining({
|
||||
npmSpec: "@openclaw/whatsapp",
|
||||
defaultChoice: "npm",
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
]),
|
||||
const entries = JSON.parse(fs.readFileSync(outputPath, "utf8")).entries;
|
||||
expect(entries.map((entry: { name?: string }) => entry.name)).toContain(
|
||||
"@wecom/wecom-openclaw-plugin",
|
||||
);
|
||||
const whatsappEntries = JSON.parse(fs.readFileSync(outputPath, "utf8")).entries.filter(
|
||||
expect(entries.map((entry: { name?: string }) => entry.name)).toContain(
|
||||
"openclaw-plugin-yuanbao",
|
||||
);
|
||||
const whatsappEntry = findCatalogEntry(
|
||||
entries,
|
||||
(entry: { openclaw?: { channel?: { id?: string } } }) =>
|
||||
entry.openclaw?.channel?.id === "whatsapp",
|
||||
);
|
||||
expect(summarizeCatalogEntry(whatsappEntry)).toEqual({
|
||||
name: "@openclaw/whatsapp",
|
||||
description: "OpenClaw WhatsApp channel plugin",
|
||||
source: "official",
|
||||
plugin: undefined,
|
||||
channel: {
|
||||
id: "whatsapp",
|
||||
label: "WhatsApp",
|
||||
selectionLabel: "WhatsApp (QR link)",
|
||||
detailLabel: "WhatsApp Web",
|
||||
docsLabel: "whatsapp",
|
||||
docsPath: "/channels/whatsapp",
|
||||
blurb: "works with your own number; recommend a separate phone + eSIM.",
|
||||
systemImage: "message",
|
||||
},
|
||||
install: {
|
||||
npmSpec: "@openclaw/whatsapp",
|
||||
defaultChoice: "npm",
|
||||
minHostVersion: ">=2026.4.25",
|
||||
},
|
||||
});
|
||||
const whatsappEntries = entries.filter(
|
||||
(entry: { openclaw?: { channel?: { id?: string } } }) =>
|
||||
entry.openclaw?.channel?.id === "whatsapp",
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user