Files
oh-my-pi-telegram/tests/outbound-buttons.test.ts
Evandro Fonseca Junior d1d04001d0
Release / release (push) Failing after 5s
Validate / validate (push) Failing after 5m21s
chore: fork @llblab/[email protected] as @evandrodevbr/oh-my-pi-telegram
Fork of upstream llblab/[email protected].0 (SHA afe09c5) repackaged as a
drop-in extension for can1357/oh-my-pi (omp >= 16.5.2).

Changes vs upstream:
- Rename package: @llblab/pi-telegram -> @evandrodevbr/oh-my-pi-telegram
- Bump version: 0.22.0 -> 0.22.0-evandro.1
- Update repository/homepage/bugs URLs to evandrodevbr
- Add omp field in package.json (displayName + compatibleWith)
- README: prepend 'Oh My Pi (omp) Compatibility' section with install
  commands, verified-components table, upstream lineage, and rationale
- CHANGELOG: add '0.22.0-evandro.1' entry under Unreleased
- docs/: rename @llblab/pi-telegram imports to @evandrodevbr/oh-my-pi-telegram
- tests/public-api.test.ts: rename package import paths

Gates re-run on the fork:
- npm run typecheck  -> tsc --noEmit (success)
- npm test           -> 1229 pass / 0 fail / 1 platform-only skip
- npm run audit      -> found 0 vulnerabilities
- npm run pack:check -> evandrodevbr-oh-my-pi-telegram-0.22.0-evandro.1.tgz

Verified:
- omp install --link ./pi-telegram -> Linked OK
- omp plugin list -> @evandrodevbr/[email protected].0-evandro.1

Upstream lineage: badlogic/pi-telegram -> llblab/pi-telegram (0.22.0) -> evandrodevbr/oh-my-pi-telegram (this fork)
2026-07-15 14:18:16 -03:00

126 lines
3.7 KiB
TypeScript

/**
* Regression tests for Telegram outbound button helpers
* Exercises assistant-authored button markup extraction, action storage, callback handling, and prompt-turn construction
*/
import assert from "node:assert/strict";
import test from "node:test";
import {
createTelegramButtonActionStore,
createTelegramButtonPromptTurn,
handleTelegramButtonCallbackQuery,
planTelegramButtonReply,
} from "../lib/outbound-buttons.ts";
test("Button reply planner strips telegram_button markup and registers actions", () => {
const actions: unknown[] = [];
const plan = planTelegramButtonReply(
[
"Visible answer.",
"",
'<!-- telegram_button label="Run" -->',
"Run the workflow.",
"-->",
"",
"Tail.",
].join("\n"),
{
registerAction: (action) => {
actions.push(action);
return `btn:${actions.length}`;
},
},
);
assert.equal(plan.markdown, "Visible answer.\n\nTail.");
assert.deepEqual(actions, [{ text: "Run", prompt: "Run the workflow." }]);
assert.deepEqual(plan.replyMarkup, {
inline_keyboard: [[{ text: "Run", callback_data: "btn:1" }]],
});
});
test("Button action store resolves registered actions once and expires old entries", () => {
const store = createTelegramButtonActionStore();
const callbackData = store.register({ text: "Run", prompt: "Do it." });
assert.deepEqual(store.resolve(callbackData), {
text: "Run",
prompt: "Do it.",
});
assert.equal(store.resolve(callbackData), undefined);
assert.equal(store.resolve("other:callback"), undefined);
const expiringStore = createTelegramButtonActionStore({ ttlMs: -1 });
const expiredCallbackData = expiringStore.register({
text: "Expired",
prompt: "Too late.",
});
assert.equal(expiringStore.resolve(expiredCallbackData), undefined);
});
test("Button prompt turn preserves prompt text and queue metadata", () => {
const turn = createTelegramButtonPromptTurn({
chatId: 10,
replyToMessageId: 20,
queueOrder: 30,
action: { text: "Run", prompt: "Run this now." },
target: { chatId: 10, threadId: 40 },
});
assert.equal(turn.kind, "prompt");
assert.equal(turn.chatId, 10);
assert.deepEqual(turn.target, { chatId: 10, threadId: 40 });
assert.equal(turn.replyToMessageId, 20);
assert.equal(turn.queueLane, "priority");
assert.deepEqual(turn.sourceMessageIds, [20]);
assert.deepEqual(turn.content, [
{ type: "text", text: "[telegram] Run this now." },
]);
assert.equal(turn.historyText, "Run this now.");
assert.equal(turn.statusSummary, "Run");
});
test("Button callback handler enqueues owned actions and consumes expired buttons", async () => {
const answered: string[] = [];
const enqueued: unknown[] = [];
const handled = await handleTelegramButtonCallbackQuery(
{
id: "q1",
data: "tgbtn:live",
message: { message_id: 2, chat: { id: 1 } },
},
"ctx",
{
resolveAction: () => ({ text: "Run", prompt: "Run it." }),
answerCallbackQuery: async (_id, text) => {
answered.push(text ?? "");
},
enqueueButtonPrompt: (query, action, ctx) => {
enqueued.push({ query, action, ctx });
},
},
);
assert.equal(handled, true);
assert.deepEqual(answered, ["Queued."]);
assert.equal(enqueued.length, 1);
const expired = await handleTelegramButtonCallbackQuery(
{ id: "q2", data: "tgbtn:expired" },
"ctx",
{
resolveAction: () => undefined,
answerCallbackQuery: async (_id, text) => {
answered.push(text ?? "");
},
enqueueButtonPrompt: () => {
throw new Error("must not enqueue expired buttons");
},
},
);
assert.equal(expired, true);
assert.deepEqual(answered, ["Queued.", "Button action expired."]);
});