import { renderTelegramText, TELEGRAM_TEMPLATES, TelegramTemplateCode, } from './telegram-texts'; const ORIGIN = 'https://app.example.org'; describe('TELEGRAM_TEMPLATES', () => { it('has the exact texts of the bot replies', () => { expect(TELEGRAM_TEMPLATES).toEqual({ LINKED: 'Verbunden mit ApiCore. Hier kommen deine Erinnerungen. /stop beendet das.', LINK_INVALID: 'Der Link ist ungültig oder abgelaufen. Bitte in ApiCore neu verbinden.', STOPPED: 'Abgemeldet. Du bekommst keine Nachrichten mehr.', HELP: 'Dieser Bot schickt Erinnerungen aus ApiCore. Verbinden geht nur in ApiCore unter Profil > Benachrichtigungen. /stop beendet.', } satisfies Record); }); }); describe('renderTelegramText', () => { it('sends the message, a blank line and the app link', () => { const text = renderTelegramText( { message: 'Heute fällig: Futter bestellen', link: '/tasks' }, true, ORIGIN, ); expect(text).toBe( 'Heute fällig: Futter bestellen\n\nhttps://app.example.org/tasks', ); }); it('falls back to /dashboard without a link', () => { const text = renderTelegramText({ message: 'm', link: null }, true, ORIGIN); expect(text).toBe('m\n\nhttps://app.example.org/dashboard'); }); it('without details only says there is a new message, plus the link', () => { const text = renderTelegramText( { message: 'Heute fällig: Schwarmzelle Völker', link: '/tasks' }, false, ORIGIN, ); expect(text).toBe( 'Neue Meldung in ApiCore.\n\nhttps://app.example.org/tasks', ); expect(text).not.toContain('Schwarm'); }); it('tolerates a trailing slash of the origin', () => { const text = renderTelegramText( { message: 'm', link: '/tasks' }, true, `${ORIGIN}/`, ); expect(text.endsWith('https://app.example.org/tasks')).toBe(true); }); it('cuts a long message to at most 600 characters and keeps the link whole', () => { const text = renderTelegramText( { message: 'ä'.repeat(2000), link: '/tasks' }, true, ORIGIN, ); expect([...text].length).toBeLessThanOrEqual(600); expect(text.endsWith('\n\nhttps://app.example.org/tasks')).toBe(true); expect(text).toContain('…\n\n'); }); it('counts code points, not UTF-16 units', () => { const text = renderTelegramText( { message: '🐝'.repeat(1000), link: '/tasks' }, true, ORIGIN, ); expect([...text].length).toBeLessThanOrEqual(600); expect(text).not.toMatch(/[\ud800-\udbff](?![\udc00-\udfff])/); }); it('removes control characters and invisible characters from the message', () => { const text = renderTelegramText( { message: 'a\u0007b‮c​d\r\ne', link: '/tasks' }, true, ORIGIN, ); expect(text).toBe('abcd\ne\n\nhttps://app.example.org/tasks'); }); it('without an origin sends the text alone, no link', () => { expect( renderTelegramText({ message: 'Hallo', link: '/tasks' }, true, null), ).toBe('Hallo'); expect( renderTelegramText({ message: 'Hallo', link: '/tasks' }, false, null), ).toBe('Neue Meldung in ApiCore.'); }); });