claude-code-router/packages/electron/test/unit/plugin-app-url.test.ts
2026-07-26 18:09:01 +08:00

120 lines
4.3 KiB
TypeScript

import assert from "node:assert/strict";
import { existsSync } from "node:fs";
import path from "node:path";
import test from "node:test";
import { CLAUDE_DESIGN_PLUGIN_ID } from "@ccr/core/contracts/app.ts";
import { CCR_DESKTOP_APP_ENV } from "@ccr/core/runtime/desktop-app.ts";
import { builtInPluginAppForOpen, configForPluginAppOpen, isLegacyClaudeDesignUrl, pluginAppUrlForOpen } from "@ccr/electron/main/plugin-app-url.ts";
const configWithIgnoredSavedDesignHtml = {
plugins: [
{
config: {
savedHtmlPath: "/tmp/Claude Design.html",
useSavedHtml: true
},
enabled: true,
id: "claude-design"
}
]
} as any;
test("Claude Design app URLs classify legacy Claude Design entries as legacy", () => {
assert.equal(isLegacyClaudeDesignUrl("https://claude.ai/discover/design"), true);
assert.equal(isLegacyClaudeDesignUrl("https://claude.ai/design"), true);
assert.equal(isLegacyClaudeDesignUrl("https://claude-design.ccrdesk.top/design"), false);
assert.equal(isLegacyClaudeDesignUrl("https://example.com/discover/design"), false);
});
test("Claude Design app opening migrates legacy Design URLs to the current shell", () => {
assert.equal(
pluginAppUrlForOpen(
configWithIgnoredSavedDesignHtml,
"claude-design",
"https://claude.ai/discover/design"
),
"https://claude-design.ccrdesk.top/design"
);
});
test("Claude Design app opening keeps current and non-Design app URLs unchanged", () => {
assert.equal(
pluginAppUrlForOpen(
configWithIgnoredSavedDesignHtml,
"claude-design",
"https://claude-design.ccrdesk.top/design"
),
"https://claude-design.ccrdesk.top/design"
);
assert.equal(
pluginAppUrlForOpen(
configWithIgnoredSavedDesignHtml,
"claude-ship",
"https://example.com/discover/design"
),
"https://example.com/discover/design"
);
});
test("Claude Design resolves to the built-in app without installed plugin config", () => {
const pluginApp = builtInPluginAppForOpen(CLAUDE_DESIGN_PLUGIN_ID);
assert.equal(pluginApp?.id, "claude-design");
assert.equal(pluginApp?.name, "Claude Design");
assert.equal(pluginApp?.url, "https://claude-design.ccrdesk.top/design");
assert.equal(builtInPluginAppForOpen("unknown-plugin"), undefined);
assert.equal(builtInPluginAppForOpen(CLAUDE_DESIGN_PLUGIN_ID, "missing"), undefined);
});
test("Claude Design app opening injects the runtime plugin config", () => {
withDesktopRuntime(() => {
const config = { plugins: [] } as any;
const runtimeConfig = configForPluginAppOpen(config, CLAUDE_DESIGN_PLUGIN_ID);
assert.equal(config.plugins.length, 0);
assert.equal(runtimeConfig.plugins.length, 1);
assert.equal(runtimeConfig.plugins[0].id, CLAUDE_DESIGN_PLUGIN_ID);
assert.equal(runtimeConfig.plugins[0].module, bundledPluginModule("claude-design"));
assert.equal(configForPluginAppOpen(config, "claude-ship"), config);
});
});
test("Claude Design app opening fills an existing built-in plugin config without a module", () => {
withDesktopRuntime(() => {
const config = {
plugins: [{
config: { savedHtmlPath: "/tmp/Claude Design.html" },
enabled: true,
id: CLAUDE_DESIGN_PLUGIN_ID
}]
} as any;
const runtimeConfig = configForPluginAppOpen(config, CLAUDE_DESIGN_PLUGIN_ID);
assert.equal(config.plugins[0].module, undefined);
assert.equal(runtimeConfig.plugins.length, 1);
assert.equal(runtimeConfig.plugins[0].module, bundledPluginModule("claude-design"));
assert.deepEqual(runtimeConfig.plugins[0].config, { savedHtmlPath: "/tmp/Claude Design.html" });
});
});
function bundledPluginModule(pluginId: string): string {
const distModule = path.resolve(process.cwd(), "packages", "electron", "dist", "bundled-plugins", pluginId, "index.cjs");
return existsSync(distModule)
? distModule
: path.resolve(process.cwd(), "packages", "electron", "bundled-plugins", pluginId, "index.cjs");
}
function withDesktopRuntime(run: () => void): void {
const previousDesktopApp = process.env[CCR_DESKTOP_APP_ENV];
try {
process.env[CCR_DESKTOP_APP_ENV] = "1";
run();
} finally {
if (previousDesktopApp === undefined) {
delete process.env[CCR_DESKTOP_APP_ENV];
} else {
process.env[CCR_DESKTOP_APP_ENV] = previousDesktopApp;
}
}
}