refactor(test): use env helper for web auto-reply timezone test

This commit is contained in:
Peter Steinberger
2026-02-21 18:45:04 +00:00
parent 7ba09e414f
commit d982893490

View File

@@ -1,5 +1,6 @@
import { beforeAll, describe, expect, it, vi } from "vitest"; import { beforeAll, describe, expect, it, vi } from "vitest";
import { escapeRegExp, formatEnvelopeTimestamp } from "../../test/helpers/envelope-timestamp.js"; import { escapeRegExp, formatEnvelopeTimestamp } from "../../test/helpers/envelope-timestamp.js";
import { withEnvAsync } from "../test-utils/env.js";
import { import {
installWebAutoReplyTestHomeHooks, installWebAutoReplyTestHomeHooks,
installWebAutoReplyUnitTestHooks, installWebAutoReplyUnitTestHooks,
@@ -233,92 +234,90 @@ describe("web auto-reply", () => {
}); });
it("processes inbound messages without batching and preserves timestamps", async () => { it("processes inbound messages without batching and preserves timestamps", async () => {
const originalTz = process.env.TZ; await withEnvAsync({ TZ: "Europe/Vienna" }, async () => {
process.env.TZ = "Europe/Vienna"; const originalMax = process.getMaxListeners();
process.setMaxListeners?.(1); // force low to confirm bump
const originalMax = process.getMaxListeners(); const store = await makeSessionStore({
process.setMaxListeners?.(1); // force low to confirm bump main: { sessionId: "sid", updatedAt: Date.now() },
});
const store = await makeSessionStore({ try {
main: { sessionId: "sid", updatedAt: Date.now() }, const sendMedia = vi.fn();
}); const reply = vi.fn().mockResolvedValue(undefined);
const sendComposing = vi.fn();
const resolver = vi.fn().mockResolvedValue({ text: "ok" });
try { let capturedOnMessage:
const sendMedia = vi.fn(); | ((msg: import("./inbound.js").WebInboundMessage) => Promise<void>)
const reply = vi.fn().mockResolvedValue(undefined); | undefined;
const sendComposing = vi.fn(); const listenerFactory = async (opts: {
const resolver = vi.fn().mockResolvedValue({ text: "ok" }); onMessage: (msg: import("./inbound.js").WebInboundMessage) => Promise<void>;
}) => {
capturedOnMessage = opts.onMessage;
return { close: vi.fn() };
};
let capturedOnMessage: setLoadConfigMock(() => ({
| ((msg: import("./inbound.js").WebInboundMessage) => Promise<void>) agents: {
| undefined; defaults: {
const listenerFactory = async (opts: { envelopeTimezone: "utc",
onMessage: (msg: import("./inbound.js").WebInboundMessage) => Promise<void>; },
}) => {
capturedOnMessage = opts.onMessage;
return { close: vi.fn() };
};
setLoadConfigMock(() => ({
agents: {
defaults: {
envelopeTimezone: "utc",
}, },
}, session: { store: store.storePath },
session: { store: store.storePath }, }));
}));
await monitorWebChannel(false, listenerFactory as never, false, resolver); await monitorWebChannel(false, listenerFactory as never, false, resolver);
expect(capturedOnMessage).toBeDefined(); expect(capturedOnMessage).toBeDefined();
// Two messages from the same sender with fixed timestamps // Two messages from the same sender with fixed timestamps
await capturedOnMessage?.( await capturedOnMessage?.(
makeInboundMessage({ makeInboundMessage({
body: "first", body: "first",
from: "+1", from: "+1",
to: "+2", to: "+2",
id: "m1", id: "m1",
timestamp: 1735689600000, // Jan 1 2025 00:00:00 UTC timestamp: 1735689600000, // Jan 1 2025 00:00:00 UTC
sendComposing, sendComposing,
reply, reply,
sendMedia, sendMedia,
}), }),
); );
await capturedOnMessage?.( await capturedOnMessage?.(
makeInboundMessage({ makeInboundMessage({
body: "second", body: "second",
from: "+1", from: "+1",
to: "+2", to: "+2",
id: "m2", id: "m2",
timestamp: 1735693200000, // Jan 1 2025 01:00:00 UTC timestamp: 1735693200000, // Jan 1 2025 01:00:00 UTC
sendComposing, sendComposing,
reply, reply,
sendMedia, sendMedia,
}), }),
); );
expect(resolver).toHaveBeenCalledTimes(2); expect(resolver).toHaveBeenCalledTimes(2);
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];
const firstTimestamp = formatEnvelopeTimestamp(new Date("2025-01-01T00:00:00Z")); const firstTimestamp = formatEnvelopeTimestamp(new Date("2025-01-01T00:00:00Z"));
const secondTimestamp = formatEnvelopeTimestamp(new Date("2025-01-01T01:00:00Z")); const secondTimestamp = formatEnvelopeTimestamp(new Date("2025-01-01T01:00:00Z"));
const firstPattern = escapeRegExp(firstTimestamp); const firstPattern = escapeRegExp(firstTimestamp);
const secondPattern = escapeRegExp(secondTimestamp); const secondPattern = escapeRegExp(secondTimestamp);
expect(firstArgs.Body).toMatch( expect(firstArgs.Body).toMatch(
new RegExp(`\\[WhatsApp \\+1 (\\+\\d+[smhd] )?${firstPattern}\\] \\[openclaw\\] first`), new RegExp(`\\[WhatsApp \\+1 (\\+\\d+[smhd] )?${firstPattern}\\] \\[openclaw\\] first`),
); );
expect(firstArgs.Body).not.toContain("second"); expect(firstArgs.Body).not.toContain("second");
expect(secondArgs.Body).toMatch( expect(secondArgs.Body).toMatch(
new RegExp(`\\[WhatsApp \\+1 (\\+\\d+[smhd] )?${secondPattern}\\] \\[openclaw\\] second`), new RegExp(`\\[WhatsApp \\+1 (\\+\\d+[smhd] )?${secondPattern}\\] \\[openclaw\\] second`),
); );
expect(secondArgs.Body).not.toContain("first"); expect(secondArgs.Body).not.toContain("first");
// Max listeners bumped to avoid warnings in multi-instance test runs // Max listeners bumped to avoid warnings in multi-instance test runs
expect(process.getMaxListeners?.()).toBeGreaterThanOrEqual(50); expect(process.getMaxListeners?.()).toBeGreaterThanOrEqual(50);
} finally { } finally {
process.setMaxListeners?.(originalMax); process.setMaxListeners?.(originalMax);
process.env.TZ = originalTz; await store.cleanup();
await store.cleanup(); }
} });
}); });
}); });