Files
ThreadNet-Web/modules/widget-lifecycle/src/WidgetLifecycleModule.test.ts
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

154 lines
4.8 KiB
TypeScript
Raw Normal View History

2026-02-25 09:36:58 +00:00
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { vi, describe, expect, it } from "vitest";
2026-02-25 09:36:58 +00:00
2026-06-10 17:00:34 +01:00
import WidgetLifecycleModule, { type WidgetLifecycleApiAdapter } from "./WidgetLifecycleModule";
2026-02-25 09:36:58 +00:00
import type {
CapabilitiesApprover,
IdentityApprover,
PreloadApprover,
WidgetDescriptor,
2026-06-10 17:00:34 +01:00
Api,
2026-02-25 09:36:58 +00:00
} from "@element-hq/element-web-module-api";
const createApi = (config: unknown = {}) => {
const handlers: {
preload?: PreloadApprover;
identity?: IdentityApprover;
capabilities?: CapabilitiesApprover;
} = {};
const widgetLifecycle: WidgetLifecycleApiAdapter = {
registerPreloadApprover: vi.fn((approver) => {
2026-02-25 09:36:58 +00:00
handlers.preload = approver;
}),
registerIdentityApprover: vi.fn((approver) => {
2026-02-25 09:36:58 +00:00
handlers.identity = approver;
}),
registerCapabilitiesApprover: vi.fn((approver) => {
2026-02-25 09:36:58 +00:00
handlers.capabilities = approver;
}),
2026-02-25 09:36:58 +00:00
};
return {
api: {
config: {
get: () => config,
},
widgetLifecycle,
2026-06-10 17:00:34 +01:00
} as Api,
2026-02-25 09:36:58 +00:00
handlers,
};
};
const widget: WidgetDescriptor = {
id: "widget-id",
2026-03-04 18:02:17 +00:00
templateUrl: "https://example.com/",
2026-02-25 09:36:58 +00:00
creatorUserId: "@user-id",
2026-06-10 17:00:34 +01:00
type: "com.example.custom",
origin: "example.com",
2026-02-25 09:36:58 +00:00
};
describe("WidgetLifecycleModule", () => {
it("does nothing when no config is present", async () => {
const { api } = createApi(null);
const module = new WidgetLifecycleModule(api);
await module.load();
expect(api.widgetLifecycle.registerPreloadApprover).not.toHaveBeenCalled();
expect(api.widgetLifecycle.registerIdentityApprover).not.toHaveBeenCalled();
expect(api.widgetLifecycle.registerCapabilitiesApprover).not.toHaveBeenCalled();
});
2026-02-25 09:36:58 +00:00
it("approves preload when configured", async () => {
const { api, handlers } = createApi({
widget_permissions: {
"https://example.com/": { preload_approved: true },
},
});
const module = new WidgetLifecycleModule(api);
await module.load();
expect(await handlers.preload?.(widget)).toBe(true);
});
it("approves identity when configured", async () => {
const { api, handlers } = createApi({
widget_permissions: {
"https://example.com/": { identity_approved: true },
},
});
const module = new WidgetLifecycleModule(api);
await module.load();
expect(await handlers.identity?.(widget)).toBe(true);
});
it("approves configured capabilities", async () => {
const { api, handlers } = createApi({
widget_permissions: {
"https://example.com/": {
capabilities_approved: ["org.matrix.msc2931.navigate"],
},
},
});
const module = new WidgetLifecycleModule(api);
await module.load();
const approved = await handlers.capabilities?.(
widget,
new Set(["org.matrix.msc2931.navigate", "org.matrix.msc2762.timeline:*"]),
);
expect(approved).toEqual(new Set(["org.matrix.msc2931.navigate"]));
});
it("returns no approvals when not configured", async () => {
const { api, handlers } = createApi({});
const module = new WidgetLifecycleModule(api);
await module.load();
expect(await handlers.preload?.(widget)).toBe(false);
expect(await handlers.identity?.(widget)).toBe(false);
expect(await handlers.capabilities?.(widget, new Set(["org.matrix.msc2931.navigate"]))).toBeUndefined();
});
it("returns no approvals when config is missing", async () => {
const { api, handlers } = createApi(undefined);
const module = new WidgetLifecycleModule(api);
await module.load();
expect(await handlers.preload?.(widget)).toBe(false);
expect(await handlers.identity?.(widget)).toBe(false);
expect(await handlers.capabilities?.(widget, new Set(["org.matrix.msc2931.navigate"]))).toBeUndefined();
});
it("fails closed on invalid config", async () => {
const { api, handlers } = createApi({
widget_permissions: {
"https://example.com/": {
preload_approved: null,
},
},
});
const module = new WidgetLifecycleModule(api);
await module.load();
expect(await handlers.preload?.(widget)).toBe(false);
expect(await handlers.identity?.(widget)).toBe(false);
expect(await handlers.capabilities?.(widget, new Set(["org.matrix.msc2931.navigate"]))).toBeUndefined();
});
});