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)
126 lines
3.7 KiB
TypeScript
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."]);
|
|
});
|