import { afterEach, describe, expect, it, vi } from 'vitest'; import { InMemoryDurableSessionStore } from '@mosaicstack/agent'; import { createDiscordIngressEnvelope, type DiscordIngressPayload, } from '@mosaicstack/discord-plugin'; import { InteractionController } from '../../agent/interaction.controller.js'; import { RuntimeProviderService } from '../../agent/runtime-provider-registry.service.js'; import { TessDurableSessionService } from '../../agent/tess-durable-session.service.js'; import { ChatGateway } from '../../chat/chat.gateway.js'; import { CommandAuthorizationService } from '../../commands/command-authorization.service.js'; const SERVICE_TOKEN = 'test-discord-service-token'; const envKeys = [ 'DISCORD_SERVICE_TOKEN', 'DISCORD_SERVICE_TENANT_ID', 'DISCORD_INTERACTION_BINDINGS', 'DISCORD_ALLOWED_GUILD_IDS', 'DISCORD_ALLOWED_CHANNEL_IDS', 'DISCORD_ALLOWED_USER_IDS', 'MOSAIC_AGENT_NAME', ] as const; const priorEnv = new Map(); function payload(content: string, messageId: string, correlationId: string): DiscordIngressPayload { return { content, messageId, correlationId, guildId: 'guild-1', channelId: 'channel-1', userId: 'discord-admin-1', conversationId: 'conversation-1', }; } function authorization(): CommandAuthorizationService { const entries = new Map(); return new CommandAuthorizationService( { select: () => ({ from: () => ({ where: () => ({ limit: async () => [{ role: 'admin' }] }) }), }), } as never, { get: async (key: string) => entries.get(key) ?? null, set: async (key: string, value: string) => entries.set(key, value), del: async (key: string) => Number(entries.delete(key)), }, ); } describe('Tess Discord/CLI durable-session integration', () => { afterEach(() => { for (const key of envKeys) { const value = priorEnv.get(key); if (value === undefined) delete process.env[key]; else process.env[key] = value; } priorEnv.clear(); }); it('enrolls through the CLI surface then resolves the same durable session from Discord', async () => { for (const key of envKeys) priorEnv.set(key, process.env[key]); process.env['MOSAIC_AGENT_NAME'] = 'Nova'; process.env['DISCORD_SERVICE_TOKEN'] = SERVICE_TOKEN; process.env['DISCORD_SERVICE_TENANT_ID'] = 'tenant-1'; process.env['DISCORD_ALLOWED_GUILD_IDS'] = 'guild-1'; process.env['DISCORD_ALLOWED_CHANNEL_IDS'] = 'channel-1'; process.env['DISCORD_ALLOWED_USER_IDS'] = 'discord-admin-1'; process.env['DISCORD_INTERACTION_BINDINGS'] = JSON.stringify([ { instanceId: 'Nova', guildId: 'guild-1', channelId: 'channel-1', pairedUsers: { 'discord-admin-1': { role: 'admin', mosaicUserId: 'mosaic-admin-1' }, }, }, ]); const durable = new TessDurableSessionService( new InMemoryDurableSessionStore() as never, {} as never, ); const enrollmentRuntime = { listSessions: vi.fn().mockResolvedValue([{ id: 'runtime-1' }]), }; const controller = new InteractionController(enrollmentRuntime as never, durable); await controller.enroll( 'Nova', 'conversation-1', { providerId: 'fleet', runtimeSessionId: 'runtime-1' }, { id: 'mosaic-admin-1', tenantId: 'tenant-1' }, 'cli-enrollment-correlation', ); const authz = authorization(); const terminated = vi.fn().mockResolvedValue(undefined); const runtime = new RuntimeProviderService( { require: () => ({ capabilities: async () => ({ supported: ['session.terminate'] }), terminate: terminated, }), } as never, { record: async () => undefined } as never, { consume: (approvalId, action) => authz.consumeRuntimeTerminationApproval(approvalId, action), }, ); const gateway = new ChatGateway( {} as never, {} as never, {} as never, {} as never, {} as never, {} as never, authz, runtime, durable, ); const client = { data: { discordService: true }, emit: vi.fn() }; await gateway.handleDiscordApproval( client as never, createDiscordIngressEnvelope( payload('/approve', 'approve-1', 'discord-approve-correlation'), SERVICE_TOKEN, ), ); const approval = client.emit.mock.calls.find( ([event]) => event === 'discord:approval', )?.[1] as { approvalId: string; success: boolean; }; expect(approval.success).toBe(true); await gateway.handleDiscordStop( client as never, createDiscordIngressEnvelope( payload(`/stop ${approval.approvalId}`, 'stop-1', 'discord-stop-correlation'), SERVICE_TOKEN, ), ); expect(terminated).toHaveBeenCalledWith( 'runtime-1', approval.approvalId, expect.objectContaining({ actorId: 'mosaic-admin-1' }), ); expect(client.emit).toHaveBeenCalledWith('discord:stop', { correlationId: 'discord-stop-correlation', success: true, }); }); });