openpetswithchatandmcp/apps/desktop/tests/plugin-ui-static.test.ts
2026-06-18 04:21:57 +00:00

83 lines
6.8 KiB
TypeScript

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const desktopRoot = process.env.FAMILIAROS_DESKTOP_ROOT ?? resolve(dirname(fileURLToPath(import.meta.url)), "..");
const windowsSource = readFileSync(resolve(desktopRoot, "src/windows.ts"), "utf8");
const controlCenterPreloadSource = readFileSync(resolve(desktopRoot, "control-center-preload.cjs"), "utf8");
const controlCenterRendererSource = readFileSync(resolve(desktopRoot, "src/renderer/src/main.tsx"), "utf8");
const familiarWindowSource = readFileSync(resolve(desktopRoot, "src/familiar-window.ts"), "utf8");
const jsHostSource = readFileSync(resolve(desktopRoot, "src/plugin-js-host.ts"), "utf8");
const panelPreloadSource = readFileSync(resolve(desktopRoot, "panel-preload.cjs"), "utf8");
const pluginCommandFormPreloadSource = readFileSync(resolve(desktopRoot, "plugin-command-form-preload.cjs"), "utf8");
const pluginSdkPreloadSource = readFileSync(resolve(desktopRoot, "plugin-sdk-preload.cjs"), "utf8");
const promptWindowPreloadSource = readFileSync(resolve(desktopRoot, "prompt-window-preload.cjs"), "utf8");
const promptWindowSource = readFileSync(resolve(desktopRoot, "src/prompt-window.ts"), "utf8");
assert.doesNotMatch(windowsSource, /openTaskWindow|TaskWindowKind|createPluginsHtml|getPreloadPath|"preload\.cjs"/);
assert.match(windowsSource, /assertAllowedSender\(event, \["control-center"\]\)/);
assert.match(windowsSource, /familiaros:plugins-snapshot/);
assert.match(windowsSource, /familiaros:plugins-save-config/);
assert.match(windowsSource, /familiaros:plugins-load-local/);
assert.match(windowsSource, /familiaros:plugins-catalog-snapshot/);
assert.match(windowsSource, /familiaros:plugins-install-catalog/);
assert.match(windowsSource, /familiaros:plugins-update-catalog/);
assert.match(windowsSource, /familiaros:plugins-uninstall/);
assert.match(windowsSource, /familiaros:plugins-load-local[\s\S]*assertAllowedSender\(event, \["control-center"\]\)/);
assert.match(controlCenterPreloadSource, /getPluginsSnapshot: \(\) => ipcRenderer\.invoke\("familiaros:plugins-snapshot"\)/);
assert.match(controlCenterPreloadSource, /getPluginCatalogSnapshot: \(refresh\) => ipcRenderer\.invoke\("familiaros:plugins-catalog-snapshot", refresh\)/);
assert.match(controlCenterPreloadSource, /setPluginEnabled: \(id, enabled\) => ipcRenderer\.invoke\("familiaros:plugins-set-enabled", id, enabled\)/);
assert.match(controlCenterPreloadSource, /savePluginConfig: \(id, config\) => ipcRenderer\.invoke\("familiaros:plugins-save-config", id, config\)/);
assert.match(controlCenterPreloadSource, /loadLocalPlugin: \(\) => ipcRenderer\.invoke\("familiaros:plugins-load-local"\)/);
assert.match(controlCenterPreloadSource, /installCatalogPlugin: \(id\) => ipcRenderer\.invoke\("familiaros:plugins-install-catalog", id\)/);
assert.match(controlCenterPreloadSource, /uninstallPlugin: \(id\) => ipcRenderer\.invoke\("familiaros:plugins-uninstall", id\)/);
assert.doesNotMatch(controlCenterPreloadSource, /onboarding/i);
assert.doesNotMatch(controlCenterPreloadSource, /plugins-load-local",\s*[^)]/);
assert.doesNotMatch(controlCenterPreloadSource, /manifestPath/);
assert.doesNotMatch(controlCenterPreloadSource, /installPath/);
assert.doesNotMatch(controlCenterPreloadSource, /familiaros:plugins-install-catalog",\s*[^)]+,\s*[^)]/);
assert.match(controlCenterRendererSource, /function PluginsView\(\)/);
assert.match(controlCenterRendererSource, /currentRoute === "plugins"[\s\S]*<PluginsView \/>/);
assert.doesNotMatch(controlCenterRendererSource, /OnboardingView|currentRoute === "onboarding"/);
assert.match(controlCenterRendererSource, /materializeListItemDefaults/);
assert.match(controlCenterRendererSource, /updateCatalogEntry[\s\S]*api\.updateCatalogPlugin/);
assert.match(controlCenterRendererSource, /installed\.source === "catalog"[\s\S]*updateCatalogEntry/);
assert.match(controlCenterRendererSource, /const api = resolveControlCenterApi\(apiBridge\);/);
assert.match(controlCenterRendererSource, /function resolveControlCenterApi\(/);
assert.match(controlCenterRendererSource, /bridge\.familiarOSControlCenter \?\? bridge\.openPetsControlCenter/);
assert.match(jsHostSource, /FamiliarOSPlugin[\s\S]*register/);
assert.match(jsHostSource, /start\(sdk\)/);
assert.match(jsHostSource, /__familiarOSRegisteredPlugin/);
assert.match(jsHostSource, /__openPetsRegisteredPlugin/);
assert.match(jsHostSource, /__familiarOSError/);
assert.match(jsHostSource, /__familiarOSRunCallback \?\? globalThis\.__openPetsRunCallback/);
assert.match(jsHostSource, /preload: getPluginSdkPreloadPath\(\)/);
assert.match(panelPreloadSource, /contextBridge\.exposeInMainWorld\("familiarOSPanel", api\)/);
assert.match(panelPreloadSource, /contextBridge\.exposeInMainWorld\("openPetsPanel", api\)/);
assert.match(pluginCommandFormPreloadSource, /contextBridge\.exposeInMainWorld\("familiarOSCommandForm", api\)/);
assert.match(pluginCommandFormPreloadSource, /contextBridge\.exposeInMainWorld\("openPetsCommandForm", api\)/);
assert.match(promptWindowPreloadSource, /contextBridge\.exposeInMainWorld\("familiarOSPromptWindow", api\)/);
assert.match(promptWindowPreloadSource, /contextBridge\.exposeInMainWorld\("openPetsPromptWindow", api\)/);
assert.match(promptWindowSource, /window\.familiarOSPromptWindow \|\| window\.openPetsPromptWindow/);
assert.match(familiarWindowSource, /window\.familiarOSCommandForm\|\|window\.openPetsCommandForm/);
assert.match(pluginSdkPreloadSource, /__familiarOSError/);
assert.match(pluginSdkPreloadSource, /contextBridge\.exposeInMainWorld\("__familiarOSSdk", sdk\)/);
assert.match(pluginSdkPreloadSource, /contextBridge\.exposeInMainWorld\("__openPetsSdk", sdk\)/);
assert.match(pluginSdkPreloadSource, /contextBridge\.exposeInMainWorld\("__familiarOSRunCallback", runCallback\)/);
assert.match(pluginSdkPreloadSource, /contextBridge\.exposeInMainWorld\("__openPetsRunCallback", runCallback\)/);
assert.match(pluginSdkPreloadSource, /speak: \(spec\) => call\("familiar\.speak", \[petId, spec\]\)/);
assert.match(pluginSdkPreloadSource, /register: \(command, handler\) => call\("commands\.register"/);
// SDK v3 namespaces are exposed to the plugin sandbox.
assert.match(pluginSdkPreloadSource, /bubble: \(spec\) => call\("ui\.bubble", \[spec\]\)/);
assert.match(pluginSdkPreloadSource, /on: \(event, fn\) => subscription\("events\.on", "events\.off"/);
assert.match(pluginSdkPreloadSource, /publish: \(topic, payload\) => call\("bus\.publish", \[topic, payload\]\)/);
// Plugin platform settings are reachable from the Control Center.
assert.match(windowsSource, /familiaros:plugin-platform-settings-get/);
assert.match(windowsSource, /familiaros:plugins-inspector/);
assert.match(controlCenterPreloadSource, /getPluginPlatformSettings: \(\) => ipcRenderer\.invoke\("familiaros:plugin-platform-settings-get"\)/);
console.error("Plugin Control Center static validation passed.");