/** * Regression tests for the Telegram preview domain * Covers native rich draft previews, safe-prefix selection, and finalization behavior */ import assert from "node:assert/strict"; import test from "node:test"; import { allocateTelegramDraftId, buildTelegramPreviewFinalText, clearTelegramPreview, createTelegramAssistantPreviewRuntime, createTelegramNativeMarkdownPreviewFinalizer, createTelegramPreviewControllerRuntime, createTelegramPreviewRuntimeState, finalizeTelegramPreview, flushTelegramPreview, getSafeTelegramRichMarkdownDraftPrefix, shouldUseTelegramDraftPreview, type TelegramPreviewRuntimeState, } from "../lib/preview.ts"; import { createTelegramThreadTarget } from "../lib/target.ts"; function createPreviewRuntimeHarness(state?: TelegramPreviewRuntimeState) { let previewState = state; let draftSupport: "unknown" | "supported" = "unknown"; let nextDraftId = 10; const events: string[] = []; return { events, getState: () => previewState, getDraftSupport: () => draftSupport, deps: { getState: () => previewState, setState: (nextState: TelegramPreviewRuntimeState | undefined) => { previewState = nextState; }, maxMessageLength: 100, getDraftSupport: () => draftSupport, setDraftSupport: (support: "unknown" | "supported") => { draftSupport = support; }, allocateDraftId: () => nextDraftId++, sendDraft: async ( chatId: number, draftId: number, text?: string, _options?: { message_thread_id?: number }, ) => { events.push(`draft:${chatId}:${draftId}:${text}`); }, canSend: undefined as undefined | (() => boolean), recordRuntimeEvent: ( category: string, _error: unknown, details?: Record, ) => { events.push(`${category}:${details?.phase}`); }, }, }; } test("Preview helpers create draft-only state and allocate draft ids", () => { assert.deepEqual(createTelegramPreviewRuntimeState(), { mode: "draft", pendingText: "", lastSentText: "", }); assert.equal(allocateTelegramDraftId(0, 2), 1); assert.equal(allocateTelegramDraftId(1, 2), 2); assert.equal(allocateTelegramDraftId(2, 2), 1); }); test("Preview final text prefers pending text then last sent draft text", () => { assert.equal( buildTelegramPreviewFinalText({ mode: "draft", pendingText: " final ", lastSentText: "old", }), "final", ); assert.equal( buildTelegramPreviewFinalText({ mode: "draft", pendingText: " ", lastSentText: " old ", }), "old", ); assert.equal( buildTelegramPreviewFinalText({ mode: "draft", pendingText: " ", lastSentText: " ", }), undefined, ); }); test("Preview helpers always use native rich drafts", () => { assert.equal( shouldUseTelegramDraftPreview({ draftSupport: "unknown" }), true, ); assert.equal( shouldUseTelegramDraftPreview({ draftSupport: "supported", snapshot: { text: "ok" }, }), true, ); }); test("Native Markdown draft prefix keeps only structurally closed Markdown", () => { assert.equal( getSafeTelegramRichMarkdownDraftPrefix("**Bold** and *italic*", 100), "**Bold** and *italic*", ); assert.equal( getSafeTelegramRichMarkdownDraftPrefix("**Bold** and *ita", 100), "**Bold** and", ); assert.equal( getSafeTelegramRichMarkdownDraftPrefix("**Heading still streaming", 100), undefined, ); assert.equal( getSafeTelegramRichMarkdownDraftPrefix("Before\n\n```ts\nconst x = 1", 100), "Before", ); assert.equal( getSafeTelegramRichMarkdownDraftPrefix( "Before\n\n```ts\nconst x = 1\n```", 100, ), "Before\n\n```ts\nconst x = 1\n```", ); assert.equal( getSafeTelegramRichMarkdownDraftPrefix( "[OpenAI](https://openai.com) and [half", 100, ), "[OpenAI](https://openai.com) and", ); assert.equal( getSafeTelegramRichMarkdownDraftPrefix("Block math:\n\n$$\nx^2", 100), "Block math:", ); assert.equal( getSafeTelegramRichMarkdownDraftPrefix( "