Files
cinny/src/app/utils/bridge.test.ts
T

87 lines
3.2 KiB
TypeScript
Raw Normal View History

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { MatrixEvent, Room } from 'matrix-js-sdk';
import {
describeRoomBridge,
getBridgedUserNetwork,
getRoomBridges,
parseBridgeEvent,
} from './bridge';
const bridgeEvent = (type: string, stateKey: string, content: Record<string, unknown>) =>
new MatrixEvent({ type, state_key: stateKey, content, room_id: '!r:x', sender: '@discordbot:x' });
// Shape of what mautrix-discord 0.7.7 sends for a guild channel.
const discordContent = {
bridgebot: '@discordbot:matrix.lotusguild.org',
protocol: { id: 'discordgo', displayname: 'Discord' },
channel: {
id: '1565159372122882070',
displayname: '#general',
external_url: 'https://discord.com/channels/1/1565159372122882070',
},
network: { id: '1', displayname: 'Lotus Guild' },
};
const roomWithState = (events: MatrixEvent[]): Room =>
({
getLiveTimeline: () => ({
getState: () => ({
getStateEvents: (type: string) => events.filter((e) => e.getType() === type),
}),
}),
}) as unknown as Room;
test('Discord ghosts are recognised; the bridge bot and lookalikes are not', () => {
assert.equal(
getBridgedUserNetwork('@discord_123456789012345678:matrix.lotusguild.org'),
'discord',
);
assert.equal(getBridgedUserNetwork('@discordbot:matrix.lotusguild.org'), undefined);
assert.equal(getBridgedUserNetwork('@discord_fan:matrix.lotusguild.org'), undefined);
assert.equal(getBridgedUserNetwork('@discord-relay:matrix.lotusguild.org'), undefined);
assert.equal(getBridgedUserNetwork('@jared:matrix.lotusguild.org'), undefined);
});
test('parseBridgeEvent reads a mautrix-discord m.bridge event', () => {
assert.deepEqual(parseBridgeEvent(bridgeEvent('m.bridge', 'k', discordContent)), {
network: 'discord',
channelName: '#general',
networkName: 'Lotus Guild',
externalUrl: 'https://discord.com/channels/1/1565159372122882070',
});
});
test('parseBridgeEvent ignores unknown protocols and empty content', () => {
assert.equal(
parseBridgeEvent(bridgeEvent('m.bridge', 'k', { protocol: { id: 'telegram' } })),
undefined,
);
assert.equal(parseBridgeEvent(bridgeEvent('m.bridge', 'k', {})), undefined);
});
test('only http(s) channel links are kept', () => {
const content = {
...discordContent,
channel: { displayname: '#x', external_url: ['javascript', 'alert(1)'].join(':') },
};
assert.equal(parseBridgeEvent(bridgeEvent('m.bridge', 'k', content))?.externalUrl, undefined);
});
test('getRoomBridges merges m.bridge with its unstable copy, one entry per channel', () => {
const room = roomWithState([
bridgeEvent('m.bridge', 'fi.mau.discord://discord/1/2', discordContent),
bridgeEvent('uk.half-shot.bridge', 'fi.mau.discord://discord/1/2', discordContent),
]);
assert.equal(getRoomBridges(room).length, 1);
assert.equal(getRoomBridges(roomWithState([])).length, 0);
});
test('describeRoomBridge degrades gracefully without names', () => {
assert.equal(
describeRoomBridge({ network: 'discord', channelName: '#general', networkName: 'Lotus Guild' }),
'Bridged to #general in Lotus Guild on Discord',
);
assert.equal(describeRoomBridge({ network: 'discord' }), 'Bridged to Discord');
});