fix(tess): route bare Discord approvals #733
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest';
|
|||||||
import { InMemoryDurableSessionStore } from '@mosaicstack/agent';
|
import { InMemoryDurableSessionStore } from '@mosaicstack/agent';
|
||||||
import {
|
import {
|
||||||
createDiscordIngressEnvelope,
|
createDiscordIngressEnvelope,
|
||||||
|
DiscordPlugin,
|
||||||
type DiscordIngressPayload,
|
type DiscordIngressPayload,
|
||||||
} from '@mosaicstack/discord-plugin';
|
} from '@mosaicstack/discord-plugin';
|
||||||
import { InteractionController } from '../../agent/interaction.controller.js';
|
import { InteractionController } from '../../agent/interaction.controller.js';
|
||||||
@@ -30,7 +31,7 @@ function payload(content: string, messageId: string, correlationId: string): Dis
|
|||||||
guildId: 'guild-1',
|
guildId: 'guild-1',
|
||||||
channelId: 'channel-1',
|
channelId: 'channel-1',
|
||||||
userId: 'discord-admin-1',
|
userId: 'discord-admin-1',
|
||||||
conversationId: 'conversation-1',
|
conversationId: 'Nova:discord:channel-1',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +90,7 @@ describe('Tess Discord/CLI durable-session integration', () => {
|
|||||||
const controller = new InteractionController(enrollmentRuntime as never, durable);
|
const controller = new InteractionController(enrollmentRuntime as never, durable);
|
||||||
await controller.enroll(
|
await controller.enroll(
|
||||||
'Nova',
|
'Nova',
|
||||||
'conversation-1',
|
'Nova:discord:channel-1',
|
||||||
{ providerId: 'fleet', runtimeSessionId: 'runtime-1' },
|
{ providerId: 'fleet', runtimeSessionId: 'runtime-1' },
|
||||||
{ id: 'mosaic-admin-1', tenantId: 'tenant-1' },
|
{ id: 'mosaic-admin-1', tenantId: 'tenant-1' },
|
||||||
'cli-enrollment-correlation',
|
'cli-enrollment-correlation',
|
||||||
@@ -122,14 +123,46 @@ describe('Tess Discord/CLI durable-session integration', () => {
|
|||||||
durable,
|
durable,
|
||||||
);
|
);
|
||||||
const client = { data: { discordService: true }, emit: vi.fn() };
|
const client = { data: { discordService: true }, emit: vi.fn() };
|
||||||
|
const plugin = new DiscordPlugin({
|
||||||
|
token: 'unused',
|
||||||
|
gatewayUrl: 'http://unused',
|
||||||
|
serviceToken: SERVICE_TOKEN,
|
||||||
|
allowedGuildIds: ['guild-1'],
|
||||||
|
allowedChannelIds: ['channel-1'],
|
||||||
|
allowedUserIds: ['discord-admin-1'],
|
||||||
|
interactionBindings: [
|
||||||
|
{
|
||||||
|
instanceId: 'Nova',
|
||||||
|
guildId: 'guild-1',
|
||||||
|
channelId: 'channel-1',
|
||||||
|
pairedUsers: {
|
||||||
|
'discord-admin-1': { role: 'admin', mosaicUserId: 'mosaic-admin-1' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const pluginInternals = plugin as unknown as {
|
||||||
|
client: { user: { id: string } };
|
||||||
|
socket: { connected: boolean; emit: ReturnType<typeof vi.fn> };
|
||||||
|
handleDiscordMessage(message: unknown): void;
|
||||||
|
};
|
||||||
|
const pluginSocket = { connected: true, emit: vi.fn() };
|
||||||
|
pluginInternals.client = { user: { id: 'bot-1' } };
|
||||||
|
pluginInternals.socket = pluginSocket;
|
||||||
|
pluginInternals.handleDiscordMessage({
|
||||||
|
id: 'approve-1',
|
||||||
|
guildId: 'guild-1',
|
||||||
|
channelId: 'channel-1',
|
||||||
|
author: { id: 'discord-admin-1', bot: false },
|
||||||
|
mentions: { has: () => true },
|
||||||
|
content: '<@bot-1> /approve',
|
||||||
|
channel: { parentId: null },
|
||||||
|
attachments: new Map(),
|
||||||
|
});
|
||||||
|
|
||||||
await gateway.handleDiscordApproval(
|
expect(pluginSocket.emit).toHaveBeenCalledWith('discord:approve', expect.any(Object));
|
||||||
client as never,
|
const approvalEnvelope = pluginSocket.emit.mock.calls[0]?.[1];
|
||||||
createDiscordIngressEnvelope(
|
await gateway.handleDiscordApproval(client as never, approvalEnvelope);
|
||||||
payload('/approve', 'approve-1', 'discord-approve-correlation'),
|
|
||||||
SERVICE_TOKEN,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const approval = client.emit.mock.calls.find(
|
const approval = client.emit.mock.calls.find(
|
||||||
([event]) => event === 'discord:approval',
|
([event]) => event === 'discord:approval',
|
||||||
)?.[1] as {
|
)?.[1] as {
|
||||||
|
|||||||
@@ -382,7 +382,7 @@ export class DiscordPlugin {
|
|||||||
this.config.serviceToken,
|
this.config.serviceToken,
|
||||||
);
|
);
|
||||||
this.socket.emit(
|
this.socket.emit(
|
||||||
content.startsWith('/approve ')
|
/^\/approve$/i.test(content)
|
||||||
? 'discord:approve'
|
? 'discord:approve'
|
||||||
: content.startsWith('/stop ')
|
: content.startsWith('/stop ')
|
||||||
? 'discord:stop'
|
? 'discord:stop'
|
||||||
|
|||||||
Reference in New Issue
Block a user