import { afterEach, describe, expect, it, vi } from 'vitest'; import { insideTelegram, telegramClosingConfirmation, telegramLaunch, telegramOpenExternalLink, telegramRequestFullscreen, } from './telegram'; function stubWebApp(initData: string, startParam?: string) { vi.stubGlobal('window', { Telegram: { WebApp: { initData, initDataUnsafe: startParam ? { start_param: startParam } : {}, themeParams: { bg_color: '#101418' }, ready: () => {}, expand: () => {}, }, }, }); } describe('telegram launch detection', () => { afterEach(() => vi.unstubAllGlobals()); it('is not inside Telegram without a window', () => { expect(insideTelegram()).toBe(false); }); it('is inside Telegram only with non-empty initData', () => { stubWebApp(''); expect(insideTelegram()).toBe(false); stubWebApp('query_id=abc'); expect(insideTelegram()).toBe(true); }); it('telegramLaunch returns initData, start param and theme', () => { stubWebApp('query_id=abc', 'g123'); const launch = telegramLaunch(); expect(launch.initData).toBe('query_id=abc'); expect(launch.startParam).toBe('g123'); expect(launch.theme?.bg_color).toBe('#101418'); }); }); // stubClient stands up a fake WebApp on the given platform with spies for the mobile-gated // chrome toggles, so the platform gate can be asserted without a real Telegram client. function stubClient(platform?: string) { const enable = vi.fn(); const disable = vi.fn(); const requestFullscreen = vi.fn(); vi.stubGlobal('window', { Telegram: { WebApp: { platform, enableClosingConfirmation: enable, disableClosingConfirmation: disable, requestFullscreen }, }, }); return { enable, disable, requestFullscreen }; } const mobilePlatforms = ['ios', 'android', 'android_x']; const desktopPlatforms = ['tdesktop', 'macos', 'web', undefined]; describe('telegramClosingConfirmation', () => { afterEach(() => vi.unstubAllGlobals()); it('arms the close guard on mobile clients', () => { for (const p of mobilePlatforms) { const { enable } = stubClient(p); telegramClosingConfirmation(true); expect(enable, `platform=${p}`).toHaveBeenCalledOnce(); } }); it('skips the close guard on desktop clients (the dialog there is just noise)', () => { for (const p of desktopPlatforms) { const { enable } = stubClient(p); telegramClosingConfirmation(true); expect(enable, `platform=${p}`).not.toHaveBeenCalled(); } }); it('always lifts the guard on leave, regardless of platform', () => { const { disable } = stubClient('tdesktop'); telegramClosingConfirmation(false); expect(disable).toHaveBeenCalledOnce(); }); }); describe('telegramRequestFullscreen', () => { afterEach(() => vi.unstubAllGlobals()); it('goes immersive fullscreen on mobile clients', () => { for (const p of mobilePlatforms) { const { requestFullscreen } = stubClient(p); telegramRequestFullscreen(); expect(requestFullscreen, `platform=${p}`).toHaveBeenCalledOnce(); } }); it('leaves desktop clients as a standard window (the bot full-size setting fills it)', () => { for (const p of desktopPlatforms) { const { requestFullscreen } = stubClient(p); telegramRequestFullscreen(); expect(requestFullscreen, `platform=${p}`).not.toHaveBeenCalled(); } }); }); describe('telegramOpenExternalLink', () => { afterEach(() => vi.unstubAllGlobals()); it('routes an external URL through the SDK openLink inside Telegram', () => { const openLink = vi.fn(); vi.stubGlobal('window', { Telegram: { WebApp: { openLink } } }); expect(telegramOpenExternalLink('https://gramota.ru/poisk?query=кот')).toBe(true); expect(openLink).toHaveBeenCalledWith('https://gramota.ru/poisk?query=кот'); }); it('returns false without the SDK so the caller falls back to the anchor', () => { expect(telegramOpenExternalLink('https://x.io')).toBe(false); }); });