Files
openclaw/src/plugins/lazy-service-module.test.ts
Agustin Rivera dafcaf9d69 fix(browser): harden browser control override loading (#62663)
* fix(browser): harden browser control overrides

* fix(lint): prepare boundary artifacts for extension oxlint

* docs(changelog): add browser override hardening entry

* fix(lint): avoid duplicate boundary prep

---------

Co-authored-by: Devin Robison <drobison@nvidia.com>
Co-authored-by: Devin Robison <drobison00@users.noreply.github.com>
2026-04-08 13:24:47 -06:00

122 lines
4.2 KiB
TypeScript

import { afterEach, describe, expect, it, vi } from "vitest";
import { startLazyPluginServiceModule } from "./lazy-service-module.js";
function createAsyncHookMock() {
return vi.fn(async () => {});
}
function createLazyModuleLifecycle() {
const start = createAsyncHookMock();
const stop = createAsyncHookMock();
return {
start,
stop,
module: {
startDefault: start,
stopDefault: stop,
},
};
}
async function expectLifecycleStarted(params: {
overrideEnvVar?: string;
validateOverrideSpecifier?: (specifier: string) => string;
loadDefaultModule?: () => Promise<Record<string, unknown>>;
loadOverrideModule?: (spec: string) => Promise<Record<string, unknown>>;
startExportNames: string[];
stopExportNames?: string[];
}) {
return startLazyPluginServiceModule({
...(params.overrideEnvVar ? { overrideEnvVar: params.overrideEnvVar } : {}),
...(params.validateOverrideSpecifier
? { validateOverrideSpecifier: params.validateOverrideSpecifier }
: {}),
loadDefaultModule: params.loadDefaultModule ?? (async () => createLazyModuleLifecycle().module),
...(params.loadOverrideModule ? { loadOverrideModule: params.loadOverrideModule } : {}),
startExportNames: params.startExportNames,
...(params.stopExportNames ? { stopExportNames: params.stopExportNames } : {}),
});
}
describe("startLazyPluginServiceModule", () => {
afterEach(() => {
delete process.env.OPENCLAW_LAZY_SERVICE_SKIP;
delete process.env.OPENCLAW_LAZY_SERVICE_OVERRIDE;
});
it("starts the default module and returns its stop hook", async () => {
const lifecycle = createLazyModuleLifecycle();
const handle = await expectLifecycleStarted({
loadDefaultModule: async () => lifecycle.module,
startExportNames: ["startDefault"],
stopExportNames: ["stopDefault"],
});
expect(lifecycle.start).toHaveBeenCalledTimes(1);
expect(handle).not.toBeNull();
await handle?.stop();
expect(lifecycle.stop).toHaveBeenCalledTimes(1);
});
it("honors skip env before loading the module", async () => {
process.env.OPENCLAW_LAZY_SERVICE_SKIP = "1";
const loadDefaultModule = vi.fn(async () => createLazyModuleLifecycle().module);
const handle = await startLazyPluginServiceModule({
skipEnvVar: "OPENCLAW_LAZY_SERVICE_SKIP",
loadDefaultModule,
startExportNames: ["startDefault"],
});
expect(handle).toBeNull();
expect(loadDefaultModule).not.toHaveBeenCalled();
});
it("uses the override module when configured", async () => {
process.env.OPENCLAW_LAZY_SERVICE_OVERRIDE = "virtual:service";
const start = createAsyncHookMock();
const loadOverrideModule = vi.fn(async () => ({ startOverride: start }));
await expectLifecycleStarted({
overrideEnvVar: "OPENCLAW_LAZY_SERVICE_OVERRIDE",
loadDefaultModule: async () => ({ startDefault: createAsyncHookMock() }),
loadOverrideModule,
startExportNames: ["startOverride", "startDefault"],
});
expect(loadOverrideModule).toHaveBeenCalledWith("virtual:service");
expect(start).toHaveBeenCalledTimes(1);
});
it("validates the override specifier before loading it", async () => {
process.env.OPENCLAW_LAZY_SERVICE_OVERRIDE = "virtual:service";
const loadOverrideModule = vi.fn(async () => ({ startOverride: createAsyncHookMock() }));
const validateOverrideSpecifier = vi.fn((specifier: string) => `validated:${specifier}`);
await expectLifecycleStarted({
overrideEnvVar: "OPENCLAW_LAZY_SERVICE_OVERRIDE",
validateOverrideSpecifier,
loadOverrideModule,
startExportNames: ["startOverride"],
});
expect(validateOverrideSpecifier).toHaveBeenCalledWith("virtual:service");
expect(loadOverrideModule).toHaveBeenCalledWith("validated:virtual:service");
});
it("surfaces override validation failures", async () => {
process.env.OPENCLAW_LAZY_SERVICE_OVERRIDE = "data:text/javascript,boom";
await expect(
expectLifecycleStarted({
overrideEnvVar: "OPENCLAW_LAZY_SERVICE_OVERRIDE",
validateOverrideSpecifier: () => {
throw new Error("blocked override");
},
startExportNames: ["startDefault"],
}),
).rejects.toThrow("blocked override");
});
});