import { describe, it, expect } from 'vitest'; import { createGentleNotificationEngine, FORBIDDEN_PHRASES } from './client.js'; describe('createGentleNotificationEngine', () => { it('should return default config', () => { const engine = createGentleNotificationEngine(); const config = engine.getDefaultConfig(); expect(config.maxPerHour).toBe(3); expect(config.tone).toBe('encouraging'); expect(config.adaptiveFrequency).toBe(true); expect(config.dismissCount).toBe(0); expect(config.suppressThreshold).toBe(5); }); it('should return a message for known type', () => { const engine = createGentleNotificationEngine(); const msg = engine.getMessage('reminder'); expect(msg.title.length).toBeGreaterThan(0); expect(msg.body.length).toBeGreaterThan(0); expect(['encouraging', 'neutral', 'minimal']).toContain(msg.tone); }); it('should return fallback for unknown type', () => { const engine = createGentleNotificationEngine(); const msg = engine.getMessage('nonexistent_type'); expect(msg.title).toBe('Hey'); expect(msg.body.length).toBeGreaterThan(0); }); it('should suppress when dismiss threshold reached', () => { const engine = createGentleNotificationEngine(); const config = { ...engine.getDefaultConfig(), dismissCount: 5 }; expect(engine.shouldSuppress(config)).toBe(true); }); it('should not suppress when below threshold', () => { const engine = createGentleNotificationEngine(); const config = { ...engine.getDefaultConfig(), dismissCount: 2 }; expect(engine.shouldSuppress(config)).toBe(false); }); it('should record dismissal and reduce frequency', () => { const engine = createGentleNotificationEngine(); let config = engine.getDefaultConfig(); expect(config.dismissCount).toBe(0); config = engine.recordDismissal(config); expect(config.dismissCount).toBe(1); // Record enough to trigger suppression for (let i = 0; i < 4; i++) { config = engine.recordDismissal(config); } expect(config.dismissCount).toBe(5); expect(config.maxPerHour).toBeLessThan(3); }); it('should reset dismissals', () => { const engine = createGentleNotificationEngine(); let config = engine.getDefaultConfig(); config = engine.recordDismissal(config); config = engine.recordDismissal(config); expect(config.dismissCount).toBe(2); config = engine.resetDismissals(config); expect(config.dismissCount).toBe(0); }); it('should allow registering custom messages', () => { const engine = createGentleNotificationEngine(); engine.registerMessages('fasting', [ { title: 'Fasting Reminder', body: 'Your body is doing great things!', tone: 'encouraging' }, ]); const msg = engine.getMessage('fasting'); expect(msg.title).toBe('Fasting Reminder'); }); it('should export FORBIDDEN_PHRASES', () => { expect(FORBIDDEN_PHRASES).toContain("You haven't"); expect(FORBIDDEN_PHRASES).toContain('You failed'); expect(FORBIDDEN_PHRASES.length).toBeGreaterThanOrEqual(8); }); it('should detect forbidden phrases', () => { const engine = createGentleNotificationEngine(); expect(engine.containsForbiddenPhrase("You haven't done this yet")).toBe(true); expect(engine.containsForbiddenPhrase('Great job today!')).toBe(false); expect(engine.containsForbiddenPhrase('you failed the test')).toBe(true); }); it('should respect custom initial config', () => { const engine = createGentleNotificationEngine({ maxPerHour: 10, tone: 'minimal' }); const config = engine.getDefaultConfig(); expect(config.maxPerHour).toBe(10); expect(config.tone).toBe('minimal'); }); });