import { test } from 'node:test'; import assert from 'node:assert/strict'; import type { MatrixEvent } from 'matrix-js-sdk'; import { widgetsFromStateEvents } from './useRoomWidgets'; const APP = 'https://chat.lotusguild.org'; // Minimal fake MatrixEvent, just enough of the surface widgetsFromStateEvents reads. const fakeEvent = (stateKey: string, sender: string, content: Record) => ({ getStateKey: () => stateKey, getSender: () => sender, getContent: () => content, }) as unknown as MatrixEvent; test('returns a Widget for a valid im.vector.modular.widgets state event', () => { // Regression test for matrix-widget-api 1.17.0's broken isValidUrl, which // compares URL.protocol ("https:") to "https" and rejects every URL, // making WidgetParser.parseWidgetsFromRoomState always return []. const events = new Map([ [ 'w1', fakeEvent('w1', '@a:example.org', { id: 'w1', type: 'custom', url: 'https://example.com/widget', name: 'My Widget', creatorUserId: '@a:example.org', }), ], ]); const widgets = widgetsFromStateEvents(events, APP); assert.equal(widgets.length, 1); assert.equal(widgets[0].id, 'w1'); assert.equal(widgets[0].templateUrl, 'https://example.com/widget'); assert.equal(widgets[0].creatorUserId, '@a:example.org'); assert.equal(widgets[0].name, 'My Widget'); }); test('skips removed widgets (empty content)', () => { const events = new Map([['w1', fakeEvent('w1', '@a:example.org', {})]]); assert.deepEqual(widgetsFromStateEvents(events, APP), []); }); test('skips non-https and same-origin urls', () => { const events = new Map([ [ 'w1', fakeEvent('w1', '@a:example.org', { id: 'w1', type: 'custom', url: 'http://example.com/widget', creatorUserId: '@a:example.org', }), ], [ 'w2', fakeEvent('w2', '@a:example.org', { id: 'w2', type: 'custom', url: `${APP}/evil`, creatorUserId: '@a:example.org', }), ], ]); assert.deepEqual(widgetsFromStateEvents(events, APP), []); }); test('undefined state map yields no widgets', () => { assert.deepEqual(widgetsFromStateEvents(undefined, APP), []); });