test: align envelope timestamps with local tz
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import { resetInboundDedupe } from "../auto-reply/reply/inbound-dedupe.js";
|
import { resetInboundDedupe } from "../auto-reply/reply/inbound-dedupe.js";
|
||||||
import { createTelegramBot } from "./bot.js";
|
import { createTelegramBot } from "./bot.js";
|
||||||
|
|
||||||
@@ -89,6 +89,7 @@ vi.mock("grammy", () => ({
|
|||||||
const sequentializeMiddleware = vi.fn();
|
const sequentializeMiddleware = vi.fn();
|
||||||
const sequentializeSpy = vi.fn(() => sequentializeMiddleware);
|
const sequentializeSpy = vi.fn(() => sequentializeMiddleware);
|
||||||
let _sequentializeKey: ((ctx: unknown) => string) | undefined;
|
let _sequentializeKey: ((ctx: unknown) => string) | undefined;
|
||||||
|
let originalTz: string | undefined;
|
||||||
vi.mock("@grammyjs/runner", () => ({
|
vi.mock("@grammyjs/runner", () => ({
|
||||||
sequentialize: (keyFn: (ctx: unknown) => string) => {
|
sequentialize: (keyFn: (ctx: unknown) => string) => {
|
||||||
_sequentializeKey = keyFn;
|
_sequentializeKey = keyFn;
|
||||||
@@ -120,6 +121,8 @@ const getOnHandler = (event: string) => {
|
|||||||
|
|
||||||
describe("createTelegramBot", () => {
|
describe("createTelegramBot", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
originalTz = process.env.TZ;
|
||||||
|
process.env.TZ = "UTC";
|
||||||
resetInboundDedupe();
|
resetInboundDedupe();
|
||||||
loadConfig.mockReturnValue({
|
loadConfig.mockReturnValue({
|
||||||
channels: {
|
channels: {
|
||||||
@@ -138,6 +141,10 @@ describe("createTelegramBot", () => {
|
|||||||
_sequentializeKey = undefined;
|
_sequentializeKey = undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
process.env.TZ = originalTz;
|
||||||
|
});
|
||||||
|
|
||||||
// groupPolicy tests
|
// groupPolicy tests
|
||||||
|
|
||||||
it("accepts group messages when mentionPatterns match (without @botUsername)", async () => {
|
it("accepts group messages when mentionPatterns match (without @botUsername)", async () => {
|
||||||
@@ -176,7 +183,9 @@ describe("createTelegramBot", () => {
|
|||||||
expect(payload.WasMentioned).toBe(true);
|
expect(payload.WasMentioned).toBe(true);
|
||||||
expect(payload.SenderName).toBe("Ada");
|
expect(payload.SenderName).toBe("Ada");
|
||||||
expect(payload.SenderId).toBe("9");
|
expect(payload.SenderId).toBe("9");
|
||||||
expect(payload.Body).toMatch(/^\[Telegram Test Group id:7 (\+\d+[smhd] )?2025-01-09T00:00Z\]/);
|
expect(payload.Body).toMatch(
|
||||||
|
/^\[Telegram Test Group id:7 (\+\d+[smhd] )?2025-01-09 00:00 [^\]]+\]/,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it("keeps group envelope headers stable (sender identity is separate)", async () => {
|
it("keeps group envelope headers stable (sender identity is separate)", async () => {
|
||||||
onSpy.mockReset();
|
onSpy.mockReset();
|
||||||
@@ -217,7 +226,7 @@ describe("createTelegramBot", () => {
|
|||||||
expect(payload.SenderName).toBe("Ada Lovelace");
|
expect(payload.SenderName).toBe("Ada Lovelace");
|
||||||
expect(payload.SenderId).toBe("99");
|
expect(payload.SenderId).toBe("99");
|
||||||
expect(payload.SenderUsername).toBe("ada");
|
expect(payload.SenderUsername).toBe("ada");
|
||||||
expect(payload.Body).toMatch(/^\[Telegram Ops id:42 (\+\d+[smhd] )?2025-01-09T00:00Z\]/);
|
expect(payload.Body).toMatch(/^\[Telegram Ops id:42 (\+\d+[smhd] )?2025-01-09 00:00 [^\]]+\]/);
|
||||||
});
|
});
|
||||||
it("reacts to mention-gated group messages when ackReaction is enabled", async () => {
|
it("reacts to mention-gated group messages when ackReaction is enabled", async () => {
|
||||||
onSpy.mockReset();
|
onSpy.mockReset();
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ describe("createTelegramBot", () => {
|
|||||||
expect(replySpy).toHaveBeenCalledTimes(1);
|
expect(replySpy).toHaveBeenCalledTimes(1);
|
||||||
const payload = replySpy.mock.calls[0][0];
|
const payload = replySpy.mock.calls[0][0];
|
||||||
expect(payload.Body).toMatch(
|
expect(payload.Body).toMatch(
|
||||||
/^\[Telegram Ada Lovelace \(@ada_bot\) id:1234 (\+\d+[smhd] )?2025-01-09T00:00Z\]/,
|
/^\[Telegram Ada Lovelace \(@ada_bot\) id:1234 (\+\d+[smhd] )?2025-01-09 01:00 [^\]]+\]/,
|
||||||
);
|
);
|
||||||
expect(payload.Body).toContain("hello world");
|
expect(payload.Body).toContain("hello world");
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -451,7 +451,7 @@ describe("createTelegramBot", () => {
|
|||||||
expect(replySpy).toHaveBeenCalledTimes(1);
|
expect(replySpy).toHaveBeenCalledTimes(1);
|
||||||
const payload = replySpy.mock.calls[0][0];
|
const payload = replySpy.mock.calls[0][0];
|
||||||
expect(payload.Body).toMatch(
|
expect(payload.Body).toMatch(
|
||||||
/^\[Telegram Ada Lovelace \(@ada_bot\) id:1234 (\+\d+[smhd] )?2025-01-09T00:00Z\]/,
|
/^\[Telegram Ada Lovelace \(@ada_bot\) id:1234 (\+\d+[smhd] )?2025-01-09 01:00 [^\]]+\]/,
|
||||||
);
|
);
|
||||||
expect(payload.Body).toContain("hello world");
|
expect(payload.Body).toContain("hello world");
|
||||||
} finally {
|
} finally {
|
||||||
@@ -551,86 +551,102 @@ describe("createTelegramBot", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("accepts group messages when mentionPatterns match (without @botUsername)", async () => {
|
it("accepts group messages when mentionPatterns match (without @botUsername)", async () => {
|
||||||
|
const originalTz = process.env.TZ;
|
||||||
|
process.env.TZ = "UTC";
|
||||||
onSpy.mockReset();
|
onSpy.mockReset();
|
||||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
||||||
replySpy.mockReset();
|
replySpy.mockReset();
|
||||||
|
|
||||||
loadConfig.mockReturnValue({
|
try {
|
||||||
identity: { name: "Bert" },
|
loadConfig.mockReturnValue({
|
||||||
messages: { groupChat: { mentionPatterns: ["\\bbert\\b"] } },
|
identity: { name: "Bert" },
|
||||||
channels: {
|
messages: { groupChat: { mentionPatterns: ["\\bbert\\b"] } },
|
||||||
telegram: {
|
channels: {
|
||||||
groupPolicy: "open",
|
telegram: {
|
||||||
groups: { "*": { requireMention: true } },
|
groupPolicy: "open",
|
||||||
|
groups: { "*": { requireMention: true } },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
createTelegramBot({ token: "tok" });
|
createTelegramBot({ token: "tok" });
|
||||||
const handler = getOnHandler("message") as (ctx: Record<string, unknown>) => Promise<void>;
|
const handler = getOnHandler("message") as (ctx: Record<string, unknown>) => Promise<void>;
|
||||||
|
|
||||||
await handler({
|
await handler({
|
||||||
message: {
|
message: {
|
||||||
chat: { id: 7, type: "group", title: "Test Group" },
|
chat: { id: 7, type: "group", title: "Test Group" },
|
||||||
text: "bert: introduce yourself",
|
text: "bert: introduce yourself",
|
||||||
date: 1736380800,
|
date: 1736380800,
|
||||||
message_id: 1,
|
message_id: 1,
|
||||||
from: { id: 9, first_name: "Ada" },
|
from: { id: 9, first_name: "Ada" },
|
||||||
},
|
},
|
||||||
me: { username: "clawdbot_bot" },
|
me: { username: "clawdbot_bot" },
|
||||||
getFile: async () => ({ download: async () => new Uint8Array() }),
|
getFile: async () => ({ download: async () => new Uint8Array() }),
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(replySpy).toHaveBeenCalledTimes(1);
|
expect(replySpy).toHaveBeenCalledTimes(1);
|
||||||
const payload = replySpy.mock.calls[0][0];
|
const payload = replySpy.mock.calls[0][0];
|
||||||
expectInboundContextContract(payload);
|
expectInboundContextContract(payload);
|
||||||
expect(payload.WasMentioned).toBe(true);
|
expect(payload.WasMentioned).toBe(true);
|
||||||
expect(payload.Body).toMatch(/^\[Telegram Test Group id:7 (\+\d+[smhd] )?2025-01-09T00:00Z\]/);
|
expect(payload.Body).toMatch(
|
||||||
expect(payload.SenderName).toBe("Ada");
|
/^\[Telegram Test Group id:7 (\+\d+[smhd] )?2025-01-09 00:00 [^\]]+\]/,
|
||||||
expect(payload.SenderId).toBe("9");
|
);
|
||||||
|
expect(payload.SenderName).toBe("Ada");
|
||||||
|
expect(payload.SenderId).toBe("9");
|
||||||
|
} finally {
|
||||||
|
process.env.TZ = originalTz;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes sender identity in group envelope headers", async () => {
|
it("includes sender identity in group envelope headers", async () => {
|
||||||
|
const originalTz = process.env.TZ;
|
||||||
|
process.env.TZ = "UTC";
|
||||||
onSpy.mockReset();
|
onSpy.mockReset();
|
||||||
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
const replySpy = replyModule.__replySpy as unknown as ReturnType<typeof vi.fn>;
|
||||||
replySpy.mockReset();
|
replySpy.mockReset();
|
||||||
|
|
||||||
loadConfig.mockReturnValue({
|
try {
|
||||||
channels: {
|
loadConfig.mockReturnValue({
|
||||||
telegram: {
|
channels: {
|
||||||
groupPolicy: "open",
|
telegram: {
|
||||||
groups: { "*": { requireMention: false } },
|
groupPolicy: "open",
|
||||||
|
groups: { "*": { requireMention: false } },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
|
||||||
createTelegramBot({ token: "tok" });
|
createTelegramBot({ token: "tok" });
|
||||||
const handler = getOnHandler("message") as (ctx: Record<string, unknown>) => Promise<void>;
|
const handler = getOnHandler("message") as (ctx: Record<string, unknown>) => Promise<void>;
|
||||||
|
|
||||||
await handler({
|
await handler({
|
||||||
message: {
|
message: {
|
||||||
chat: { id: 42, type: "group", title: "Ops" },
|
chat: { id: 42, type: "group", title: "Ops" },
|
||||||
text: "hello",
|
text: "hello",
|
||||||
date: 1736380800,
|
date: 1736380800,
|
||||||
message_id: 2,
|
message_id: 2,
|
||||||
from: {
|
from: {
|
||||||
id: 99,
|
id: 99,
|
||||||
first_name: "Ada",
|
first_name: "Ada",
|
||||||
last_name: "Lovelace",
|
last_name: "Lovelace",
|
||||||
username: "ada",
|
username: "ada",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
me: { username: "clawdbot_bot" },
|
||||||
me: { username: "clawdbot_bot" },
|
getFile: async () => ({ download: async () => new Uint8Array() }),
|
||||||
getFile: async () => ({ download: async () => new Uint8Array() }),
|
});
|
||||||
});
|
|
||||||
|
|
||||||
expect(replySpy).toHaveBeenCalledTimes(1);
|
expect(replySpy).toHaveBeenCalledTimes(1);
|
||||||
const payload = replySpy.mock.calls[0][0];
|
const payload = replySpy.mock.calls[0][0];
|
||||||
expectInboundContextContract(payload);
|
expectInboundContextContract(payload);
|
||||||
expect(payload.Body).toMatch(/^\[Telegram Ops id:42 (\+\d+[smhd] )?2025-01-09T00:00Z\]/);
|
expect(payload.Body).toMatch(
|
||||||
expect(payload.SenderName).toBe("Ada Lovelace");
|
/^\[Telegram Ops id:42 (\+\d+[smhd] )?2025-01-09 00:00 [^\]]+\]/,
|
||||||
expect(payload.SenderId).toBe("99");
|
);
|
||||||
expect(payload.SenderUsername).toBe("ada");
|
expect(payload.SenderName).toBe("Ada Lovelace");
|
||||||
|
expect(payload.SenderId).toBe("99");
|
||||||
|
expect(payload.SenderUsername).toBe("ada");
|
||||||
|
} finally {
|
||||||
|
process.env.TZ = originalTz;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("reacts to mention-gated group messages when ackReaction is enabled", async () => {
|
it("reacts to mention-gated group messages when ackReaction is enabled", async () => {
|
||||||
|
|||||||
@@ -329,11 +329,11 @@ describe("web auto-reply", () => {
|
|||||||
const firstArgs = resolver.mock.calls[0][0];
|
const firstArgs = resolver.mock.calls[0][0];
|
||||||
const secondArgs = resolver.mock.calls[1][0];
|
const secondArgs = resolver.mock.calls[1][0];
|
||||||
expect(firstArgs.Body).toMatch(
|
expect(firstArgs.Body).toMatch(
|
||||||
/\[WhatsApp \+1 (\+\d+[smhd] )?2025-01-01T00:00Z\] \[clawdbot\] first/,
|
/\[WhatsApp \+1 (\+\d+[smhd] )?2025-01-01 01:00 [^\]]+\] \[clawdbot\] first/,
|
||||||
);
|
);
|
||||||
expect(firstArgs.Body).not.toContain("second");
|
expect(firstArgs.Body).not.toContain("second");
|
||||||
expect(secondArgs.Body).toMatch(
|
expect(secondArgs.Body).toMatch(
|
||||||
/\[WhatsApp \+1 (\+\d+[smhd] )?2025-01-01T01:00Z\] \[clawdbot\] second/,
|
/\[WhatsApp \+1 (\+\d+[smhd] )?2025-01-01 02:00 [^\]]+\] \[clawdbot\] second/,
|
||||||
);
|
);
|
||||||
expect(secondArgs.Body).not.toContain("first");
|
expect(secondArgs.Body).not.toContain("first");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user