import { describe, expect, it } from 'vitest'; import { matchReactionPrompt } from './reactions.js'; import type { AutomationReactionConfig } from '../config/schema.js'; function makeRule(overrides: Partial & Pick): AutomationReactionConfig { return { name: overrides.name, enabled: overrides.enabled ?? true, on: overrides.on ?? ['gmail'], filter: overrides.filter, run: overrides.run, }; } describe('matchReactionPrompt', () => { it('matches channel + contains filter and renders text template', () => { const rules: AutomationReactionConfig[] = [ makeRule({ name: 'boss-email', on: ['gmail'], filter: { contains: 'boss@company.com' }, run: 'Summarize this email and propose next actions:\n\n{{text}}', }), ]; const result = matchReactionPrompt(rules, { channel: 'gmail', senderId: 'watcher', text: 'New email from boss@company.com: Q1 plan', metadata: { from: 'boss@company.com' }, }); expect(result).toEqual({ name: 'boss-email', prompt: 'Summarize this email and propose next actions:\n\nNew email from boss@company.com: Q1 plan', }); }); it('matches metadata paths and supports metadata templating', () => { const rules: AutomationReactionConfig[] = [ makeRule({ name: 'github-push', on: ['webhook'], filter: { metadata: { 'webhookName': 'github', 'body.repository.full_name': 'acme/app' } }, run: 'New push on {{metadata.body.repository.full_name}} from {{metadata.body.pusher.name}}', }), ]; const result = matchReactionPrompt(rules, { channel: 'webhook', senderId: 'github', text: 'raw webhook payload', metadata: { webhookName: 'github', body: { repository: { full_name: 'acme/app' }, pusher: { name: 'will' }, }, }, }); expect(result).toEqual({ name: 'github-push', prompt: 'New push on acme/app from will', }); }); it('returns null on no match or invalid regex', () => { const rules: AutomationReactionConfig[] = [ makeRule({ name: 'bad', on: ['gmail'], filter: { regex: '[' }, run: 'x', }), makeRule({ name: 'different-channel', on: ['webhook'], run: 'x', }), ]; const result = matchReactionPrompt(rules, { channel: 'gmail', senderId: 'watcher', text: 'hello', metadata: {}, }); expect(result).toBeNull(); }); });